File qemut-add-support-for-cpuid-MSR_IA32_SPEC_CTRL.patch of Package xen.openSUSE_Leap_42.3_Update
From: Wei Wang <wei.w.wang@intel.com>
Date: Tue, 7 Nov 2017 16:39:49 +0800
Subject: [PATCH] i386/kvm: MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD
CPUID(EAX=0X7,ECX=0).EDX[26]/[27] indicates the support of
MSR_IA32_SPEC_CTRL and MSR_IA32_PRED_CMD. Expose the CPUID
to the guest. Also add the support of transferring the MSRs during live
migration.
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
---
Index: xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/helper.c
===================================================================
--- xen-4.9.1-testing.orig/tools/qemu-xen-traditional-dir-remote/target-i386/helper.c
+++ xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/helper.c
@@ -1528,6 +1528,21 @@ void cpu_x86_cpuid(CPUX86State *env, uin
*ecx = 0;
*edx = 0;
break;
+ case 7:
+ /* Structured Extended Feature Flags Enumeration Leaf */
+ if (count == 0) {
+ host_cpuid(index, 0, eax, ebx, ecx, edx);
+ *eax = 0; /* Maximum ECX value for sub-leaves */
+ *ebx = 0; /* Feature flags */
+ *ecx = 0; /* Reserved */
+ *edx = env->cpuid_features | *edx;
+ } else {
+ *eax = 0;
+ *ebx = 0;
+ *ecx = 0;
+ *edx = 0;
+ }
+ break;
case 9:
/* Direct Cache Access Information Leaf */
*eax = 0; /* Bits 0-31 in DCA_CAP MSR */
Index: xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/cpu.h
===================================================================
--- xen-4.9.1-testing.orig/tools/qemu-xen-traditional-dir-remote/target-i386/cpu.h
+++ xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/cpu.h
@@ -250,6 +250,7 @@
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
+#define MSR_IA32_SPEC_CTRL 0x00000048
#define MSR_MTRRcap 0xfe
#define MSR_MTRRcap_VCNT 8
@@ -382,6 +383,9 @@
#define CPUID_EXT3_IBS (1 << 10)
#define CPUID_EXT3_SKINIT (1 << 12)
+#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26)
+#define CPUID_7_0_EDX_PRED_CMD (1U << 27)
+
#define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
#define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
#define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
@@ -670,6 +674,7 @@ typedef struct CPUX86State {
/* in order to simplify APIC support, we leave this pointer to the
user */
struct APICState *apic_state;
+ uint64_t spec_ctrl;
} CPUX86State;
CPUX86State *cpu_x86_init(const char *cpu_model);
Index: xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/kvm.c
===================================================================
--- xen-4.9.1-testing.orig/tools/qemu-xen-traditional-dir-remote/target-i386/kvm.c
+++ xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/kvm.c
@@ -129,48 +129,73 @@ int kvm_arch_init_vcpu(CPUState *env)
return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
}
-static int kvm_has_msr_star(CPUState *env)
+static int kvm_has_msr(CPUState *env, int msr)
{
- static int has_msr_star;
- int ret;
+ int ret, has_msr;
+ struct kvm_msr_list msr_list, *kvm_msr_list;
- /* first time */
- if (has_msr_star == 0) {
- struct kvm_msr_list msr_list, *kvm_msr_list;
+ has_msr = -1;
- has_msr_star = -1;
-
- /* Obtain MSR list from KVM. These are the MSRs that we must
- * save/restore */
- msr_list.nmsrs = 0;
- ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
- if (ret < 0)
- return 0;
+ /* Obtain MSR list from KVM. These are the MSRs that we must
+ * save/restore */
+ msr_list.nmsrs = 0;
+ ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
+ if (ret < 0)
+ return 0;
- kvm_msr_list = qemu_mallocz(sizeof(msr_list) +
- msr_list.nmsrs * sizeof(msr_list.indices[0]));
+ kvm_msr_list = qemu_mallocz(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
- kvm_msr_list->nmsrs = msr_list.nmsrs;
- ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
- if (ret >= 0) {
- int i;
-
- for (i = 0; i < kvm_msr_list->nmsrs; i++) {
- if (kvm_msr_list->indices[i] == MSR_STAR) {
- has_msr_star = 1;
- break;
- }
+ kvm_msr_list->nmsrs = msr_list.nmsrs;
+ ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
+ if (ret >= 0) {
+ int i;
+
+ for (i = 0; i < kvm_msr_list->nmsrs; i++) {
+ if (kvm_msr_list->indices[i] == msr) {
+ has_msr = 1;
+ break;
}
}
-
- free(kvm_msr_list);
}
+ free(kvm_msr_list);
+
+ if (has_msr == 1)
+ return 1;
+ return 0;
+}
+
+static int kvm_has_msr_star(CPUState *env)
+ static int has_msr_star;
+
+ /* first time */
+ if (has_msr_star == 0) {
+ has_msr_star = -1;
+
+ if (kvm_has_msr(env, MSR_STAR))
+ has_msr_star = 1;
+ }
if (has_msr_star == 1)
return 1;
return 0;
}
+static int kvm_has_msr_spec_ctrl(CPUState *env)
+ static int has_msr_spec_ctrl;
+
+ /* first time */
+ if (has_msr_spec_ctrl == 0) {
+ has_msr_spec_ctrl = -1;
+
+ if (kvm_has_msr(env, MSR_IA32_SPEC_CTRL))
+ has_msr_spec_ctrl = 1;
+ }
+ if (has_msr_spec_ctrl == 1)
+ return 1;
+ return 0;
+}
+
int kvm_arch_init(KVMState *s, int smp_cpus)
{
int ret;
@@ -379,8 +404,10 @@ static int kvm_put_msrs(CPUState *env)
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
- if (kvm_has_msr_star(env))
+ if (kvm_has_msr_star(env, MSR_STAR))
kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+ if (kvm_has_msr_spec_ctrl(env, MSR_IA32_SPEC_CTRL)
+ kvm_msr_entry_set(&msrs[n++], MSR_IA32_SPEC_CTRL, env->spec_ctrl);
kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
#ifdef TARGET_X86_64
/* FIXME if lm capable */
@@ -515,6 +542,8 @@ static int kvm_get_msrs(CPUState *env)
if (kvm_has_msr_star(env))
msrs[n++].index = MSR_STAR;
msrs[n++].index = MSR_IA32_TSC;
+ if (kvm_has_msr_spec_ctrl(env))
+ msrs[n++].index = MSR_IA32_SPEC_CTRL;
#ifdef TARGET_X86_64
/* FIXME lm_capable_kernel */
msrs[n++].index = MSR_CSTAR;
@@ -558,6 +587,9 @@ static int kvm_get_msrs(CPUState *env)
case MSR_IA32_TSC:
env->tsc = msrs[i].data;
break;
+ case MSR_IA32_SPEC_CTRL:
+ env->spec_ctrl = msrs[i].data;
+ break;
}
}
@@ -680,6 +712,9 @@ int kvm_arch_handle_exit(CPUState *env,
ret = kvm_handle_halt(env);
break;
}
+ if (has_msr_spec_ctrl) {
+ kvm_msr_entry_add(cpu, MSR_IA32_SPEC_CTRL, 0);
+ }
return ret;
}
Index: xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/machine.c
===================================================================
--- xen-4.9.1-testing.orig/tools/qemu-xen-traditional-dir-remote/target-i386/machine.c
+++ xen-4.9.1-testing/tools/qemu-xen-traditional-dir-remote/target-i386/machine.c
@@ -143,6 +143,7 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_be64s(f, &env->mtrr_var[i].base);
qemu_put_be64s(f, &env->mtrr_var[i].mask);
}
+ qemu_put_be64s(f, &env->spec_ctrl);
}
#ifdef USE_X86LDOUBLE
@@ -321,6 +322,7 @@ int cpu_load(QEMUFile *f, void *opaque,
qemu_get_be64s(f, &env->mtrr_var[i].base);
qemu_get_be64s(f, &env->mtrr_var[i].mask);
}
+ qemu_get_be64s(f, &env->spec_ctrl);
}
/* XXX: ensure compatiblity for halted bit ? */