[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86: Allow PV guest set X86_CR4_PCE flag
With added PV support for VPMU, guests may legitimately decide to set CR4's PCE flag. We should allow this when VPMU is enabled. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> --- xen/arch/x86/cpu/vpmu.c | 19 +++++++++++++++++++ xen/arch/x86/domain.c | 13 ++++++++++++- xen/include/asm-x86/domain.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c index 8af3df1..8cac04e 100644 --- a/xen/arch/x86/cpu/vpmu.c +++ b/xen/arch/x86/cpu/vpmu.c @@ -81,6 +81,12 @@ static void __init parse_vpmu_param(char *s) } } +static void update_cr4_mask_pce(bool_t allow) +{ + pv_guest_update_cr4_mask(X86_CR4_PCE, 0, allow); + pv_guest_update_cr4_mask(X86_CR4_PCE, 1, allow); +} + void vpmu_lvtpc_update(uint32_t val) { struct vpmu_struct *vpmu; @@ -475,6 +481,7 @@ void vpmu_initialise(struct vcpu *v) printk(XENLOG_G_WARNING "VPMU: Unknown CPU vendor %d. " "Disabling VPMU\n", vendor); opt_vpmu_enabled = 0; + update_cr4_mask_pce(0); vpmu_mode = XENPMU_MODE_OFF; } return; /* Don't bother restoring vpmu_count, VPMU is off forever */ @@ -679,7 +686,16 @@ long do_xenpmu_op(unsigned int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg) if ( (vpmu_count == 0) || ((vpmu_mode ^ pmu_params.val) == (XENPMU_MODE_SELF | XENPMU_MODE_HV)) ) + { + if ( (vpmu_mode != XENPMU_MODE_OFF) && + (pmu_params.val == XENPMU_MODE_OFF) ) + update_cr4_mask_pce(0); + else if ( (vpmu_mode == XENPMU_MODE_OFF) && + (pmu_params.val != XENPMU_MODE_OFF) ) + update_cr4_mask_pce(1); + vpmu_mode = pmu_params.val; + } else if ( vpmu_mode != pmu_params.val ) { printk(XENLOG_WARNING @@ -807,8 +823,11 @@ static int __init vpmu_init(void) } if ( vpmu_mode != XENPMU_MODE_OFF ) + { + update_cr4_mask_pce(1); printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "." __stringify(XENPMU_VER_MIN) "\n"); + } else opt_vpmu_enabled = 0; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 045f6ff..71a2bb3 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -738,7 +738,18 @@ static int __init init_pv_cr4_masks(void) return 0; } -__initcall(init_pv_cr4_masks); +presmp_initcall(init_pv_cr4_masks); + +void pv_guest_update_cr4_mask(unsigned long mask, bool_t is_compat, + bool_t allow) +{ + unsigned long *curr_mask = is_compat ? &compat_pv_cr4_mask : &pv_cr4_mask; + + if ( !allow ) + *curr_mask |= mask; + else + *curr_mask &= ~mask; +} unsigned long pv_guest_cr4_fixup(const struct vcpu *v, unsigned long guest_cr4) { diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 0fce09e..9758b0a 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -561,6 +561,8 @@ void vcpu_show_registers(const struct vcpu *); /* Clean up CR4 bits that are not under guest control. */ unsigned long pv_guest_cr4_fixup(const struct vcpu *, unsigned long guest_cr4); +void pv_guest_update_cr4_mask(unsigned long mask, bool_t is_compat, + bool_t allow); /* Convert between guest-visible and real CR4 values. */ #define pv_guest_cr4_to_real_cr4(v) \ -- 1.8.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |