paravirt: add hooks for ptep_modify_prot_start/commit
This patch adds paravirt-ops hooks in pv_mmu_ops for ptep_modify_prot_start and ptep_modify_prot_commit. This allows the hypervisor-specific backends to implement these in some more efficient way. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
1ea0704e0d
commit
08b882c627
@@ -380,6 +380,9 @@ struct pv_mmu_ops pv_mmu_ops = {
|
|||||||
.pte_update = paravirt_nop,
|
.pte_update = paravirt_nop,
|
||||||
.pte_update_defer = paravirt_nop,
|
.pte_update_defer = paravirt_nop,
|
||||||
|
|
||||||
|
.ptep_modify_prot_start = __ptep_modify_prot_start,
|
||||||
|
.ptep_modify_prot_commit = __ptep_modify_prot_commit,
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPTE
|
#ifdef CONFIG_HIGHPTE
|
||||||
.kmap_atomic_pte = kmap_atomic,
|
.kmap_atomic_pte = kmap_atomic,
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1138,6 +1138,9 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
|||||||
.set_pte_at = xen_set_pte_at,
|
.set_pte_at = xen_set_pte_at,
|
||||||
.set_pmd = xen_set_pmd_hyper,
|
.set_pmd = xen_set_pmd_hyper,
|
||||||
|
|
||||||
|
.ptep_modify_prot_start = __ptep_modify_prot_start,
|
||||||
|
.ptep_modify_prot_commit = __ptep_modify_prot_commit,
|
||||||
|
|
||||||
.pte_val = xen_pte_val,
|
.pte_val = xen_pte_val,
|
||||||
.pte_flags = native_pte_val,
|
.pte_flags = native_pte_val,
|
||||||
.pgd_val = xen_pgd_val,
|
.pgd_val = xen_pgd_val,
|
||||||
|
@@ -238,6 +238,11 @@ struct pv_mmu_ops {
|
|||||||
void (*pte_update_defer)(struct mm_struct *mm,
|
void (*pte_update_defer)(struct mm_struct *mm,
|
||||||
unsigned long addr, pte_t *ptep);
|
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_val)(pte_t);
|
||||||
pteval_t (*pte_flags)(pte_t);
|
pteval_t (*pte_flags)(pte_t);
|
||||||
pte_t (*make_pte)(pteval_t pte);
|
pte_t (*make_pte)(pteval_t pte);
|
||||||
@@ -1039,6 +1044,29 @@ static inline pgdval_t pgd_val(pgd_t pgd)
|
|||||||
return ret;
|
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)
|
static inline void set_pte(pte_t *ptep, pte_t pte)
|
||||||
{
|
{
|
||||||
if (sizeof(pteval_t) > sizeof(long))
|
if (sizeof(pteval_t) > sizeof(long))
|
||||||
|
Reference in New Issue
Block a user