* [PATCH 1/6] KVM: VMX: Remove redundant variable
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-18 8:48 ` [PATCH 2/6] x86: Add IA32_TSC_AUX MSR Sheng Yang
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
It's no longer necessary.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/kvm/vmx.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 9a0a2cf..5c464ed 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2383,14 +2383,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
for (i = 0; i < NR_VMX_MSR; ++i) {
u32 index = vmx_msr_index[i];
u32 data_low, data_high;
- u64 data;
int j = vmx->nmsrs;
if (rdmsr_safe(index, &data_low, &data_high) < 0)
continue;
if (wrmsr_safe(index, data_low, data_high) < 0)
continue;
- data = data_low | ((u64)data_high << 32);
vmx->guest_msrs[j].index = i;
vmx->guest_msrs[j].data = 0;
vmx->guest_msrs[j].mask = -1ull;
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 2/6] x86: Add IA32_TSC_AUX MSR
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
2009-12-18 8:48 ` [PATCH 1/6] KVM: VMX: Remove redundant variable Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-18 8:48 ` [PATCH 3/6] KVM: Extended shared_msr_global to per CPU Sheng Yang
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Also replaced the hardcode value in write_tsc() and write_tscp_aux().
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
(Already applied by Ingo)
arch/x86/include/asm/msr-index.h | 1 +
arch/x86/include/asm/msr.h | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 4ffe09b..ac98d29 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -12,6 +12,7 @@
#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */
#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */
#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */
/* EFER bits: */
#define _EFER_SCE 0 /* SYSCALL/SYSRET */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 7e2b6ba..e61fb87 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -240,9 +240,9 @@ do { \
#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \
(u32)((val) >> 32))
-#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2))
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
-#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
#ifdef CONFIG_SMP
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 3/6] KVM: Extended shared_msr_global to per CPU
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
2009-12-18 8:48 ` [PATCH 1/6] KVM: VMX: Remove redundant variable Sheng Yang
2009-12-18 8:48 ` [PATCH 2/6] x86: Add IA32_TSC_AUX MSR Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-18 8:48 ` [PATCH 4/6] x86: Raise vsyscall priority on hotplug notifier chain Sheng Yang
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
shared_msr_global saved host value of relevant MSRs, but it have an
assumption that all MSRs it tracked shared the value across the different
CPUs. It's not true with some MSRs, e.g. MSR_TSC_AUX.
Extend it to per CPU to provide the support of MSR_TSC_AUX, and more
alike MSRs.
Notice now the shared_msr_global still have one assumption: it can only deal
with the MSRs that won't change in host after KVM module loaded.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/kvm/x86.c | 55 +++++++++++++++++++++++++++++++--------------------
1 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index dd15d7a..9ce7917 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -92,16 +92,16 @@ module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
struct kvm_shared_msrs_global {
int nr;
- struct kvm_shared_msr {
- u32 msr;
- u64 value;
- } msrs[KVM_NR_SHARED_MSRS];
+ u32 msrs[KVM_NR_SHARED_MSRS];
};
struct kvm_shared_msrs {
struct user_return_notifier urn;
bool registered;
- u64 current_value[KVM_NR_SHARED_MSRS];
+ struct kvm_shared_msr_values {
+ u64 host;
+ u64 curr;
+ } values[KVM_NR_SHARED_MSRS];
};
static struct kvm_shared_msrs_global __read_mostly shared_msrs_global;
@@ -146,53 +146,64 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
static void kvm_on_user_return(struct user_return_notifier *urn)
{
unsigned slot;
- struct kvm_shared_msr *global;
struct kvm_shared_msrs *locals
= container_of(urn, struct kvm_shared_msrs, urn);
+ struct kvm_shared_msr_values *values;
for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
- global = &shared_msrs_global.msrs[slot];
- if (global->value != locals->current_value[slot]) {
- wrmsrl(global->msr, global->value);
- locals->current_value[slot] = global->value;
+ values = &locals->values[slot];
+ if (values->host != values->curr) {
+ wrmsrl(shared_msrs_global.msrs[slot], values->host);
+ values->curr = values->host;
}
}
locals->registered = false;
user_return_notifier_unregister(urn);
}
-void kvm_define_shared_msr(unsigned slot, u32 msr)
+static void shared_msr_update(unsigned slot, u32 msr)
{
- int cpu;
+ struct kvm_shared_msrs *smsr;
u64 value;
+ smsr = &__get_cpu_var(shared_msrs);
+ /* only read, and nobody should modify it at this time,
+ * so don't need lock */
+ if (slot >= shared_msrs_global.nr) {
+ printk(KERN_ERR "kvm: invalid MSR slot!");
+ return;
+ }
+ rdmsrl_safe(msr, &value);
+ smsr->values[slot].host = value;
+ smsr->values[slot].curr = value;
+}
+
+void kvm_define_shared_msr(unsigned slot, u32 msr)
+{
if (slot >= shared_msrs_global.nr)
shared_msrs_global.nr = slot + 1;
- shared_msrs_global.msrs[slot].msr = msr;
- rdmsrl_safe(msr, &value);
- shared_msrs_global.msrs[slot].value = value;
- for_each_online_cpu(cpu)
- per_cpu(shared_msrs, cpu).current_value[slot] = value;
+ shared_msrs_global.msrs[slot] = msr;
+ /* we need ensured the shared_msr_global have been updated */
+ smp_wmb();
}
EXPORT_SYMBOL_GPL(kvm_define_shared_msr);
static void kvm_shared_msr_cpu_online(void)
{
unsigned i;
- struct kvm_shared_msrs *locals = &__get_cpu_var(shared_msrs);
for (i = 0; i < shared_msrs_global.nr; ++i)
- locals->current_value[i] = shared_msrs_global.msrs[i].value;
+ shared_msr_update(i, shared_msrs_global.msrs[i]);
}
void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
{
struct kvm_shared_msrs *smsr = &__get_cpu_var(shared_msrs);
- if (((value ^ smsr->current_value[slot]) & mask) == 0)
+ if (((value ^ smsr->values[slot].curr) & mask) == 0)
return;
- smsr->current_value[slot] = value;
- wrmsrl(shared_msrs_global.msrs[slot].msr, value);
+ smsr->values[slot].curr = value;
+ wrmsrl(shared_msrs_global.msrs[slot], value);
if (!smsr->registered) {
smsr->urn.on_user_return = kvm_on_user_return;
user_return_notifier_register(&smsr->urn);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 4/6] x86: Raise vsyscall priority on hotplug notifier chain
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
` (2 preceding siblings ...)
2009-12-18 8:48 ` [PATCH 3/6] KVM: Extended shared_msr_global to per CPU Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-18 8:48 ` [PATCH 5/6] KVM: Add cpuid_update() callback to kvm_x86_ops Sheng Yang
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang, Ingo Molnar, linux-kernel
KVM need vsyscall_init() to initialize MSR_TSC_AUX before it read the value.
Per Avi's suggestion, this patch raised vsyscall priority on hotplug notifier
chain, to 30.
CC: Ingo Molnar <mingo@elte.hu>
CC: linux-kernel@vger.kernel.org
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/kernel/vsyscall_64.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 8cb4974..971bbc9 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -300,7 +300,8 @@ static int __init vsyscall_init(void)
register_sysctl_table(kernel_root_table2);
#endif
on_each_cpu(cpu_vsyscall_init, NULL, 1);
- hotcpu_notifier(cpu_vsyscall_notifier, 0);
+ /* notifier priority > KVM */
+ hotcpu_notifier(cpu_vsyscall_notifier, 30);
return 0;
}
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 5/6] KVM: Add cpuid_update() callback to kvm_x86_ops
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
` (3 preceding siblings ...)
2009-12-18 8:48 ` [PATCH 4/6] x86: Raise vsyscall priority on hotplug notifier chain Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-18 8:48 ` [PATCH 6/6] KVM: VMX: Add instruction rdtscp support for guest Sheng Yang
2009-12-20 9:30 ` [PATCH 0/6 v2] Add support for RDTSCP in VMX Avi Kivity
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Sometime, we need to adjust some state in order to reflect guest CPUID
setting, e.g. if we don't expose rdtscp to guest, we won't want to enable
it on hardware. cpuid_update() is introduced for this purpose.
Also export kvm_find_cpuid_entry() for later use.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm.c | 6 ++++++
arch/x86/kvm/vmx.c | 6 ++++++
arch/x86/kvm/x86.c | 3 +++
4 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4f865e8..d2a91ae 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -471,6 +471,7 @@ struct kvm_x86_ops {
int (*hardware_setup)(void); /* __init */
void (*hardware_unsetup)(void); /* __exit */
bool (*cpu_has_accelerated_tpr)(void);
+ void (*cpuid_update)(struct kvm_vcpu *vcpu);
/* Create, but do not attach this VCPU */
struct kvm_vcpu *(*vcpu_create)(struct kvm *kvm, unsigned id);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 3de0b37..d89b0a0 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2854,6 +2854,10 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
return 0;
}
+static void svm_cpuid_update(struct kvm_vcpu *vcpu)
+{
+}
+
static const struct trace_print_flags svm_exit_reasons_str[] = {
{ SVM_EXIT_READ_CR0, "read_cr0" },
{ SVM_EXIT_READ_CR3, "read_cr3" },
@@ -2978,6 +2982,8 @@ static struct kvm_x86_ops svm_x86_ops = {
.exit_reasons_str = svm_exit_reasons_str,
.gb_page_enable = svm_gb_page_enable,
+
+ .cpuid_update = svm_cpuid_update,
};
static int __init svm_init(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5c464ed..91dff23 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3961,6 +3961,10 @@ static bool vmx_gb_page_enable(void)
return false;
}
+static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
+{
+}
+
static struct kvm_x86_ops vmx_x86_ops = {
.cpu_has_kvm_support = cpu_has_kvm_support,
.disabled_by_bios = vmx_disabled_by_bios,
@@ -4025,6 +4029,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
.exit_reasons_str = vmx_exit_reasons_str,
.gb_page_enable = vmx_gb_page_enable,
+
+ .cpuid_update = vmx_cpuid_update,
};
static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9ce7917..e16dede 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1574,6 +1574,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
cpuid_fix_nx_cap(vcpu);
r = 0;
kvm_apic_set_version(vcpu);
+ kvm_x86_ops->cpuid_update(vcpu);
out_free:
vfree(cpuid_entries);
@@ -1596,6 +1597,7 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
goto out;
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu);
+ kvm_x86_ops->cpuid_update(vcpu);
return 0;
out:
@@ -3730,6 +3732,7 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
}
return best;
}
+EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
{
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 6/6] KVM: VMX: Add instruction rdtscp support for guest
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
` (4 preceding siblings ...)
2009-12-18 8:48 ` [PATCH 5/6] KVM: Add cpuid_update() callback to kvm_x86_ops Sheng Yang
@ 2009-12-18 8:48 ` Sheng Yang
2009-12-20 9:30 ` [PATCH 0/6 v2] Add support for RDTSCP in VMX Avi Kivity
6 siblings, 0 replies; 12+ messages in thread
From: Sheng Yang @ 2009-12-18 8:48 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Sheng Yang
Before enabling, execution of "rdtscp" in guest would result in #UD.
Signed-off-by: Sheng Yang <sheng@linux.intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/include/asm/vmx.h | 1 +
arch/x86/kvm/svm.c | 7 ++++
arch/x86/kvm/vmx.c | 60 +++++++++++++++++++++++++++++++++++++--
arch/x86/kvm/x86.c | 3 +-
5 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d2a91ae..07e6636 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -533,6 +533,7 @@ struct kvm_x86_ops {
int (*get_tdp_level)(void);
u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
bool (*gb_page_enable)(void);
+ bool (*rdtscp_supported)(void);
const struct trace_print_flags *exit_reasons_str;
};
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 2b49454..8c39320 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -53,6 +53,7 @@
*/
#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
+#define SECONDARY_EXEC_RDTSCP 0x00000008
#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d89b0a0..3a880ac 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2916,6 +2916,11 @@ static bool svm_gb_page_enable(void)
return true;
}
+static bool svm_rdtscp_supported(void)
+{
+ return false;
+}
+
static struct kvm_x86_ops svm_x86_ops = {
.cpu_has_kvm_support = has_svm,
.disabled_by_bios = is_disabled,
@@ -2984,6 +2989,8 @@ static struct kvm_x86_ops svm_x86_ops = {
.gb_page_enable = svm_gb_page_enable,
.cpuid_update = svm_cpuid_update,
+
+ .rdtscp_supported = svm_rdtscp_supported,
};
static int __init svm_init(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 91dff23..584403f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -136,6 +136,8 @@ struct vcpu_vmx {
ktime_t entry_time;
s64 vnmi_blocked_time;
u32 exit_reason;
+
+ bool rdtscp_enabled;
};
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -210,7 +212,7 @@ static const u32 vmx_msr_index[] = {
#ifdef CONFIG_X86_64
MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR,
#endif
- MSR_EFER, MSR_K6_STAR,
+ MSR_EFER, MSR_TSC_AUX, MSR_K6_STAR,
};
#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
@@ -347,6 +349,12 @@ static inline int cpu_has_vmx_vpid(void)
SECONDARY_EXEC_ENABLE_VPID;
}
+static inline int cpu_has_vmx_rdtscp(void)
+{
+ return vmcs_config.cpu_based_2nd_exec_ctrl &
+ SECONDARY_EXEC_RDTSCP;
+}
+
static inline int cpu_has_virtual_nmis(void)
{
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS;
@@ -878,6 +886,11 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
}
+static bool vmx_rdtscp_supported(void)
+{
+ return cpu_has_vmx_rdtscp();
+}
+
/*
* Swap MSR entry in host/guest MSR entry array.
*/
@@ -913,6 +926,9 @@ static void setup_msrs(struct vcpu_vmx *vmx)
index = __find_msr_index(vmx, MSR_CSTAR);
if (index >= 0)
move_msr_up(vmx, index, save_nmsrs++);
+ index = __find_msr_index(vmx, MSR_TSC_AUX);
+ if (index >= 0 && vmx->rdtscp_enabled)
+ move_msr_up(vmx, index, save_nmsrs++);
/*
* MSR_K6_STAR is only needed on long mode guests, and only
* if efer.sce is enabled.
@@ -1002,6 +1018,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
case MSR_IA32_SYSENTER_ESP:
data = vmcs_readl(GUEST_SYSENTER_ESP);
break;
+ case MSR_TSC_AUX:
+ if (!to_vmx(vcpu)->rdtscp_enabled)
+ return 1;
+ /* Otherwise falls through */
default:
vmx_load_host_state(to_vmx(vcpu));
msr = find_msr_entry(to_vmx(vcpu), msr_index);
@@ -1065,7 +1085,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
vcpu->arch.pat = data;
break;
}
- /* Otherwise falls through to kvm_set_msr_common */
+ ret = kvm_set_msr_common(vcpu, msr_index, data);
+ break;
+ case MSR_TSC_AUX:
+ if (!vmx->rdtscp_enabled)
+ return 1;
+ /* Check reserved bit, higher 32 bits should be zero */
+ if ((data >> 32) != 0)
+ return 1;
+ /* Otherwise falls through */
default:
msr = find_msr_entry(vmx, msr_index);
if (msr) {
@@ -1243,7 +1271,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
SECONDARY_EXEC_ENABLE_VPID |
SECONDARY_EXEC_ENABLE_EPT |
SECONDARY_EXEC_UNRESTRICTED_GUEST |
- SECONDARY_EXEC_PAUSE_LOOP_EXITING;
+ SECONDARY_EXEC_PAUSE_LOOP_EXITING |
+ SECONDARY_EXEC_RDTSCP;
if (adjust_vmx_controls(min2, opt2,
MSR_IA32_VMX_PROCBASED_CTLS2,
&_cpu_based_2nd_exec_control) < 0)
@@ -3961,8 +3990,31 @@ static bool vmx_gb_page_enable(void)
return false;
}
+static inline u32 bit(int bitno)
+{
+ return 1 << (bitno & 31);
+}
+
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
{
+ struct kvm_cpuid_entry2 *best;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 exec_control;
+
+ vmx->rdtscp_enabled = false;
+ if (vmx_rdtscp_supported()) {
+ exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL);
+ if (exec_control & SECONDARY_EXEC_RDTSCP) {
+ best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+ if (best && (best->edx & bit(X86_FEATURE_RDTSCP)))
+ vmx->rdtscp_enabled = true;
+ else {
+ exec_control &= ~SECONDARY_EXEC_RDTSCP;
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
+ exec_control);
+ }
+ }
+ }
}
static struct kvm_x86_ops vmx_x86_ops = {
@@ -4031,6 +4083,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
.gb_page_enable = vmx_gb_page_enable,
.cpuid_update = vmx_cpuid_update,
+
+ .rdtscp_supported = vmx_rdtscp_supported,
};
static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e16dede..91e4234 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1646,6 +1646,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
#else
unsigned f_lm = 0;
#endif
+ unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
/* cpuid 1.edx */
const u32 kvm_supported_word0_x86_features =
@@ -1665,7 +1666,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
F(PAT) | F(PSE36) | 0 /* Reserved */ |
f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
- F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ |
+ F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
/* cpuid 1.ecx */
const u32 kvm_supported_word4_x86_features =
--
1.5.4.5
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 0/6 v2] Add support for RDTSCP in VMX
2009-12-18 8:48 [PATCH 0/6 v2] Add support for RDTSCP in VMX Sheng Yang
` (5 preceding siblings ...)
2009-12-18 8:48 ` [PATCH 6/6] KVM: VMX: Add instruction rdtscp support for guest Sheng Yang
@ 2009-12-20 9:30 ` Avi Kivity
2009-12-22 17:26 ` Marcelo Tosatti
6 siblings, 1 reply; 12+ messages in thread
From: Avi Kivity @ 2009-12-20 9:30 UTC (permalink / raw)
To: Sheng Yang; +Cc: Marcelo Tosatti, kvm
On 12/18/2009 10:48 AM, Sheng Yang wrote:
Applied all, thanks.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 0/6 v2] Add support for RDTSCP in VMX
2009-12-20 9:30 ` [PATCH 0/6 v2] Add support for RDTSCP in VMX Avi Kivity
@ 2009-12-22 17:26 ` Marcelo Tosatti
2009-12-22 18:26 ` Avi Kivity
0 siblings, 1 reply; 12+ messages in thread
From: Marcelo Tosatti @ 2009-12-22 17:26 UTC (permalink / raw)
To: Avi Kivity; +Cc: Sheng Yang, kvm
On Sun, Dec 20, 2009 at 11:30:00AM +0200, Avi Kivity wrote:
> On 12/18/2009 10:48 AM, Sheng Yang wrote:
>
> Applied all, thanks.
Need to save/restore MSR_TSC_AUX in qemu-kvm.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/6 v2] Add support for RDTSCP in VMX
2009-12-22 17:26 ` Marcelo Tosatti
@ 2009-12-22 18:26 ` Avi Kivity
2009-12-23 13:37 ` Marcelo Tosatti
0 siblings, 1 reply; 12+ messages in thread
From: Avi Kivity @ 2009-12-22 18:26 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Sheng Yang, kvm
On 12/22/2009 07:26 PM, Marcelo Tosatti wrote:
> On Sun, Dec 20, 2009 at 11:30:00AM +0200, Avi Kivity wrote:
>
>> On 12/18/2009 10:48 AM, Sheng Yang wrote:
>>
>> Applied all, thanks.
>>
> Need to save/restore MSR_TSC_AUX in qemu-kvm.
>
Should be automatic. After all, we expose all the MSR list, so qemu can
read it and save everything there.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/6 v2] Add support for RDTSCP in VMX
2009-12-22 18:26 ` Avi Kivity
@ 2009-12-23 13:37 ` Marcelo Tosatti
2009-12-23 13:44 ` Avi Kivity
0 siblings, 1 reply; 12+ messages in thread
From: Marcelo Tosatti @ 2009-12-23 13:37 UTC (permalink / raw)
To: Avi Kivity, Glauber de Oliveira Costa; +Cc: Sheng Yang, kvm
On Tue, Dec 22, 2009 at 08:26:25PM +0200, Avi Kivity wrote:
> On 12/22/2009 07:26 PM, Marcelo Tosatti wrote:
>> On Sun, Dec 20, 2009 at 11:30:00AM +0200, Avi Kivity wrote:
>>
>>> On 12/18/2009 10:48 AM, Sheng Yang wrote:
>>>
>>> Applied all, thanks.
>>>
>> Need to save/restore MSR_TSC_AUX in qemu-kvm.
>>
>
> Should be automatic. After all, we expose all the MSR list, so qemu can
> read it and save everything there.
Hum, thinking a bit more about this (and reading Glauber's previous attempt) its not
entirely clear that using the list provided by KVM_GET_MSR_INDEX_LIST to automatically save/restore
is a good thing:
- The MSR must be saved in QEMU's CPUState representation, and its
likely that it won't exist prior to the addition there.
- What about savevm/loadvm versioning? Currently the QEMU migration
protocol is unable to deal with a new kernel that supports, for example,
MSR_TSC_AUX vs a kernel that does not (in case MSRs were automatically
saved), with the same qemu-kvm version.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/6 v2] Add support for RDTSCP in VMX
2009-12-23 13:37 ` Marcelo Tosatti
@ 2009-12-23 13:44 ` Avi Kivity
0 siblings, 0 replies; 12+ messages in thread
From: Avi Kivity @ 2009-12-23 13:44 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Glauber de Oliveira Costa, Sheng Yang, kvm
On 12/23/2009 03:37 PM, Marcelo Tosatti wrote:
>
>> Should be automatic. After all, we expose all the MSR list, so qemu can
>> read it and save everything there.
>>
> Hum, thinking a bit more about this (and reading Glauber's previous attempt) its not
> entirely clear that using the list provided by KVM_GET_MSR_INDEX_LIST to automatically save/restore
> is a good thing:
>
> - The MSR must be saved in QEMU's CPUState representation, and its
> likely that it won't exist prior to the addition there.
>
> - What about savevm/loadvm versioning? Currently the QEMU migration
> protocol is unable to deal with a new kernel that supports, for example,
> MSR_TSC_AUX vs a kernel that does not (in case MSRs were automatically
> saved), with the same qemu-kvm version.
>
You're right.
Well, qemu knows about cpuid.rdtscp, so we can add it to vmstate if it
is enabled. We should probably whitelist flags in qemu in the same way
we whitelist them in kvm.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 12+ messages in thread