|
@@ -238,6 +238,11 @@ struct pv_mmu_ops {
|
|
|
void (*pte_update_defer)(struct mm_struct *mm,
|
|
|
unsigned long addr, pte_t *ptep);
|
|
|
|
|
|
+ pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep);
|
|
|
+ void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep, pte_t pte);
|
|
|
+
|
|
|
pteval_t (*pte_val)(pte_t);
|
|
|
pteval_t (*pte_flags)(pte_t);
|
|
|
pte_t (*make_pte)(pteval_t pte);
|
|
@@ -1039,6 +1044,29 @@ static inline pgdval_t pgd_val(pgd_t pgd)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
|
|
|
+static inline pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep)
|
|
|
+{
|
|
|
+ pteval_t ret;
|
|
|
+
|
|
|
+ ret = PVOP_CALL3(pteval_t, pv_mmu_ops.ptep_modify_prot_start,
|
|
|
+ mm, addr, ptep);
|
|
|
+
|
|
|
+ return (pte_t) { .pte = ret };
|
|
|
+}
|
|
|
+
|
|
|
+static inline void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
|
|
|
+ pte_t *ptep, pte_t pte)
|
|
|
+{
|
|
|
+ if (sizeof(pteval_t) > sizeof(long))
|
|
|
+ /* 5 arg words */
|
|
|
+ pv_mmu_ops.ptep_modify_prot_commit(mm, addr, ptep, pte);
|
|
|
+ else
|
|
|
+ PVOP_VCALL4(pv_mmu_ops.ptep_modify_prot_commit,
|
|
|
+ mm, addr, ptep, pte.pte);
|
|
|
+}
|
|
|
+
|
|
|
static inline void set_pte(pte_t *ptep, pte_t pte)
|
|
|
{
|
|
|
if (sizeof(pteval_t) > sizeof(long))
|