migrate PV EOI MSR
cover migrate PV EOI MSR
It turns out PV EOI gets disabled after migration - until next guest reset.
This is because we are missing code to actually migrate it. This patch fixes it up: it does not do anything useful without kvm irqchip but applies cleanly to qemu.git as well as qemu-kvm.git, so I think it's cleaner to apply it in qemu.git to keep diff to minimum.
Needed for 1.2.
Michael S. Tsirkin (2):
linux-headers: update asm/kvm_para.h to 3.6
kvm: get/set PV EOI MSR
linux-headers/asm-x86/kvm_para.h | 7 +++++++ target-i386/cpu.h | 1 + target-i386/kvm.c | 13 +++++++++++++ target-i386/machine.c | 21 +++++++++++++++++++++ 4 files changed, 42 insertions(+)
Signature · 1 line
MST
PATCH 1/2 linux-headers: update asm/kvm_para.h to 3.6
Update asm-x96/kvm_para.h to version present in Linux 3.6. This is needed for the new PV EOI feature.
--- linux-headers/asm-x86/kvm_para.h | 7 +++++++ 1 file changed, 7 insertions(+)
linux-headers/asm-x86/kvm_para.h +7 -0
@@ -22,6 +22,7 @@#define KVM_FEATURE_CLOCKSOURCE2 3#define KVM_FEATURE_ASYNC_PF 4#define KVM_FEATURE_STEAL_TIME 5 +#define KVM_FEATURE_PV_EOI 6/* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored.
@@ -37,6 +38,7 @@#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01#define MSR_KVM_ASYNC_PF_EN 0x4b564d02#define MSR_KVM_STEAL_TIME 0x4b564d03 +#define MSR_KVM_PV_EOI_EN 0x4b564d04struct kvm_steal_time {__u64 steal;
@@ -89,5 +91,10 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_EOI_BIT 0 +#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT) +#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK +#define KVM_PV_EOI_DISABLED 0x0 +#endif /* _ASM_X86_KVM_PARA_H */
Signature · 1 line
MST
Re: [PATCH for-1.2 1/2] linux-headers: update asm/kvm_para.h to 3.6
Quoted 1 line · Michael S. Tsirkin
Update
asm-x96/kvm_para.hto version present in Linux 3.6.
Nope, we have update-linux-headers.sh for this. Just run it again 3.6-rcX, grab the result, and mention the source (release version or kvm.git hash).
Jan
Quoted 39 lines
This is needed for the new PV EOI feature.
Signed-off-by Michael S. Tsirkin <[email protected]>--- linux-headers/asm-x86/kvm_para.h | 7 +++++++ 1 file changed, 7 insertions(+)linux-headers/asm-x86/kvm_para.h +7
-0@@ -22,6 +22,7 @@#define KVM_FEATURE_CLOCKSOURCE2 3#define KVM_FEATURE_ASYNC_PF 4#define KVM_FEATURE_STEAL_TIME 5 +#define KVM_FEATURE_PV_EOI 6/* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. @@ -37,6 +38,7 @@#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01#define MSR_KVM_ASYNC_PF_EN 0x4b564d02#define MSR_KVM_STEAL_TIME 0x4b564d03 +#define MSR_KVM_PV_EOI_EN 0x4b564d04struct kvm_steal_time {__u64 steal;@@ -89,5 +91,10 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_EOI_BIT 0 +#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT) +#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK +#define KVM_PV_EOI_DISABLED 0x0 +#endif /* _ASM_X86_KVM_PARA_H */
PATCH 2/2 kvm: get/set PV EOI MSR
In reply to Michael S. TsirkinSupport get/set of new PV EOI MSR, for migration. Add an optional section for MSR value - send it out in case MSR was changed from the default value (0).
--- target-i386/cpu.h | 1 + target-i386/kvm.c | 13 +++++++++++++ target-i386/machine.c | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+)
target-i386/cpu.h +1 -0
@@ -699,6 +699,7 @@ typedef struct CPUX86State {uint64_t system_time_msr;uint64_t wall_clock_msr;uint64_t async_pf_en_msr; +uint64_t pv_eoi_en_msr;uint64_t tsc;uint64_t tsc_deadline;
target-i386/kvm.c +13 -0
@@ -64,6 +64,7 @@ static bool has_msr_star;static bool has_msr_hsave_pa;static bool has_msr_tsc_deadline;static bool has_msr_async_pf_en; +static bool has_msr_pv_eoi_en;static bool has_msr_misc_enable;static int lm_capable_kernel;
@@ -456,6 +457,8 @@ int kvm_arch_init_vcpu(CPUX86State *env) has_msr_async_pf_en = c->eax & (1 <<KVM_FEATURE_ASYNC_PF ); + has_msr_pv_eoi_en = c->eax & (1 <<KVM_FEATURE_PV_EOI ); +cpu_x86_cpuid (env,0 ,0 , &limit, &unused, &unused, &unused);for (i =0 ; i <= limit; i++) {
@@ -1018,6 +1021,10 @@ static int kvm_put_msrs(CPUX86State *env, int level)kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); } +if (has_msr_pv_eoi_en) { +kvm_msr_entry_set (&msrs[n++],MSR_KVM_PV_EOI_EN , + env->pv_eoi_en_msr); + }if (hyperv_hypercall_available ()) {kvm_msr_entry_set (&msrs[n++],HV_X64_MSR_GUEST_OS_ID ,0 );kvm_msr_entry_set (&msrs[n++],HV_X64_MSR_HYPERCALL ,0 );
@@ -1260,6 +1267,9 @@ static int kvm_get_msrs(CPUX86State *env)if (has_msr_async_pf_en) { msrs[n++].index =MSR_KVM_ASYNC_PF_EN ; } +if (has_msr_pv_eoi_en) { + msrs[n++].index =MSR_KVM_PV_EOI_EN ; + }if (env->mcg_cap) { msrs[n++].index =MSR_MCG_STATUS ;
@@ -1339,6 +1349,9 @@ static int kvm_get_msrs(CPUX86State *env)case MSR_KVM_ASYNC_PF_EN : env->async_pf_en_msr = msrs[i].data;break ; +case MSR_KVM_PV_EOI_EN : + env->pv_eoi_en_msr = msrs[i].data; +break ; } }
target-i386/machine.c +21 -0
@@ -279,6 +279,13 @@ static bool async_pf_msr_needed(void *opaque)return cpu->async_pf_en_msr !=0 ; } +static bool pv_eoi_msr_needed (void *opaque) +{ +CPUX86State *cpu = opaque; + +return cpu->pv_eoi_en_msr !=0 ; +} +static const VMStateDescription vmstate_async_pf_msr = { .name ="cpu/async_pf_msr" , .version_id =1 ,
@@ -290,6 +297,17 @@ static const VMStateDescription vmstate_async_pf_msr = { } }; +static const VMStateDescription vmstate_pv_eoi_msr = { + .name ="cpu/async_pv_eoi_msr" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT64 (pv_eoi_en_msr, CPUX86State), +VMSTATE_END_OF_LIST () + } +}; +static bool fpop_ip_dp_needed (void *opaque) {CPUX86State *env = opaque;
@@ -454,6 +472,9 @@ static const VMStateDescription vmstate_cpu = { .vmsd = &vmstate_async_pf_msr, .needed = async_pf_msr_needed, } , { + .vmsd = &vmstate_pv_eoi_msr, + .needed = pv_eoi_msr_needed, + } , { .vmsd = &vmstate_fpop_ip_dp, .needed = fpop_ip_dp_needed, }, {
Signature · 1 line
MST
Quoted 7 lines · Michael S. Tsirkin
It turns out PV EOI gets disabled after migration - until next guest reset.
This is because we are missing code to actually migrate it. This patch fixes it up: it does not do anything useful without kvm irqchip but applies cleanly to qemu.git as well as qemu-kvm.git, so I think it's cleaner to apply it in qemu.git to keep diff to minimum.
There is nothing except pci-assign left in qemu-kvm (which will be posted for upstream in a minute), so you are intuitively doing the right thing.
Patch 2 looks good to me, see patch 1 for the clean procedure.
Jan