mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/mm: pagetable_dying() is HVM-only
Its only caller lives in HVM-only code.
This involves wider changes, in order to limit #ifdef-ary: Shadow's
SHOPT_FAST_EMULATION and the fields used by it get constrained to HVM
builds as well. Additionally the shadow_{init,continue}_emulation()
stubs for the !HVM case aren't needed anymore and hence get dropped.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
This commit is contained in:
1 parent
8b8d011ad8
commit
2fb2dee1ac
7 files changed
+37
-24
No files matched your search
@@ -851,6 +851,7 @@ int paging_enable(struct domain *d, u32 mode)
|
||||
return shadow_enable(d, mode);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
/* Called from the guest to indicate that a process is being torn down
|
||||
* and therefore its pagetables will soon be discarded */
|
||||
void pagetable_dying(paddr_t gpa)
|
||||
@@ -865,6 +866,7 @@ void pagetable_dying(paddr_t gpa)
|
||||
BUG();
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_HVM */
|
||||
|
||||
/* Print paging-assistance info to the console */
|
||||
void paging_dump_domain_info(struct domain *d)
|
||||
|
||||
@@ -66,7 +66,9 @@ int shadow_domain_init(struct domain *d)
|
||||
#if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
|
||||
d->arch.paging.shadow.oos_active = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_HVM
|
||||
d->arch.paging.shadow.pagetable_dying_op = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -690,8 +692,10 @@ void shadow_promote(struct domain *d, mfn_t gmfn, unsigned int type)
|
||||
if ( !test_and_set_bit(_PGC_page_table, &page->count_info) )
|
||||
{
|
||||
page->shadow_flags = 0;
|
||||
#ifdef CONFIG_HVM
|
||||
if ( is_hvm_domain(d) )
|
||||
page->pagetable_dying = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
ASSERT(!(page->shadow_flags & (1u << type)));
|
||||
|
||||
@@ -2764,8 +2764,10 @@ static int sh_page_fault(struct vcpu *v,
|
||||
mfn_t gmfn, sl1mfn = _mfn(0);
|
||||
shadow_l1e_t sl1e, *ptr_sl1e;
|
||||
paddr_t gpa;
|
||||
#ifdef CONFIG_HVM
|
||||
struct sh_emulate_ctxt emul_ctxt;
|
||||
const struct x86_emulate_ops *emul_ops;
|
||||
#endif
|
||||
int r;
|
||||
p2m_type_t p2mt;
|
||||
uint32_t rc, error_code;
|
||||
@@ -3253,7 +3255,13 @@ static int sh_page_fault(struct vcpu *v,
|
||||
* caught by user-mode page-table check above.
|
||||
*/
|
||||
emulate_readonly:
|
||||
if ( !is_hvm_domain(d) )
|
||||
{
|
||||
ASSERT_UNREACHABLE();
|
||||
goto not_a_shadow_fault;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
/* Unshadow if we are writing to a toplevel pagetable that is
|
||||
* flagged as a dying process, and that is not currently used. */
|
||||
if ( sh_mfn_is_a_page_table(gmfn) && is_hvm_domain(d) &&
|
||||
@@ -3302,8 +3310,6 @@ static int sh_page_fault(struct vcpu *v,
|
||||
#if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
|
||||
early_emulation:
|
||||
#endif
|
||||
if ( is_hvm_domain(d) )
|
||||
{
|
||||
/*
|
||||
* If we are in the middle of injecting an exception or interrupt then
|
||||
* we should not emulate: the fault is a side effect of the processor
|
||||
@@ -3327,18 +3333,14 @@ static int sh_page_fault(struct vcpu *v,
|
||||
va, gfn);
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
}
|
||||
|
||||
SHADOW_PRINTK("emulate: eip=%#lx esp=%#lx\n", regs->rip, regs->rsp);
|
||||
|
||||
emul_ops = shadow_init_emulation(&emul_ctxt, regs, GUEST_PTE_SIZE);
|
||||
|
||||
r = x86_emulate(&emul_ctxt.ctxt, emul_ops);
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
if ( r == X86EMUL_EXCEPTION )
|
||||
{
|
||||
ASSERT(is_hvm_domain(d));
|
||||
/*
|
||||
* This emulation covers writes to shadow pagetables. We tolerate #PF
|
||||
* (from accesses spanning pages, concurrent paging updated from
|
||||
@@ -3360,7 +3362,6 @@ static int sh_page_fault(struct vcpu *v,
|
||||
r = X86EMUL_UNHANDLEABLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NB. We do not unshadow on X86EMUL_EXCEPTION. It's not clear that it
|
||||
@@ -3466,6 +3467,7 @@ static int sh_page_fault(struct vcpu *v,
|
||||
emulate_done:
|
||||
SHADOW_PRINTK("emulated\n");
|
||||
return EXCRET_fault_fixed;
|
||||
#endif /* CONFIG_HVM */
|
||||
|
||||
mmio:
|
||||
if ( !guest_mode(regs) )
|
||||
@@ -4166,7 +4168,9 @@ sh_update_cr3(struct vcpu *v, int do_locking, bool noflush)
|
||||
int sh_rm_write_access_from_sl1p(struct domain *d, mfn_t gmfn,
|
||||
mfn_t smfn, unsigned long off)
|
||||
{
|
||||
#ifdef CONFIG_HVM
|
||||
struct vcpu *curr = current;
|
||||
#endif
|
||||
int r;
|
||||
shadow_l1e_t *sl1p, sl1e;
|
||||
struct page_info *sp;
|
||||
@@ -4174,10 +4178,12 @@ int sh_rm_write_access_from_sl1p(struct domain *d, mfn_t gmfn,
|
||||
ASSERT(mfn_valid(gmfn));
|
||||
ASSERT(mfn_valid(smfn));
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
/* Remember if we've been told that this process is being torn down */
|
||||
if ( curr->domain == d && is_hvm_domain(d) )
|
||||
curr->arch.paging.shadow.pagetable_dying
|
||||
= mfn_to_page(gmfn)->pagetable_dying;
|
||||
#endif
|
||||
|
||||
sp = mfn_to_page(smfn);
|
||||
|
||||
@@ -4433,6 +4439,7 @@ int sh_remove_l3_shadow(struct domain *d, mfn_t sl4mfn, mfn_t sl3mfn)
|
||||
}
|
||||
#endif /* 64bit guest */
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
/**************************************************************************/
|
||||
/* Function for the guest to inform us that a process is being torn
|
||||
* down. We remember that as a hint to unshadow its pagetables soon,
|
||||
@@ -4554,6 +4561,7 @@ static void sh_pagetable_dying(paddr_t gpa)
|
||||
put_gfn(d, gpa >> PAGE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_HVM */
|
||||
|
||||
/**************************************************************************/
|
||||
/* Audit tools */
|
||||
@@ -4887,8 +4895,8 @@ const struct paging_mode sh_paging_mode = {
|
||||
#if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
|
||||
.shadow.guess_wrmap = sh_guess_wrmap,
|
||||
#endif
|
||||
#endif /* CONFIG_HVM */
|
||||
.shadow.pagetable_dying = sh_pagetable_dying,
|
||||
#endif /* CONFIG_HVM */
|
||||
.shadow.trace_emul_write_val = trace_emulate_write_val,
|
||||
.shadow.shadow_levels = SHADOW_PAGING_LEVELS,
|
||||
};
|
||||
|
||||
@@ -66,7 +66,11 @@ extern int shadow_audit_enable;
|
||||
#define SHOPT_FAST_EMULATION 0x80 /* Fast write emulation */
|
||||
#define SHOPT_OUT_OF_SYNC 0x100 /* Allow guest writes to L1 PTs */
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
#define SHADOW_OPTIMIZATIONS 0x1ff
|
||||
#else
|
||||
#define SHADOW_OPTIMIZATIONS (0x1ff & ~SHOPT_FAST_EMULATION)
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@@ -716,26 +720,11 @@ struct sh_emulate_ctxt {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
const struct x86_emulate_ops *shadow_init_emulation(
|
||||
struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs,
|
||||
unsigned int pte_size);
|
||||
void shadow_continue_emulation(
|
||||
struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs);
|
||||
#else
|
||||
static inline const struct x86_emulate_ops *shadow_init_emulation(
|
||||
struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs,
|
||||
unsigned int pte_size)
|
||||
{
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
static inline void shadow_continue_emulation(
|
||||
struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Stop counting towards early unshadows, as we've seen a real page fault */
|
||||
static inline void sh_reset_early_unshadow(struct vcpu *v)
|
||||
|
||||
@@ -117,8 +117,10 @@ struct shadow_domain {
|
||||
/* OOS */
|
||||
bool_t oos_active;
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
/* Has this domain ever used HVMOP_pagetable_dying? */
|
||||
bool_t pagetable_dying_op;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PV
|
||||
/* PV L1 Terminal Fault mitigation. */
|
||||
@@ -137,10 +139,12 @@ struct shadow_vcpu {
|
||||
unsigned long last_emulated_mfn_for_unshadow;
|
||||
/* MFN of the last shadow that we shot a writeable mapping in */
|
||||
unsigned long last_writeable_pte_smfn;
|
||||
#ifdef CONFIG_HVM
|
||||
/* Last frame number that we emulated a write to. */
|
||||
unsigned long last_emulated_frame;
|
||||
/* Last MFN that we emulated a write successfully */
|
||||
unsigned long last_emulated_mfn;
|
||||
#endif
|
||||
|
||||
/* Shadow out-of-sync: pages that this vcpu has let go out of sync */
|
||||
mfn_t oos[SHADOW_OOS_PAGES];
|
||||
@@ -151,8 +155,10 @@ struct shadow_vcpu {
|
||||
unsigned long off[SHADOW_OOS_FIXUPS];
|
||||
} oos_fixup[SHADOW_OOS_PAGES];
|
||||
|
||||
#ifdef CONFIG_HVM
|
||||
bool_t pagetable_dying;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/************************************************/
|
||||
@@ -225,10 +231,12 @@ struct paging_vcpu {
|
||||
const struct paging_mode *mode;
|
||||
/* Nested Virtualization: paging mode of nested guest */
|
||||
const struct paging_mode *nestedmode;
|
||||
#ifdef CONFIG_HVM
|
||||
/* HVM guest: last emulate was to a pagetable */
|
||||
unsigned int last_write_was_pt:1;
|
||||
/* HVM guest: last write emulation succeeds */
|
||||
unsigned int last_write_emul_ok:1;
|
||||
#endif
|
||||
/* Translated guest: virtual TLB */
|
||||
struct shadow_vtlb *vtlb;
|
||||
spinlock_t vtlb_lock;
|
||||
|
||||
@@ -287,7 +287,9 @@ struct page_info
|
||||
*/
|
||||
struct {
|
||||
uint16_t shadow_flags;
|
||||
#ifdef CONFIG_HVM
|
||||
bool pagetable_dying;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* When in use as a shadow, next shadow in this hash chain. */
|
||||
|
||||
@@ -107,8 +107,8 @@ struct shadow_paging_mode {
|
||||
void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
|
||||
int (*guess_wrmap )(struct vcpu *v,
|
||||
unsigned long vaddr, mfn_t gmfn);
|
||||
#endif
|
||||
void (*pagetable_dying )(paddr_t gpa);
|
||||
#endif
|
||||
void (*trace_emul_write_val )(const void *ptr, unsigned long vaddr,
|
||||
const void *src, unsigned int bytes);
|
||||
#endif
|
||||
|
||||