diff options
-rw-r--r-- | arch/x86/kernel/paravirt.c | 3 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 3 | ||||
-rw-r--r-- | include/asm-x86/paravirt.h | 28 |
3 files changed, 34 insertions, 0 deletions
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index c98d54688180..f1ab0f727007 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -380,6 +380,9 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
380 | .pte_update = paravirt_nop, | 380 | .pte_update = paravirt_nop, |
381 | .pte_update_defer = paravirt_nop, | 381 | .pte_update_defer = paravirt_nop, |
382 | 382 | ||
383 | .ptep_modify_prot_start = __ptep_modify_prot_start, | ||
384 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, | ||
385 | |||
383 | #ifdef CONFIG_HIGHPTE | 386 | #ifdef CONFIG_HIGHPTE |
384 | .kmap_atomic_pte = kmap_atomic, | 387 | .kmap_atomic_pte = kmap_atomic, |
385 | #endif | 388 | #endif |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 73fb0c4c150a..0b7553cbc529 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1138,6 +1138,9 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1138 | .set_pte_at = xen_set_pte_at, | 1138 | .set_pte_at = xen_set_pte_at, |
1139 | .set_pmd = xen_set_pmd_hyper, | 1139 | .set_pmd = xen_set_pmd_hyper, |
1140 | 1140 | ||
1141 | .ptep_modify_prot_start = __ptep_modify_prot_start, | ||
1142 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, | ||
1143 | |||
1141 | .pte_val = xen_pte_val, | 1144 | .pte_val = xen_pte_val, |
1142 | .pte_flags = native_pte_val, | 1145 | .pte_flags = native_pte_val, |
1143 | .pgd_val = xen_pgd_val, | 1146 | .pgd_val = xen_pgd_val, |
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 5ea37a48eecb..e9ada314dfc1 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
@@ -238,6 +238,11 @@ struct pv_mmu_ops { | |||
238 | void (*pte_update_defer)(struct mm_struct *mm, | 238 | void (*pte_update_defer)(struct mm_struct *mm, |
239 | unsigned long addr, pte_t *ptep); | 239 | unsigned long addr, pte_t *ptep); |
240 | 240 | ||
241 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, | ||
242 | pte_t *ptep); | ||
243 | void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, | ||
244 | pte_t *ptep, pte_t pte); | ||
245 | |||
241 | pteval_t (*pte_val)(pte_t); | 246 | pteval_t (*pte_val)(pte_t); |
242 | pteval_t (*pte_flags)(pte_t); | 247 | pteval_t (*pte_flags)(pte_t); |
243 | pte_t (*make_pte)(pteval_t pte); | 248 | pte_t (*make_pte)(pteval_t pte); |
@@ -1039,6 +1044,29 @@ static inline pgdval_t pgd_val(pgd_t pgd) | |||
1039 | return ret; | 1044 | return ret; |
1040 | } | 1045 | } |
1041 | 1046 | ||
1047 | #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION | ||
1048 | static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, | ||
1049 | pte_t *ptep) | ||
1050 | { | ||
1051 | pteval_t ret; | ||
1052 | |||
1053 | ret = PVOP_CALL3(pteval_t, pv_mmu_ops.ptep_modify_prot_start, | ||
1054 | mm, addr, ptep); | ||
1055 | |||
1056 | return (pte_t) { .pte = ret }; | ||
1057 | } | ||
1058 | |||
1059 | static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | ||
1060 | pte_t *ptep, pte_t pte) | ||
1061 | { | ||
1062 | if (sizeof(pteval_t) > sizeof(long)) | ||
1063 | /* 5 arg words */ | ||
1064 | pv_mmu_ops.ptep_modify_prot_commit(mm, addr, ptep, pte); | ||
1065 | else | ||
1066 | PVOP_VCALL4(pv_mmu_ops.ptep_modify_prot_commit, | ||
1067 | mm, addr, ptep, pte.pte); | ||
1068 | } | ||
1069 | |||
1042 | static inline void set_pte(pte_t *ptep, pte_t pte) | 1070 | static inline void set_pte(pte_t *ptep, pte_t pte) |
1043 | { | 1071 | { |
1044 | if (sizeof(pteval_t) > sizeof(long)) | 1072 | if (sizeof(pteval_t) > sizeof(long)) |