]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Revert "x86/paravirt: Remove paravirt ops pmd_update[_defer] and pte_update_defer"
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 11 May 2016 18:28:21 +0000 (14:28 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 11 May 2016 18:28:21 +0000 (14:28 -0400)
This reverts commit 9ff226047d9f2fb8366b71daf42039911f5aa088.

As it breaks the kABI: pv_mmu_ops

And we don't need this patch.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/pgtable.h
arch/x86/kernel/paravirt.c
arch/x86/lguest/boot.c
arch/x86/mm/pgtable.c
arch/x86/xen/mmu.c

index a373c59415074de949b6875ffccbeb78d31052e5..42f16f6e8e759603fa0fbb741859a06b64a5ca76 100644 (file)
@@ -411,6 +411,23 @@ static inline void pte_update(struct mm_struct *mm, unsigned long addr,
 {
        PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep);
 }
+static inline void pmd_update(struct mm_struct *mm, unsigned long addr,
+                             pmd_t *pmdp)
+{
+       PVOP_VCALL3(pv_mmu_ops.pmd_update, mm, addr, pmdp);
+}
+
+static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr,
+                                   pte_t *ptep)
+{
+       PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep);
+}
+
+static inline void pmd_update_defer(struct mm_struct *mm, unsigned long addr,
+                                   pmd_t *pmdp)
+{
+       PVOP_VCALL3(pv_mmu_ops.pmd_update_defer, mm, addr, pmdp);
+}
 
 static inline pte_t __pte(pteval_t val)
 {
index 16242da8c27bfb0d0a75ebbb23aec4efe8bb9001..19d3a1304a94d7a2e8e600575ea771dff9afd8d1 100644 (file)
@@ -281,6 +281,12 @@ struct pv_mmu_ops {
                           pmd_t *pmdp, pmd_t pmdval);
        void (*pte_update)(struct mm_struct *mm, unsigned long addr,
                           pte_t *ptep);
+       void (*pte_update_defer)(struct mm_struct *mm,
+                                unsigned long addr, pte_t *ptep);
+       void (*pmd_update)(struct mm_struct *mm, unsigned long addr,
+                          pmd_t *pmdp);
+       void (*pmd_update_defer)(struct mm_struct *mm,
+                                unsigned long addr, pmd_t *pmdp);
 
        pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
                                        pte_t *ptep);
index 01eb26675ba1009860e6f1fbaebc95ea5a9d2bb9..fe57e7a98839801ce76a6a33c0f3a7552e5d292a 100644 (file)
@@ -62,6 +62,9 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page);
 #define pmd_clear(pmd)                 native_pmd_clear(pmd)
 
 #define pte_update(mm, addr, ptep)              do { } while (0)
+#define pte_update_defer(mm, addr, ptep)        do { } while (0)
+#define pmd_update(mm, addr, ptep)              do { } while (0)
+#define pmd_update_defer(mm, addr, ptep)        do { } while (0)
 
 #define pgd_val(x)     native_pgd_val(x)
 #define __pgd(x)       native_make_pgd(x)
@@ -701,9 +704,14 @@ static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr,
  * updates should either be sets, clears, or set_pte_atomic for P->P
  * transitions, which means this hook should only be called for user PTEs.
  * This hook implies a P->P protection or access change has taken place, which
- * requires a subsequent TLB flush.
+ * requires a subsequent TLB flush.  The notification can optionally be delayed
+ * until the TLB flush event by using the pte_update_defer form of the
+ * interface, but care must be taken to assure that the flush happens while
+ * still holding the same page table lock so that the shadow and primary pages
+ * do not become out of sync on SMP.
  */
 #define pte_update(mm, addr, ptep)             do { } while (0)
+#define pte_update_defer(mm, addr, ptep)       do { } while (0)
 #endif
 
 /*
@@ -795,7 +803,9 @@ static inline int pmd_write(pmd_t pmd)
 static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, unsigned long addr,
                                       pmd_t *pmdp)
 {
-       return native_pmdp_get_and_clear(pmdp);
+       pmd_t pmd = native_pmdp_get_and_clear(pmdp);
+       pmd_update(mm, addr, pmdp);
+       return pmd;
 }
 
 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -803,6 +813,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
                                      unsigned long addr, pmd_t *pmdp)
 {
        clear_bit(_PAGE_BIT_RW, (unsigned long *)pmdp);
+       pmd_update(mm, addr, pmdp);
 }
 
 /*
index 5451b5220ed8de9ccf63a5f7b4b2d3ba053b5707..c614dd492f5f720058346a33883f5a67d4689b94 100644 (file)
@@ -436,6 +436,9 @@ struct pv_mmu_ops pv_mmu_ops = {
        .set_pmd = native_set_pmd,
        .set_pmd_at = native_set_pmd_at,
        .pte_update = paravirt_nop,
+       .pte_update_defer = paravirt_nop,
+       .pmd_update = paravirt_nop,
+       .pmd_update_defer = paravirt_nop,
 
        .ptep_modify_prot_start = __ptep_modify_prot_start,
        .ptep_modify_prot_commit = __ptep_modify_prot_commit,
index ce4905a40223f1df226039f64b0f731586c4feca..e9da4bcfe316a75539d80d203c948607af7d8026 100644 (file)
@@ -1478,6 +1478,7 @@ __init void lguest_init(void)
        pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode;
        pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu;
        pv_mmu_ops.pte_update = lguest_pte_update;
+       pv_mmu_ops.pte_update_defer = lguest_pte_update;
 
 #ifdef CONFIG_X86_LOCAL_APIC
        /* APIC read/write intercepts */
index d57db90e2fb944a5a5f58c3202ae1750cb8db508..0b97d2c75df3d5fc05b1caafdadce2972660543d 100644 (file)
@@ -414,7 +414,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
 
        if (changed && dirty) {
                *ptep = entry;
-               pte_update(vma->vm_mm, address, ptep);
+               pte_update_defer(vma->vm_mm, address, ptep);
        }
 
        return changed;
@@ -431,6 +431,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma,
 
        if (changed && dirty) {
                *pmdp = entry;
+               pmd_update_defer(vma->vm_mm, address, pmdp);
                /*
                 * We had a write-protection fault here and changed the pmd
                 * to to more permissive. No need to flush the TLB for that,
@@ -468,6 +469,9 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma,
                ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,
                                         (unsigned long *)pmdp);
 
+       if (ret)
+               pmd_update(vma->vm_mm, addr, pmdp);
+
        return ret;
 }
 #endif
@@ -514,6 +518,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma,
        set = !test_and_set_bit(_PAGE_BIT_SPLITTING,
                                (unsigned long *)pmdp);
        if (set) {
+               pmd_update(vma->vm_mm, address, pmdp);
                /* need tlb flush only to serialize against gup-fast */
                flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        }
index c913ca4f6958693f6d7357c53bf149076a4b6d4f..cb5e266a8bf752297eaf6fc0d822c9398239fadf 100644 (file)
@@ -2436,6 +2436,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
        .flush_tlb_others = xen_flush_tlb_others,
 
        .pte_update = paravirt_nop,
+       .pte_update_defer = paravirt_nop,
 
        .pgd_alloc = xen_pgd_alloc,
        .pgd_free = xen_pgd_free,