x86: fix EFER handling

Introduce a per-CPU shadow of what is currently in EFER, as context
switch code must re-write this MSR so that all guests run with
appropriate EFER.SCE and EFER.NX settings. Remove EFER from the set of
MSRs that VMX deals with in a generic fashion.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
This commit is contained in:
kfraser@localhost.localdomain committed 2007-05-15 10:43:18 +01:00
1 parent 71adf3c9eb
commit f1bd686887
11 files changed
+188 -75

No files matched your search

+8 -10
View File
@@ -47,6 +47,7 @@
#endif
DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
DEFINE_PER_CPU(__u64, efer);
static void paravirt_ctxt_switch_from(struct vcpu *v);
static void paravirt_ctxt_switch_to(struct vcpu *v);
@@ -1135,21 +1136,18 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
__context_switch();
#ifdef CONFIG_COMPAT
if ( is_idle_vcpu(prev) ||
(is_pv_32on64_domain(prev->domain) !=
is_pv_32on64_domain(next->domain)) )
if ( !is_hvm_vcpu(next) &&
(is_idle_vcpu(prev) ||
is_hvm_vcpu(prev) ||
is_pv_32on64_vcpu(prev) != is_pv_32on64_vcpu(next)) )
{
uint32_t efer_lo, efer_hi;
uint64_t efer = read_efer();
local_flush_tlb_one(GDT_VIRT_START(next) +
FIRST_RESERVED_GDT_BYTE);
rdmsr(MSR_EFER, efer_lo, efer_hi);
if ( !is_pv_32on64_domain(next->domain) == !(efer_lo & EFER_SCE) )
{
efer_lo ^= EFER_SCE;
wrmsr(MSR_EFER, efer_lo, efer_hi);
}
if ( !is_pv_32on64_vcpu(next) == !(efer & EFER_SCE) )
write_efer(efer ^ EFER_SCE);
}
#endif
+14 -12
View File
@@ -93,11 +93,8 @@ static inline void svm_inject_exception(struct vcpu *v, int trap,
static void stop_svm(void)
{
u32 eax, edx;
/* We turn off the EFER_SVME bit. */
rdmsr(MSR_EFER, eax, edx);
eax &= ~EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
write_efer(read_efer() & ~EFER_SVME);
}
static void svm_store_cpu_guest_regs(
@@ -138,7 +135,13 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
case MSR_EFER:
/* Offending reserved bit will cause #GP. */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
#ifdef __x86_64__
if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
#else
if ( (msr_content & ~(EFER_NX | EFER_SCE)) ||
#endif
(!cpu_has_nx && (msr_content & EFER_NX)) ||
(!cpu_has_syscall && (msr_content & EFER_SCE)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
@@ -495,7 +498,7 @@ int svm_vmcb_restore(struct vcpu *v, struct hvm_hw_cpu *c)
}
void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
static void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -511,7 +514,7 @@ void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
}
void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
static void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -530,13 +533,13 @@ void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
hvm_set_guest_time(v, data->tsc);
}
void svm_save_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
static void svm_save_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
{
svm_save_cpu_state(v, ctxt);
svm_vmcb_save(v, ctxt);
}
int svm_load_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
static int svm_load_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
{
svm_load_cpu_state(v, ctxt);
if (svm_vmcb_restore(v, ctxt)) {
@@ -911,6 +914,7 @@ static struct hvm_function_table svm_function_table = {
.paging_enabled = svm_paging_enabled,
.long_mode_enabled = svm_long_mode_enabled,
.pae_enabled = svm_pae_enabled,
.nx_enabled = svm_nx_enabled,
.interrupts_enabled = svm_interrupts_enabled,
.guest_x86_mode = svm_guest_x86_mode,
.get_guest_ctrl_reg = svm_get_ctrl_reg,
@@ -967,9 +971,7 @@ int start_svm(void)
((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
return 0;
rdmsr(MSR_EFER, eax, edx);
eax |= EFER_SVME;
wrmsr(MSR_EFER, eax, edx);
write_efer(read_efer() | EFER_SVME);
svm_npt_detect();
-5
View File
@@ -285,11 +285,6 @@ static void construct_vmcs(struct vcpu *v)
vmx_vmcs_enter(v);
v->arch.hvm_vmx.cpu_cr2 = 0;
v->arch.hvm_vmx.cpu_cr3 = 0;
memset(&v->arch.hvm_vmx.msr_state, 0, sizeof(v->arch.hvm_vmx.msr_state));
v->arch.hvm_vmx.vmxassist_enabled = 0;
/* VMCS controls. */
__vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
__vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
+114 -34
View File
@@ -89,7 +89,7 @@ static DEFINE_PER_CPU(struct vmx_msr_state, host_msr_state);
static u32 msr_index[VMX_MSR_COUNT] =
{
MSR_LSTAR, MSR_STAR, MSR_CSTAR,
MSR_SYSCALL_MASK, MSR_EFER,
MSR_SYSCALL_MASK
};
static void vmx_save_host_msrs(void)
@@ -116,8 +116,7 @@ static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
switch ( (u32)regs->ecx ) {
case MSR_EFER:
HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content);
msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_EFER];
msr_content = v->arch.hvm_vmx.efer;
break;
case MSR_FS_BASE:
@@ -129,7 +128,7 @@ static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
goto check_long_mode;
case MSR_SHADOW_GS_BASE:
msr_content = guest_msr_state->shadow_gs;
msr_content = v->arch.hvm_vmx.shadow_gs;
check_long_mode:
if ( !(vmx_long_mode_enabled(v)) )
{
@@ -181,7 +180,9 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
(!cpu_has_nx && (msr_content & EFER_NX)) ||
(!cpu_has_syscall && (msr_content & EFER_SCE)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
@@ -189,7 +190,7 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
}
if ( (msr_content & EFER_LME)
&& !(guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) )
&& !(v->arch.hvm_vmx.efer & EFER_LME) )
{
if ( unlikely(vmx_paging_enabled(v)) )
{
@@ -199,7 +200,7 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
}
}
else if ( !(msr_content & EFER_LME)
&& (guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) )
&& (v->arch.hvm_vmx.efer & EFER_LME) )
{
if ( unlikely(vmx_paging_enabled(v)) )
{
@@ -209,7 +210,11 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
}
}
guest_msr_state->msrs[VMX_INDEX_MSR_EFER] = msr_content;
if ( (msr_content ^ v->arch.hvm_vmx.efer) & (EFER_NX|EFER_SCE) )
write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
(msr_content & (EFER_NX|EFER_SCE)));
v->arch.hvm_vmx.efer = msr_content;
break;
case MSR_FS_BASE:
@@ -227,7 +232,7 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
__vmwrite(GUEST_GS_BASE, msr_content);
else
{
v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
v->arch.hvm_vmx.shadow_gs = msr_content;
wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
}
@@ -279,12 +284,14 @@ static void vmx_restore_host_msrs(void)
wrmsrl(msr_index[i], host_msr_state->msrs[i]);
clear_bit(i, &host_msr_state->flags);
}
if ( cpu_has_nx && !(read_efer() & EFER_NX) )
write_efer(read_efer() | EFER_NX);
}
static void vmx_save_guest_msrs(struct vcpu *v)
{
/* MSR_SHADOW_GS_BASE may have been changed by swapgs instruction. */
rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.msr_state.shadow_gs);
rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
}
static void vmx_restore_guest_msrs(struct vcpu *v)
@@ -296,11 +303,9 @@ static void vmx_restore_guest_msrs(struct vcpu *v)
guest_msr_state = &v->arch.hvm_vmx.msr_state;
host_msr_state = &this_cpu(host_msr_state);
wrmsrl(MSR_SHADOW_GS_BASE, guest_msr_state->shadow_gs);
wrmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
guest_flags = guest_msr_state->flags;
if ( !guest_flags )
return;
while ( guest_flags ) {
i = find_first_set_bit(guest_flags);
@@ -312,23 +317,90 @@ static void vmx_restore_guest_msrs(struct vcpu *v)
wrmsrl(msr_index[i], guest_msr_state->msrs[i]);
clear_bit(i, &guest_flags);
}
if ( (v->arch.hvm_vmx.efer ^ read_efer()) & (EFER_NX|EFER_SCE) )
{
HVM_DBG_LOG(DBG_LEVEL_2,
"restore guest's EFER with value %lx",
v->arch.hvm_vmx.efer);
write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
(v->arch.hvm_vmx.efer & (EFER_NX|EFER_SCE)));
}
}
#else /* __i386__ */
#define vmx_save_host_msrs() ((void)0)
#define vmx_restore_host_msrs() ((void)0)
static void vmx_restore_host_msrs(void)
{
if ( cpu_has_nx && !(read_efer() & EFER_NX) )
write_efer(read_efer() | EFER_NX);
}
#define vmx_save_guest_msrs(v) ((void)0)
#define vmx_restore_guest_msrs(v) ((void)0)
static void vmx_restore_guest_msrs(struct vcpu *v)
{
if ( (v->arch.hvm_vmx.efer ^ read_efer()) & EFER_NX )
{
HVM_DBG_LOG(DBG_LEVEL_2,
"restore guest's EFER with value %lx",
v->arch.hvm_vmx.efer);
write_efer((read_efer() & ~EFER_NX) |
(v->arch.hvm_vmx.efer & EFER_NX));
}
}
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
return 0;
u64 msr_content = 0;
struct vcpu *v = current;
switch ( regs->ecx ) {
case MSR_EFER:
msr_content = v->arch.hvm_vmx.efer;
break;
default:
return 0;
}
regs->eax = msr_content >> 0;
regs->edx = msr_content >> 32;
return 1;
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
return 0;
u64 msr_content = regs->eax | ((u64)regs->edx << 32);
struct vcpu *v = current;
switch ( regs->ecx )
{
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( (msr_content & ~EFER_NX) ||
(!cpu_has_nx && (msr_content & EFER_NX)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
return 0;
}
if ( (msr_content ^ v->arch.hvm_vmx.efer) & EFER_NX )
write_efer((read_efer() & ~EFER_NX) | (msr_content & EFER_NX));
v->arch.hvm_vmx.efer = msr_content;
break;
default:
return 0;
}
return 1;
}
#endif /* __i386__ */
@@ -636,7 +708,7 @@ int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
return -EINVAL;
}
#ifdef HVM_DEBUG_SUSPEND
#if defined(__x86_64__) && defined(HVM_DEBUG_SUSPEND)
static void dump_msr_state(struct vmx_msr_state *m)
{
int i = 0;
@@ -647,17 +719,16 @@ static void dump_msr_state(struct vmx_msr_state *m)
printk("\n");
}
#else
static void dump_msr_state(struct vmx_msr_state *m)
{
}
#define dump_msr_state(m) ((void)0)
#endif
void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
static void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
{
#ifdef __x86_64__
struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
unsigned long guest_flags = guest_state->flags;
data->shadow_gs = guest_state->shadow_gs;
data->shadow_gs = v->arch.hvm_vmx.shadow_gs;
/* save msrs */
data->msr_flags = guest_flags;
@@ -665,15 +736,18 @@ void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
data->msr_star = guest_state->msrs[VMX_INDEX_MSR_STAR];
data->msr_cstar = guest_state->msrs[VMX_INDEX_MSR_CSTAR];
data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
data->msr_efer = guest_state->msrs[VMX_INDEX_MSR_EFER];
#endif
data->msr_efer = v->arch.hvm_vmx.efer;
data->tsc = hvm_get_guest_time(v);
dump_msr_state(guest_state);
}
void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
static void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
{
#ifdef __x86_64__
struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
/* restore msrs */
@@ -682,9 +756,11 @@ void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
guest_state->msrs[VMX_INDEX_MSR_STAR] = data->msr_star;
guest_state->msrs[VMX_INDEX_MSR_CSTAR] = data->msr_cstar;
guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK] = data->msr_syscall_mask;
guest_state->msrs[VMX_INDEX_MSR_EFER] = data->msr_efer;
guest_state->shadow_gs = data->shadow_gs;
v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
#endif
v->arch.hvm_vmx.efer = data->msr_efer;
v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
@@ -694,7 +770,7 @@ void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
}
void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
static void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
{
vmx_save_cpu_state(v, ctxt);
vmx_vmcs_enter(v);
@@ -702,7 +778,7 @@ void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
vmx_vmcs_exit(v);
}
int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
static int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
{
vmx_load_cpu_state(v, ctxt);
if (vmx_vmcs_restore(v, ctxt)) {
@@ -1016,6 +1092,11 @@ static int vmx_pae_enabled(struct vcpu *v)
return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
}
static int vmx_nx_enabled(struct vcpu *v)
{
return v->arch.hvm_vmx.efer & EFER_NX;
}
static int vmx_interrupts_enabled(struct vcpu *v)
{
unsigned long eflags = __vmread(GUEST_RFLAGS);
@@ -1096,6 +1177,7 @@ static struct hvm_function_table vmx_function_table = {
.paging_enabled = vmx_paging_enabled,
.long_mode_enabled = vmx_long_mode_enabled,
.pae_enabled = vmx_pae_enabled,
.nx_enabled = vmx_nx_enabled,
.interrupts_enabled = vmx_interrupts_enabled,
.guest_x86_mode = vmx_guest_x86_mode,
.get_guest_ctrl_reg = vmx_get_ctrl_reg,
@@ -1996,8 +2078,7 @@ static int vmx_set_cr0(unsigned long value)
else
{
HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode\n");
v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]
|= EFER_LMA;
v->arch.hvm_vmx.efer |= EFER_LMA;
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
vm_entry_value |= VM_ENTRY_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
@@ -2046,8 +2127,7 @@ static int vmx_set_cr0(unsigned long value)
*/
if ( vmx_long_mode_enabled(v) )
{
v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]
&= ~EFER_LMA;
v->arch.hvm_vmx.efer &= ~EFER_LMA;
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
@@ -2079,7 +2159,7 @@ static int vmx_set_cr0(unsigned long value)
{
if ( vmx_long_mode_enabled(v) )
{
v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER] &= ~EFER_LMA;
v->arch.hvm_vmx.efer &= ~EFER_LMA;
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
+4 -4
View File
@@ -181,11 +181,11 @@ guest_supports_superpages(struct vcpu *v)
static inline int
guest_supports_nx(struct vcpu *v)
{
if ( GUEST_PAGING_LEVELS == 2 || !cpu_has_nx )
return 0;
if ( !is_hvm_vcpu(v) )
return cpu_has_nx;
// XXX - fix this!
return 1;
return 1;
return hvm_nx_enabled(v);
}
+2
View File
@@ -114,6 +114,7 @@
#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
#define cpu_has_syscall boot_cpu_has(X86_FEATURE_SYSCALL)
#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR)
@@ -136,6 +137,7 @@
#define cpu_has_xmm2 1
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
#define cpu_has_syscall 1
#define cpu_has_mp 1
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
#define cpu_has_k6_mtrr 0
+13 -4
View File
@@ -93,14 +93,17 @@ struct hvm_function_table {
* 1) determine whether paging is enabled,
* 2) determine whether long mode is enabled,
* 3) determine whether PAE paging is enabled,
* 4) determine whether interrupts are enabled or not,
* 5) determine the mode the guest is running in,
* 6) return the current guest control-register value
* 7) return the current guest segment descriptor base
* 4) determine whether NX is enabled,
* 5) determine whether interrupts are enabled or not,
* 6) determine the mode the guest is running in,
* 7) return the current guest control-register value
* 8) return the current guest segment descriptor base
* 9) return the current guest segment descriptor
*/
int (*paging_enabled)(struct vcpu *v);
int (*long_mode_enabled)(struct vcpu *v);
int (*pae_enabled)(struct vcpu *v);
int (*nx_enabled)(struct vcpu *v);
int (*interrupts_enabled)(struct vcpu *v);
int (*guest_x86_mode)(struct vcpu *v);
unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
@@ -198,6 +201,12 @@ hvm_interrupts_enabled(struct vcpu *v)
return hvm_funcs.interrupts_enabled(v);
}
static inline int
hvm_nx_enabled(struct vcpu *v)
{
return hvm_funcs.nx_enabled(v);
}
static inline int
hvm_guest_x86_mode(struct vcpu *v)
{
+5
View File
@@ -60,6 +60,11 @@ static inline int svm_pae_enabled(struct vcpu *v)
return svm_paging_enabled(v) && (guest_cr4 & X86_CR4_PAE);
}
static inline int svm_nx_enabled(struct vcpu *v)
{
return v->arch.hvm_svm.cpu_shadow_efer & EFER_NX;
}
static inline int svm_pgbit_test(struct vcpu *v)
{
return v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_PG;
+4 -2
View File
@@ -39,7 +39,6 @@ enum {
VMX_INDEX_MSR_STAR,
VMX_INDEX_MSR_CSTAR,
VMX_INDEX_MSR_SYSCALL_MASK,
VMX_INDEX_MSR_EFER,
VMX_MSR_COUNT
};
@@ -47,7 +46,6 @@ enum {
struct vmx_msr_state {
unsigned long flags;
unsigned long msrs[VMX_MSR_COUNT];
unsigned long shadow_gs;
};
struct arch_vmx_struct {
@@ -76,7 +74,11 @@ struct arch_vmx_struct {
unsigned long cpu_shadow_cr4; /* copy of guest read shadow CR4 */
unsigned long cpu_cr2; /* save CR2 */
unsigned long cpu_cr3;
#ifdef __x86_64__
struct vmx_msr_state msr_state;
unsigned long shadow_gs;
#endif
unsigned long efer;
unsigned long vmxassist_enabled:1;
};
+2 -4
View File
@@ -261,14 +261,12 @@ static inline int vmx_paging_enabled(struct vcpu *v)
static inline int vmx_long_mode_enabled(struct vcpu *v)
{
u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER];
return efer & EFER_LMA;
return v->arch.hvm_vmx.efer & EFER_LMA;
}
static inline int vmx_lme_is_set(struct vcpu *v)
{
u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER];
return efer & EFER_LME;
return v->arch.hvm_vmx.efer & EFER_LME;
}
static inline int vmx_pgbit_test(struct vcpu *v)
+22
View File
@@ -3,6 +3,9 @@
#ifndef __ASSEMBLY__
#include <xen/smp.h>
#include <xen/percpu.h>
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
@@ -142,6 +145,25 @@ static inline void wrmsrl(unsigned int msr, __u64 val)
#define EFER_NX (1<<_EFER_NX)
#define EFER_SVME (1<<_EFER_SVME)
#ifndef __ASSEMBLY__
DECLARE_PER_CPU(__u64, efer);
static inline __u64 read_efer(void)
{
if (!this_cpu(efer))
rdmsrl(MSR_EFER, this_cpu(efer));
return this_cpu(efer);
}
static inline void write_efer(__u64 val)
{
this_cpu(efer) = val;
wrmsrl(MSR_EFER, val);
}
#endif
/* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_PLATFORM_ID 0x17
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.