[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Fix PV guest CR4 handling. We should not leak hidden CR4 bits
# HG changeset patch # User Keir Fraser <keir@xxxxxxxxxxxxx> # Date 1194444944 0 # Node ID 00db9ec39831dc092cefc8bbf747ef90d19241a9 # Parent c982fe8a9f91faffe2bf08b308bca8a6e8f6c0f0 x86: Fix PV guest CR4 handling. We should not leak hidden CR4 bits into guest CR4 value. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/domain.c | 23 ++++++++++++++--------- xen/arch/x86/traps.c | 3 ++- xen/include/asm-x86/domain.h | 7 +++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff -r c982fe8a9f91 -r 00db9ec39831 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Wed Nov 07 13:41:29 2007 +0000 +++ b/xen/arch/x86/domain.c Wed Nov 07 14:15:44 2007 +0000 @@ -415,7 +415,8 @@ int vcpu_initialise(struct vcpu *v) v->arch.cr3 = __pa(idle_pg_table); } - v->arch.guest_context.ctrlreg[4] = mmu_cr4_features; + v->arch.guest_context.ctrlreg[4] = + real_cr4_to_pv_guest_cr4(mmu_cr4_features); } v->arch.perdomain_ptes = @@ -573,17 +574,18 @@ void arch_domain_destroy(struct domain * unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4) { - unsigned long hv_cr4 = read_cr4(), hv_cr4_mask = ~X86_CR4_TSD; + unsigned long hv_cr4_mask, hv_cr4 = real_cr4_to_pv_guest_cr4(read_cr4()); + + hv_cr4_mask = ~X86_CR4_TSD; if ( cpu_has_de ) hv_cr4_mask &= ~X86_CR4_DE; - if ( (guest_cr4 & hv_cr4_mask) != - (hv_cr4 & hv_cr4_mask & ~(X86_CR4_PGE|X86_CR4_PSE)) ) + if ( (guest_cr4 & hv_cr4_mask) != (hv_cr4 & hv_cr4_mask) ) gdprintk(XENLOG_WARNING, "Attempt to change CR4 flags %08lx -> %08lx\n", hv_cr4 & ~(X86_CR4_PGE|X86_CR4_PSE), guest_cr4); - return (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask); + return (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask); } /* This is called by arch_final_setup_guest and do_boot_vcpu */ @@ -684,8 +686,8 @@ int arch_set_info_guest( v->arch.guest_context.user_regs.eflags |= EF_IE; cr4 = v->arch.guest_context.ctrlreg[4]; - v->arch.guest_context.ctrlreg[4] = - (cr4 == 0) ? mmu_cr4_features : pv_guest_cr4_fixup(cr4); + v->arch.guest_context.ctrlreg[4] = cr4 ? pv_guest_cr4_fixup(cr4) : + real_cr4_to_pv_guest_cr4(mmu_cr4_features); memset(v->arch.guest_context.debugreg, 0, sizeof(v->arch.guest_context.debugreg)); @@ -1223,11 +1225,14 @@ static void paravirt_ctxt_switch_from(st static void paravirt_ctxt_switch_to(struct vcpu *v) { + unsigned long cr4; + set_int80_direct_trap(v); switch_kernel_stack(v); - if ( unlikely(read_cr4() != v->arch.guest_context.ctrlreg[4]) ) - write_cr4(v->arch.guest_context.ctrlreg[4]); + cr4 = pv_guest_cr4_to_real_cr4(v->arch.guest_context.ctrlreg[4]); + if ( unlikely(cr4 != read_cr4()) ) + write_cr4(cr4); if ( unlikely(v->arch.guest_context.debugreg[7]) ) { diff -r c982fe8a9f91 -r 00db9ec39831 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Wed Nov 07 13:41:29 2007 +0000 +++ b/xen/arch/x86/traps.c Wed Nov 07 14:15:44 2007 +0000 @@ -1797,7 +1797,8 @@ static int emulate_privileged_op(struct case 4: /* Write CR4 */ v->arch.guest_context.ctrlreg[4] = pv_guest_cr4_fixup(*reg); - write_cr4(v->arch.guest_context.ctrlreg[4]); + write_cr4(pv_guest_cr4_to_real_cr4( + v->arch.guest_context.ctrlreg[4])); break; default: diff -r c982fe8a9f91 -r 00db9ec39831 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Wed Nov 07 13:41:29 2007 +0000 +++ b/xen/include/asm-x86/domain.h Wed Nov 07 14:15:44 2007 +0000 @@ -350,7 +350,14 @@ struct arch_vcpu /* Continue the current hypercall via func(data) on specified cpu. */ int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data); +/* Clean up CR4 bits that are not under guest control. */ unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4); + +/* Convert between guest-visible and real CR4 values. */ +#define pv_guest_cr4_to_real_cr4(c) \ + ((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE))) +#define real_cr4_to_pv_guest_cr4(c) \ + ((c) & ~(X86_CR4_PGE | X86_CR4_PSE)) #endif /* __ASM_DOMAIN_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |