[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.