aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-16 22:26:38 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-16 22:26:38 +0000
commit5160866ad9ec4f3e3d2bf7b949303486a9110336 (patch)
tree5735ae0a118dff41b7e7dd395406101fe7ede944 /xen
parentf7a1cb1c2fd8ae8aab9641149b09853ed7e51a63 (diff)
downloadxen-5160866ad9ec4f3e3d2bf7b949303486a9110336.tar.gz
xen-5160866ad9ec4f3e3d2bf7b949303486a9110336.tar.bz2
xen-5160866ad9ec4f3e3d2bf7b949303486a9110336.zip
hvm: Clean up RDTSCP/TSC_AUX handling.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/x86/hvm/hvm.c16
-rw-r--r--xen/arch/x86/hvm/vmx/vmcs.c6
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c74
-rw-r--r--xen/include/asm-x86/hvm/vcpu.h2
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmcs.h1
-rw-r--r--xen/include/asm-x86/msr.h2
6 files changed, 23 insertions, 78 deletions
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 4db67b8357..2f6242b59c 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -478,6 +478,8 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
/* Architecture-specific vmcs/vmcb bits */
hvm_funcs.save_cpu_ctxt(v, &ctxt);
+ ctxt.msr_tsc_aux = v->arch.hvm_vcpu.msr_tsc_aux;
+
hvm_get_segment_register(v, x86_seg_idtr, &seg);
ctxt.idtr_limit = seg.limit;
ctxt.idtr_base = seg.base;
@@ -653,6 +655,8 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 )
return -EINVAL;
+ v->arch.hvm_vcpu.msr_tsc_aux = ctxt.msr_tsc_aux;
+
seg.limit = ctxt.idtr_limit;
seg.base = ctxt.idtr_base;
hvm_set_segment_register(v, x86_seg_idtr, &seg);
@@ -1929,6 +1933,10 @@ int hvm_msr_read_intercept(struct cpu_user_regs *regs)
msr_content = hvm_get_guest_tsc(v);
break;
+ case MSR_TSC_AUX:
+ msr_content = v->arch.hvm_vcpu.msr_tsc_aux;
+ break;
+
case MSR_IA32_APICBASE:
msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
break;
@@ -2017,10 +2025,16 @@ int hvm_msr_write_intercept(struct cpu_user_regs *regs)
switch ( ecx )
{
- case MSR_IA32_TSC:
+ case MSR_IA32_TSC:
hvm_set_guest_tsc(v, msr_content);
break;
+ case MSR_TSC_AUX:
+ v->arch.hvm_vcpu.msr_tsc_aux = (uint32_t)msr_content;
+ if ( cpu_has_rdtscp )
+ wrmsrl(MSR_TSC_AUX, (uint32_t)msr_content);
+ break;
+
case MSR_IA32_APICBASE:
vlapic_msr_set(vcpu_vlapic(v), msr_content);
break;
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index c4fe4c1ed3..a6a2f6851c 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -156,6 +156,7 @@ static void vmx_init_vmcs_config(void)
opt = (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
SECONDARY_EXEC_WBINVD_EXITING |
SECONDARY_EXEC_ENABLE_EPT |
+ SECONDARY_EXEC_ENABLE_RDTSCP |
SECONDARY_EXEC_PAUSE_LOOP_EXITING);
if ( opt_vpid_enabled )
opt |= SECONDARY_EXEC_ENABLE_VPID;
@@ -594,11 +595,6 @@ static int construct_vmcs(struct vcpu *v)
__vmwrite(PLE_WINDOW, ple_window);
}
-#ifdef __x86_64__
- if ( cpu_has_rdtscp )
- v->arch.hvm_vmx.secondary_exec_control |= SECONDARY_EXEC_ENABLE_RDTSCP;
-#endif
-
if ( cpu_has_vmx_secondary_exec_control )
__vmwrite(SECONDARY_VM_EXEC_CONTROL,
v->arch.hvm_vmx.secondary_exec_control);
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 9f302e8cb2..b75bd584af 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -148,19 +148,8 @@ static void vmx_save_host_msrs(void)
struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state);
int i;
- /*
- * If new MSR is needed to add into msr_index[] and VMX_INDEX_MSR_*** enum,
- * please note that elements in msr_index[] and VMX_INDEX_MSR_*** enum
- * are not the same. Currently we only save three MSRs(MSR_LSTAR, MSR_STAR,
- * and MSR_SYSCALL_MASK into host state.
- */
- BUILD_BUG_ON(MSR_INDEX_SIZE != VMX_INDEX_MSR_TSC_AUX ||
- VMX_INDEX_MSR_TSC_AUX != VMX_MSR_COUNT - 1);
for ( i = 0; i < MSR_INDEX_SIZE; i++ )
rdmsrl(msr_index[i], host_msr_state->msrs[i]);
-
- if ( cpu_has_rdtscp )
- rdmsrl(MSR_TSC_AUX, host_msr_state->msrs[VMX_INDEX_MSR_TSC_AUX]);
}
#define WRITE_MSR(address) \
@@ -211,21 +200,6 @@ static enum handler_return long_mode_do_msr_read(struct cpu_user_regs *regs)
msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
break;
- case MSR_TSC_AUX:
- if ( cpu_has_rdtscp )
- {
- msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_TSC_AUX];
- break;
- }
- else
- {
- HVM_DBG_LOG(DBG_LEVEL_0, "Reading from nonexistence msr 0x%x\n",
- ecx);
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
- return HNDL_exception_raised;
- }
-
-
default:
return HNDL_unhandled;
}
@@ -287,20 +261,6 @@ static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
case MSR_SYSCALL_MASK:
WRITE_MSR(SYSCALL_MASK);
- case MSR_TSC_AUX:
- if ( cpu_has_rdtscp )
- {
- struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
- guest_state->msrs[VMX_INDEX_MSR_TSC_AUX] = msr_content;
- wrmsrl(MSR_TSC_AUX, (uint32_t)msr_content);
- }
- else
- {
- HVM_DBG_LOG(DBG_LEVEL_0, "Writing to nonexistence msr 0x%x\n", ecx);
- vmx_inject_hw_exception(TRAP_gp_fault, 0);
- return HNDL_exception_raised;
- }
-
default:
return HNDL_unhandled;
}
@@ -331,22 +291,15 @@ 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_rdtscp )
- wrmsrl(MSR_TSC_AUX,
- (uint32_t)host_msr_state->msrs[VMX_INDEX_MSR_TSC_AUX]);
}
static void vmx_save_guest_msrs(struct vcpu *v)
{
- struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
/*
* We cannot cache SHADOW_GS_BASE while the VCPU runs, as it can
* be updated at any time via SWAPGS, which we cannot trap.
*/
rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
- if ( cpu_has_rdtscp )
- rdmsrl(MSR_TSC_AUX, guest_msr_state->msrs[VMX_INDEX_MSR_TSC_AUX]);
}
static void vmx_restore_guest_msrs(struct vcpu *v)
@@ -384,8 +337,7 @@ static void vmx_restore_guest_msrs(struct vcpu *v)
}
if ( cpu_has_rdtscp )
- wrmsrl(MSR_TSC_AUX,
- (uint32_t)guest_msr_state->msrs[VMX_INDEX_MSR_TSC_AUX]);
+ wrmsrl(MSR_TSC_AUX, v->arch.hvm_vcpu.msr_tsc_aux);
}
#else /* __i386__ */
@@ -627,10 +579,6 @@ static void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
data->msr_lstar = guest_state->msrs[VMX_INDEX_MSR_LSTAR];
data->msr_star = guest_state->msrs[VMX_INDEX_MSR_STAR];
data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
- if ( cpu_has_rdtscp )
- data->msr_tsc_aux = guest_state->msrs[VMX_INDEX_MSR_TSC_AUX];
- else
- data->msr_tsc_aux = 0;
#endif
data->tsc = hvm_get_guest_tsc(v);
@@ -649,10 +597,6 @@ static void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
v->arch.hvm_vmx.cstar = data->msr_cstar;
v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
- if ( cpu_has_rdtscp )
- guest_state->msrs[VMX_INDEX_MSR_TSC_AUX] = data->msr_tsc_aux;
- else
- guest_state->msrs[VMX_INDEX_MSR_TSC_AUX] = 0;
#endif
hvm_set_guest_tsc(v, data->tsc);
@@ -2545,29 +2489,19 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
hvm_hlt(regs->eflags);
break;
case EXIT_REASON_INVLPG:
- {
inst_len = __get_instruction_length(); /* Safe: INVLPG */
__update_guest_eip(inst_len);
exit_qualification = __vmread(EXIT_QUALIFICATION);
vmx_invlpg_intercept(exit_qualification);
break;
- }
- case EXIT_REASON_RDTSC:
- inst_len = __get_instruction_length();
- __update_guest_eip(inst_len);
- hvm_rdtsc_intercept(regs);
- break;
-#ifdef __x86_64__
case EXIT_REASON_RDTSCP:
- {
- struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
+ regs->ecx = v->arch.hvm_vcpu.msr_tsc_aux;
+ /* fall through */
+ case EXIT_REASON_RDTSC:
inst_len = __get_instruction_length();
__update_guest_eip(inst_len);
hvm_rdtsc_intercept(regs);
- regs->ecx = (uint32_t)(guest_state->msrs[VMX_INDEX_MSR_TSC_AUX]);
break;
- }
-#endif
case EXIT_REASON_VMCALL:
{
int rc;
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index 463f8f95b9..80c4d5b073 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -73,6 +73,8 @@ struct hvm_vcpu {
u64 asid_generation;
u32 asid;
+ u32 msr_tsc_aux;
+
union {
struct arch_vmx_struct vmx;
struct arch_svm_struct svm;
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 44b6e4cae4..ed77451afb 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -44,7 +44,6 @@ enum {
VMX_INDEX_MSR_LSTAR = 0,
VMX_INDEX_MSR_STAR,
VMX_INDEX_MSR_SYSCALL_MASK,
- VMX_INDEX_MSR_TSC_AUX,
VMX_MSR_COUNT
};
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index a65f080569..f84c0dddf8 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -84,7 +84,7 @@ static inline void wrmsrl(unsigned int msr, __u64 val)
#define write_tsc(val) wrmsrl(MSR_IA32_TSC, val)
-#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
#define rdpmc(counter,low,high) \
__asm__ __volatile__("rdpmc" \