[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] xen, x86: Allow mprotect() pte updates to be batched using new Xen
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1200407741 0 # Node ID 5f64a1735b3cc2940219dbf073ad92aa2caa8e13 # Parent e8b49cfbdac0c5ee680cd9ec3d693ed0e2d42432 xen, x86: Allow mprotect() pte updates to be batched using new Xen batched interface which preserves access/dirty pte flags. Signed-off-by: Bruce Rogers <brogers@xxxxxxxxxx> --- arch/i386/mm/hypervisor.c | 30 ++++++++++++++++++++++++++++++ include/asm-generic/pgtable.h | 4 ++++ include/asm-i386/mach-xen/asm/pgtable.h | 6 ++++++ include/asm-x86_64/mach-xen/asm/pgtable.h | 6 ++++++ include/xen/interface/xen.h | 19 ++++++++++++------- mm/mprotect.c | 2 ++ 6 files changed, 60 insertions(+), 7 deletions(-) diff -r e8b49cfbdac0 -r 5f64a1735b3c arch/i386/mm/hypervisor.c --- a/arch/i386/mm/hypervisor.c Mon Jan 14 15:52:23 2008 +0000 +++ b/arch/i386/mm/hypervisor.c Tue Jan 15 14:35:41 2008 +0000 @@ -548,3 +548,33 @@ int write_ldt_entry(void *ldt, int entry mach_lp, (u64)entry_a | ((u64)entry_b<<32)); } #endif + +#define MAX_BATCHED_FULL_PTES 32 + +int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, pgprot_t newprot) +{ + int rc = 0, i = 0; + mmu_update_t u[MAX_BATCHED_FULL_PTES]; + pte_t *pte; + spinlock_t *ptl; + + pte = pte_offset_map_lock(mm, pmd, addr, &ptl); + do { + if (pte_present(*pte)) { + u[i].ptr = virt_to_machine(pte) | MMU_PT_UPDATE_PRESERVE_AD; + u[i].val = __pte_val(pte_modify(*pte, newprot)); + if (++i == MAX_BATCHED_FULL_PTES) { + if ((rc = HYPERVISOR_mmu_update( + &u[0], i, NULL, DOMID_SELF)) != 0) + break; + i = 0; + } + } + } while (pte++, addr += PAGE_SIZE, addr != end); + if (i) + rc = HYPERVISOR_mmu_update( &u[0], i, NULL, DOMID_SELF); + pte_unmap_unlock(pte - 1, ptl); + BUG_ON(rc && rc != -ENOSYS); + return !rc; +} diff -r e8b49cfbdac0 -r 5f64a1735b3c include/asm-generic/pgtable.h --- a/include/asm-generic/pgtable.h Mon Jan 14 15:52:23 2008 +0000 +++ b/include/asm-generic/pgtable.h Tue Jan 15 14:35:41 2008 +0000 @@ -188,6 +188,10 @@ static inline void ptep_set_wrprotect(st }) #endif +#ifndef arch_change_pte_range +#define arch_change_pte_range(mm, pmd, addr, end, newprot) 0 +#endif + #ifndef __ASSEMBLY__ /* * When walking page tables, we usually want to skip any p?d_none entries; diff -r e8b49cfbdac0 -r 5f64a1735b3c include/asm-i386/mach-xen/asm/pgtable.h --- a/include/asm-i386/mach-xen/asm/pgtable.h Mon Jan 14 15:52:23 2008 +0000 +++ b/include/asm-i386/mach-xen/asm/pgtable.h Tue Jan 15 14:35:41 2008 +0000 @@ -512,6 +512,12 @@ int touch_pte_range(struct mm_struct *mm unsigned long address, unsigned long size); +int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, pgprot_t newprot); + +#define arch_change_pte_range(mm, pmd, addr, end, newprot) \ + xen_change_pte_range(mm, pmd, addr, end, newprot) + #define io_remap_pfn_range(vma,from,pfn,size,prot) \ direct_remap_pfn_range(vma,from,pfn,size,prot,DOMID_IO) diff -r e8b49cfbdac0 -r 5f64a1735b3c include/asm-x86_64/mach-xen/asm/pgtable.h --- a/include/asm-x86_64/mach-xen/asm/pgtable.h Mon Jan 14 15:52:23 2008 +0000 +++ b/include/asm-x86_64/mach-xen/asm/pgtable.h Tue Jan 15 14:35:41 2008 +0000 @@ -541,6 +541,12 @@ int touch_pte_range(struct mm_struct *mm unsigned long address, unsigned long size); +int xen_change_pte_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, pgprot_t newprot); + +#define arch_change_pte_range(mm, pmd, addr, end, newprot) \ + xen_change_pte_range(mm, pmd, addr, end, newprot) + #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ direct_remap_pfn_range(vma,vaddr,pfn,size,prot,DOMID_IO) diff -r e8b49cfbdac0 -r 5f64a1735b3c include/xen/interface/xen.h --- a/include/xen/interface/xen.h Mon Jan 14 15:52:23 2008 +0000 +++ b/include/xen/interface/xen.h Tue Jan 15 14:35:41 2008 +0000 @@ -168,9 +168,14 @@ * ptr[:2] -- Machine address within the frame whose mapping to modify. * The frame must belong to the FD, if one is specified. * val -- Value to write into the mapping entry. - */ -#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */ -#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */ + * + * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD: + * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed + * with those in @val. + */ +#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */ +#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */ +#define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */ /* * MMU EXTENDED OPERATIONS @@ -583,10 +588,10 @@ typedef uint8_t xen_domain_handle_t[16]; #define __mk_unsigned_long(x) x ## UL #define mk_unsigned_long(x) __mk_unsigned_long(x) -DEFINE_XEN_GUEST_HANDLE(uint8_t); -DEFINE_XEN_GUEST_HANDLE(uint16_t); -DEFINE_XEN_GUEST_HANDLE(uint32_t); -DEFINE_XEN_GUEST_HANDLE(uint64_t); +__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t); +__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t); +__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t); +__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); #else /* __ASSEMBLY__ */ diff -r e8b49cfbdac0 -r 5f64a1735b3c mm/mprotect.c --- a/mm/mprotect.c Mon Jan 14 15:52:23 2008 +0000 +++ b/mm/mprotect.c Tue Jan 15 14:35:41 2008 +0000 @@ -76,6 +76,8 @@ static inline void change_pmd_range(stru next = pmd_addr_end(addr, end); if (pmd_none_or_clear_bad(pmd)) continue; + if (arch_change_pte_range(mm, pmd, addr, next, newprot)) + continue; change_pte_range(mm, pmd, addr, next, newprot); } while (pmd++, addr = next, addr != end); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |