[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Xen-ia64-devel] [PATCH 1/3] [read-only mapping] GNTMAP_readonly support xen part
1 / 3
# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Node ID d4879708b89968cb860c324c27b69c9d3955fda5
# Parent e6a88b056e60120a6ce554613ccb0f6a2bd4114f
add grant table GNTMAP_readonly support.
PATCHNAME: grant_table_readonly
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/vmx/vmx_init.c Tue May 16 13:25:43 2006 +0900
@@ -346,7 +346,7 @@ int vmx_build_physmap_table(struct domai
for (j = io_ranges[i].start;
j < io_ranges[i].start + io_ranges[i].size;
j += PAGE_SIZE)
- __assign_domain_page(d, j, io_ranges[i].type);
+ __assign_domain_page(d, j, io_ranges[i].type, 0);
}
/* Map normal memory below 3G */
diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/xen/domain.c Tue May 16 13:25:43 2006 +0900
@@ -707,6 +707,16 @@ not_present:
}
#endif
+static void
+assign_pte(pte_t* pte, unsigned long maddr, unsigned long readonly)
+{
+ unsigned long arflags = _PAGE_AR_RWX;
+ if (readonly)
+ arflags = _PAGE_AR_R;
+ set_pte(pte, pfn_pte(maddr >> PAGE_SHIFT,
+ __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)));
+}
+
/* Allocate a new page for domain and map it to the specified metaphysical
address. */
struct page_info *
@@ -753,8 +763,7 @@ __assign_new_domain_page(struct domain *
ret = get_page(p, d);
BUG_ON(ret == 0);
- set_pte(pte, pfn_pte(maddr >> PAGE_SHIFT,
- __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+ assign_pte(pte, maddr, 0);
//XXX CONFIG_XEN_IA64_DOM0_VP
// TODO racy
@@ -804,16 +813,15 @@ assign_new_domain0_page(struct domain *d
/* map a physical address to the specified metaphysical addr */
void
__assign_domain_page(struct domain *d,
- unsigned long mpaddr, unsigned long physaddr)
+ unsigned long mpaddr, unsigned long physaddr,
+ unsigned long readonly)
{
pte_t *pte;
pte = lookup_alloc_domain_pte(d, mpaddr);
- if (pte_none(*pte)) {
- set_pte(pte,
- pfn_pte(physaddr >> PAGE_SHIFT,
- __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
- } else
+ if (pte_none(*pte))
+ assign_pte(pte, physaddr, readonly);
+ else
printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr);
}
@@ -828,7 +836,7 @@ assign_domain_page(struct domain *d,
BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM);
ret = get_page(page, d);
BUG_ON(ret == 0);
- __assign_domain_page(d, mpaddr, physaddr);
+ __assign_domain_page(d, mpaddr, physaddr, 0);
//XXX CONFIG_XEN_IA64_DOM0_VP
// TODO racy
@@ -843,7 +851,7 @@ assign_domain_same_page(struct domain *d
//XXX optimization
unsigned long end = mpaddr + size;
for (; mpaddr < end; mpaddr += PAGE_SIZE) {
- __assign_domain_page(d, mpaddr, mpaddr);
+ __assign_domain_page(d, mpaddr, mpaddr, 0);
}
}
@@ -1035,15 +1043,14 @@ unsigned long lookup_domain_mpa(struct d
}
pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
- pte = &pteval;
- return *(unsigned long *)pte;
+ return pte_val(pteval);
}
#endif
pte = lookup_noalloc_domain_pte(d, mpaddr);
if (pte != NULL) {
if (pte_present(*pte)) {
//printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte));
- return *(unsigned long *)pte;
+ return pte_val(*pte);
} else if (VMX_DOMAIN(d->vcpu[0]))
return GPFN_INV_MASK;
}
@@ -1083,7 +1090,7 @@ out:
// caller must call set_gpfn_from_mfn().
static void
assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
- unsigned long mfn, unsigned int flags)
+ unsigned long mfn, unsigned int readonly)
{
struct mm_struct *mm = d->arch.mm;
pte_t* pte;
@@ -1093,8 +1100,7 @@ assign_domain_page_replace(struct domain
// update pte
old_pte = ptep_get_and_clear(mm, mpaddr, pte);
- set_pte(pte, pfn_pte(mfn,
- __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+ assign_pte(pte, mfn << PAGE_SHIFT, readonly);
if (!pte_none(old_pte)) {
unsigned long old_mfn;
struct page_info* old_page;
@@ -1122,11 +1128,11 @@ assign_domain_page_replace(struct domain
unsigned long
dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
- unsigned int flags, domid_t domid)
+ unsigned int readonly, domid_t domid)
{
int error = 0;
-
struct domain* rd;
+
rd = find_domain_by_id(domid);
if (unlikely(rd == NULL)) {
error = -EINVAL;
@@ -1141,7 +1147,7 @@ dom0vp_add_physmap(struct domain* d, uns
goto out1;
}
- assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* flags:XXX */);
+ assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, readonly);
//don't update p2m table because this page belongs to rd, not d.
out1:
put_domain(rd);
@@ -1161,22 +1167,16 @@ create_grant_host_mapping(unsigned long
struct page_info* page;
int ret;
- if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
+ if (flags & (GNTMAP_device_map |
+ GNTMAP_application_map | GNTMAP_contains_pte)) {
DPRINTK("%s: flags 0x%x\n", __func__, flags);
return GNTST_general_error;
- }
- if (flags & GNTMAP_readonly) {
-#if 0
- DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
- __func__, flags);
-#endif
- flags &= ~GNTMAP_readonly;
}
page = mfn_to_page(mfn);
ret = get_page(page, page_get_owner(page));
BUG_ON(ret == 0);
- assign_domain_page_replace(d, gpaddr, mfn, flags);
+ assign_domain_page_replace(d, gpaddr, mfn, flags & GNTMAP_readonly);
return GNTST_okay;
}
@@ -1196,22 +1196,17 @@ destroy_grant_host_mapping(unsigned long
DPRINTK("%s: flags 0x%x\n", __func__, flags);
return GNTST_general_error;
}
- if (flags & GNTMAP_readonly) {
-#if 0
- DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
- __func__, flags);
-#endif
- flags &= ~GNTMAP_readonly;
- }
pte = lookup_noalloc_domain_pte(d, gpaddr);
if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn)
- return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr
-
+ return GNTST_general_error;// GNTST_bad_pseudo_phys_addr?
+
// update pte
old_pte = ptep_get_and_clear(d->arch.mm, gpaddr, pte);
if (pte_present(old_pte)) {
- old_mfn = pte_pfn(old_pte);//XXX
+ old_mfn = pte_pfn(old_pte);
+ } else {
+ return GNTST_general_error;// GNTST_bad_virt_addr?
}
domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
@@ -1312,7 +1307,7 @@ guest_physmap_add_page(struct domain *d,
ret = get_page(mfn_to_page(mfn), d);
BUG_ON(ret == 0);
- assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */);
+ assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0);
set_gpfn_from_mfn(mfn, gpfn);//XXX SMP
//BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/xen/process.c Tue May 16 13:25:43 2006 +0900
@@ -85,6 +85,8 @@ u64 translate_domain_pte(u64 pteval, u64
struct domain *d = current->domain;
ia64_itir_t itir = {.itir = itir__};
u64 mask, mpaddr, pteval2;
+ u64 arflags;
+ u64 arflags2;
pteval &= ((1UL << 53) - 1);// ignore [63:53] bits
@@ -123,6 +125,18 @@ u64 translate_domain_pte(u64 pteval, u64
}
#endif
pteval2 = lookup_domain_mpa(d,mpaddr);
+ arflags = pteval & _PAGE_AR_MASK;
+ arflags2 = pteval2 & _PAGE_AR_MASK;
+ if (arflags != _PAGE_AR_R && arflags2 == _PAGE_AR_R) {
+ DPRINTK("%s:%d "
+ "pteval 0x%lx arflag 0x%lx address 0x%lx itir 0x%lx "
+ "pteval2 0x%lx arflags2 0x%lx\n",
+ __func__, __LINE__,
+ pteval, arflags, address, itir__,
+ pteval2, arflags2);
+ pteval = (pteval & ~_PAGE_AR_MASK) | _PAGE_AR_R;
+ }
+
pteval2 &= _PAGE_PPN_MASK; // ignore non-addr bits
pteval2 |= (pteval & _PAGE_ED);
pteval2 |= _PAGE_PL_2; // force PL0->2 (PL3 is unaffected)
diff -r e6a88b056e60 -r d4879708b899 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h Tue May 16 13:25:41 2006 +0900
+++ b/xen/include/asm-ia64/domain.h Tue May 16 13:25:43 2006 +0900
@@ -118,7 +118,7 @@ extern struct mm_struct init_mm;
struct page_info * assign_new_domain_page(struct domain *d, unsigned long mpaddr);
void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);
-void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr);
+void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr, unsigned long readonly);
void assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr);
void assign_domain_io_page(struct domain *d, unsigned long mpaddr, unsigned long flags);
#ifdef CONFIG_XEN_IA64_DOM0_VP
@@ -126,7 +126,7 @@ unsigned long assign_domain_mach_page(st
unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size);
unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);
unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order);
-unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int flags, domid_t domid);
+unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int readonly, domid_t domid);
#endif
#include <asm/uaccess.h> /* for KERNEL_DS */
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
This mailing list archive is a service of Copilotco.