# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 3ac52066af814d8f2dee0c0467d641891753c96e
# Parent 371d2837a1feb3985e0899676d50c5a124555489
[IA64] Support Xen/IA64 self-grant-table-page-mapping.
Before the changeset 10677:2937703f0ed0 of xen-unstable.hg,
it is prohibited mapping a page which is granted by self domain.
However it is allowed in order to mount blktap image by dom0.
This patch is necessary to support blktap on Xen/IA64.
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
xen/arch/ia64/xen/mm.c | 39 +++++++++++++++------------
xen/include/asm-ia64/linux-xen/asm/pgtable.h | 3 ++
xen/include/public/arch-ia64.h | 3 ++
3 files changed, 29 insertions(+), 16 deletions(-)
diff -r 371d2837a1fe -r 3ac52066af81 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Fri Nov 10 11:34:39 2006 -0700
+++ b/xen/arch/ia64/xen/mm.c Fri Nov 10 11:44:38 2006 -0700
@@ -765,7 +765,8 @@ __assign_new_domain_page(struct domain *
// because set_pte_rel() has release semantics
set_pte_rel(pte,
pfn_pte(maddr >> PAGE_SHIFT,
- __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+ __pgprot(_PAGE_PGC_ALLOCATED | __DIRTY_BITS |
+ _PAGE_PL_2 | _PAGE_AR_RWX)));
smp_mb();
return p;
@@ -807,6 +808,7 @@ flags_to_prot (unsigned long flags)
#ifdef CONFIG_XEN_IA64_TLB_TRACK
res |= flags & ASSIGN_tlb_track ? _PAGE_TLB_TRACKING: 0;
#endif
+ res |= flags & ASSIGN_pgc_allocated ? _PAGE_PGC_ALLOCATED: 0;
return res;
}
@@ -866,7 +868,8 @@ assign_domain_page(struct domain *d,
set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
// because __assign_domain_page() uses set_pte_rel() which has
// release semantics, smp_mb() isn't needed.
- (void)__assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
+ (void)__assign_domain_page(d, mpaddr, physaddr,
+ ASSIGN_writable | ASSIGN_pgc_allocated);
}
int
@@ -1035,6 +1038,7 @@ assign_domain_mach_page(struct domain *d
unsigned long mpaddr, unsigned long size,
unsigned long flags)
{
+ BUG_ON(flags & ASSIGN_pgc_allocated);
assign_domain_same_page(d, mpaddr, size, flags);
return mpaddr;
}
@@ -1046,15 +1050,17 @@ domain_put_page(struct domain* d, unsign
unsigned long mfn = pte_pfn(old_pte);
struct page_info* page = mfn_to_page(mfn);
- if (page_get_owner(page) == d ||
- page_get_owner(page) == NULL) {
- BUG_ON(get_gpfn_from_mfn(mfn) != (mpaddr >> PAGE_SHIFT));
- set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
- }
-
- if (clear_PGC_allocate)
- try_to_clear_PGC_allocate(d, page);
-
+ if (pte_pgc_allocated(old_pte)) {
+ if (page_get_owner(page) == d || page_get_owner(page) == NULL) {
+ BUG_ON(get_gpfn_from_mfn(mfn) != (mpaddr >> PAGE_SHIFT));
+ set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
+ } else {
+ BUG();
+ }
+
+ if (clear_PGC_allocate)
+ try_to_clear_PGC_allocate(d, page);
+ }
domain_page_flush_and_put(d, mpaddr, ptep, old_pte, page);
}
@@ -1146,6 +1152,7 @@ assign_domain_page_cmpxchg_rel(struct do
}
BUG_ON(!pte_mem(old_pte));
+ BUG_ON(!pte_pgc_allocated(old_pte));
BUG_ON(page_get_owner(old_page) != d);
BUG_ON(get_gpfn_from_mfn(old_mfn) != (mpaddr >> PAGE_SHIFT));
BUG_ON(old_mfn == new_mfn);
@@ -1240,7 +1247,7 @@ dom0vp_add_physmap(struct domain* d, uns
struct domain* rd;
/* Not allowed by a domain. */
- if (flags & ASSIGN_nocache)
+ if (flags & (ASSIGN_nocache | ASSIGN_pgc_allocated))
return -EINVAL;
rd = find_domain_by_id(domid);
@@ -1424,8 +1431,6 @@ create_grant_host_mapping(unsigned long
page = mfn_to_page(mfn);
ret = get_page(page, page_get_owner(page));
BUG_ON(ret == 0);
- BUG_ON(page_get_owner(mfn_to_page(mfn)) == d &&
- get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
assign_domain_page_replace(d, gpaddr, mfn,
#ifdef CONFIG_XEN_IA64_TLB_TRACK
ASSIGN_tlb_track |
@@ -1551,7 +1556,8 @@ steal_page(struct domain *d, struct page
// has release semantics.
ret = assign_domain_page_cmpxchg_rel(d, gpfn << PAGE_SHIFT, page, new,
- ASSIGN_writable);
+ ASSIGN_writable |
+ ASSIGN_pgc_allocated);
if (ret < 0) {
gdprintk(XENLOG_INFO, "assign_domain_page_cmpxchg_rel failed %d\n",
ret);
@@ -1648,7 +1654,8 @@ guest_physmap_add_page(struct domain *d,
BUG_ON(ret == 0);
set_gpfn_from_mfn(mfn, gpfn);
smp_mb();
- assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, ASSIGN_writable);
+ assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
+ ASSIGN_writable | ASSIGN_pgc_allocated);
//BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >>
PAGE_SHIFT));
diff -r 371d2837a1fe -r 3ac52066af81
xen/include/asm-ia64/linux-xen/asm/pgtable.h
--- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h Fri Nov 10 11:34:39
2006 -0700
+++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h Fri Nov 10 11:44:38
2006 -0700
@@ -89,6 +89,8 @@
((pte_val(pte) & _PAGE_TLB_INSERTED_MANY) != 0)
#endif // CONFIG_XEN_IA64_TLB_TRACK
+#define _PAGE_PGC_ALLOCATED_BIT 59 /* _PGC_allocated */
+#define _PAGE_PGC_ALLOCATED (__IA64_UL(1) << _PAGE_PGC_ALLOCATED_BIT)
/* domVTI */
#define GPFN_MEM (0UL << 60) /* Guest pfn is normal mem */
#define GPFN_FRAME_BUFFER (1UL << 60) /* VGA framebuffer */
@@ -333,6 +335,7 @@ set_pte_rel(volatile pte_t* ptep, pte_t
#define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0)
#define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0)
#ifdef XEN
+#define pte_pgc_allocated(pte) ((pte_val(pte) & _PAGE_PGC_ALLOCATED) != 0)
#define pte_mem(pte) \
(!(pte_val(pte) & (GPFN_IO_MASK | GPFN_INV_MASK)) && !pte_none(pte))
#endif
diff -r 371d2837a1fe -r 3ac52066af81 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h Fri Nov 10 11:34:39 2006 -0700
+++ b/xen/include/public/arch-ia64.h Fri Nov 10 11:44:38 2006 -0700
@@ -384,6 +384,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
// tlb tracking
#define _ASSIGN_tlb_track 2
#define ASSIGN_tlb_track (1UL << _ASSIGN_tlb_track)
+/* Internal only: associated with PGC_allocated bit */
+#define _ASSIGN_pgc_allocated 3
+#define ASSIGN_pgc_allocated (1UL << _ASSIGN_pgc_allocated)
/* This structure has the same layout of struct ia64_boot_param, defined in
<asm/system.h>. It is redefined here to ease use. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|