# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID 052e3c8407a647d6ccb07fff7ff0787744216162 # Parent d3c3aeb5f3c1d652ee68efd51621ef4e020f7c76 add grant table GNTMAP_readonly support. PATCHNAME: grant_table_readonly Signed-off-by: Isaku Yamahata diff -r d3c3aeb5f3c1 -r 052e3c8407a6 xen/arch/ia64/vmx/vmx_init.c --- a/xen/arch/ia64/vmx/vmx_init.c Fri May 19 16:57:01 2006 +0900 +++ b/xen/arch/ia64/vmx/vmx_init.c Fri May 19 16:57:16 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, _PAGE_AR_RWX); } /* Map normal memory below 3G */ diff -r d3c3aeb5f3c1 -r 052e3c8407a6 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Fri May 19 16:57:01 2006 +0900 +++ b/xen/arch/ia64/xen/domain.c Fri May 19 16:57:16 2006 +0900 @@ -793,17 +793,20 @@ assign_new_domain0_page(struct domain *d } /* map a physical address to the specified metaphysical addr */ +// flags: currently only _PAGE_AR_R or _PAGE_AR_RWX is supporeted void __assign_domain_page(struct domain *d, - unsigned long mpaddr, unsigned long physaddr) + unsigned long mpaddr, unsigned long physaddr, + unsigned long flags) { pte_t *pte; + unsigned long arflags = flags & _PAGE_AR_MASK; + BUG_ON(arflags != _PAGE_AR_R && arflags != _PAGE_AR_RWX); 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))); + set_pte(pte, pfn_pte(physaddr >> PAGE_SHIFT, + __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags))); mb (); } else printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr); @@ -820,7 +823,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, _PAGE_AR_RWX); //XXX CONFIG_XEN_IA64_DOM0_VP // TODO racy @@ -830,12 +833,12 @@ assign_domain_page(struct domain *d, #ifdef CONFIG_XEN_IA64_DOM0_VP static void assign_domain_same_page(struct domain *d, - unsigned long mpaddr, unsigned long size) + unsigned long mpaddr, unsigned long size) { //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, _PAGE_AR_RWX); } } @@ -1072,15 +1075,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; } @@ -1094,7 +1096,10 @@ unsigned long lookup_domain_mpa(struct d printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__, mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT); mpafoo(mpaddr); - return 0; + + //XXX This is a work around until the emulation memory access to a region + // where memory or device are attached is implemented. + return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX))); } #ifdef CONFIG_XEN_IA64_DOM0_VP @@ -1118,19 +1123,22 @@ out: // caller must get_page(mfn_to_page(mfn)) before // caller must call set_gpfn_from_mfn(). +// flags: currently only _PAGE_AR_R or _PAGE_AR_RWX is supporeted static void assign_domain_page_replace(struct domain *d, unsigned long mpaddr, - unsigned long mfn, unsigned int flags) + unsigned long mfn, unsigned long flags) { struct mm_struct *mm = &d->arch.mm; pte_t* pte; pte_t old_pte; pte_t npte; + unsigned long arflags = flags & _PAGE_AR_MASK; + BUG_ON(arflags != _PAGE_AR_R && arflags != _PAGE_AR_RWX); pte = lookup_alloc_domain_pte(d, mpaddr); // update pte - npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)); + npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)); old_pte = ptep_xchg(mm, mpaddr, pte, npte); if (!pte_none(old_pte)) { unsigned long old_mfn; @@ -1159,11 +1167,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 long flags, domid_t domid) { int error = 0; - struct domain* rd; + rd = find_domain_by_id(domid); if (unlikely(rd == NULL)) { error = -EINVAL; @@ -1178,7 +1186,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, flags); //don't update p2m table because this page belongs to rd, not d. out1: put_domain(rd); @@ -1197,24 +1205,23 @@ create_grant_host_mapping(unsigned long struct domain* d = current->domain; struct page_info* page; int ret; - - if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) { + unsigned long arflags; + + 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); - + + arflags = _PAGE_AR_RWX; + if (flags & GNTMAP_readonly) { + arflags = _PAGE_AR_R; + } + assign_domain_page_replace(d, gpaddr, mfn, arflags); return GNTST_okay; } @@ -1233,22 +1240,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; // 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; } domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN); @@ -1349,7 +1351,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, _PAGE_AR_RWX); set_gpfn_from_mfn(mfn, gpfn);//XXX SMP //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT)); diff -r d3c3aeb5f3c1 -r 052e3c8407a6 xen/arch/ia64/xen/process.c --- a/xen/arch/ia64/xen/process.c Fri May 19 16:57:01 2006 +0900 +++ b/xen/arch/ia64/xen/process.c Fri May 19 16:57:16 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 mpaddr 0x%lx\n", + __func__, __LINE__, + pteval, arflags, address, itir__, + pteval2, arflags2, mpaddr); + 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 d3c3aeb5f3c1 -r 052e3c8407a6 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Fri May 19 16:57:01 2006 +0900 +++ b/xen/include/asm-ia64/domain.h Fri May 19 16:57:16 2006 +0900 @@ -112,7 +112,7 @@ struct arch_vcpu { 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 flags); 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 @@ -120,7 +120,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 long flags, domid_t domid); #endif #include /* for KERNEL_DS */