Add support for async page fault to qemu
PATCH 1/1 Add support for async page fault to qemu
Add save/restore of MSR for migration and cpuid bit.
qemu-kvm-x86.c +5 -0
@@ -678,6 +678,9 @@ static int get_msr_entry(struct kvm_msr_entry *entry, CPUState *env) env->mcg_ctl = entry->data;break ;#endif +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = entry->data; +break ;default :#ifdef KVM_CAP_MCE if (entry->index >= MSR_MC0_CTL &&
@@ -967,6 +970,7 @@ void kvm_arch_load_regs(CPUState *env, int level) }kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); }#ifdef KVM_CAP_MCE if (env->mcg_cap) {
@@ -1186,6 +1190,7 @@ void kvm_arch_save_regs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ;#ifdef KVM_CAP_MCE if (env->mcg_cap) {
target-i386/cpu.h +2 -1
@@ -669,6 +669,7 @@ typedef struct CPUX86State {#endif uint64_t system_time_msr;uint64_t wall_clock_msr; +uint64_t async_pf_en_msr;uint64_t tsc;
@@ -923,7 +924,7 @@ CPUState *pc_new_cpu(const char *cpu_model);#define cpu_list_id x86_cpu_list#define cpudef_setup x86_cpudef_setup -#define CPU_SAVE_VERSION 12 +#define CPU_SAVE_VERSION 13/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/cpuid.c +1 -1
@@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = { };static const char *kvm_feature_name[] = { -"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,NULL ,NULL ,NULL ,NULL , +"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,"kvm_asyncpf" ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,
target-i386/kvm.c +8 -0
@@ -151,6 +151,9 @@ struct kvm_para_features { #ifdef KVM_CAP_PV_MMU { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, #endif +#ifdef KVM_CAP_ASYNC_PF + { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, +#endif { -1, -1 } };
@@ -672,6 +675,7 @@ static int kvm_put_msrs(CPUState *env, int level)kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); } msr_data.info.nmsrs = n;
@@ -880,6 +884,7 @@ static int kvm_get_msrs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ; msr_data.info.nmsrs = n; ret =kvm_vcpu_ioctl (env,KVM_GET_MSRS , &msr_data);
@@ -926,6 +931,9 @@ static int kvm_get_msrs(CPUState *env)case MSR_VM_HSAVE_PA : env->vm_hsave = msrs[i].data;break ; +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = msrs[i].data; +break ; } }
target-i386/machine.c +3 -0
@@ -474,6 +474,9 @@ static const VMStateDescription vmstate_cpu = {VMSTATE_UINT64_V (xcr0, CPUState,12 ),VMSTATE_UINT64_V (xstate_bv, CPUState,12 ),VMSTATE_YMMH_REGS_VARS (ymmh_regs, CPUState,CPU_NB_REGS ,12 ), + +/* KVM async pf msr */ +VMSTATE_UINT64_V (async_pf_en_msr, CPUState,13 ),VMSTATE_END_OF_LIST () /* The above list is not sorted /wrt version numbers, watch out! */ }
--
Gleb.
Quoted 1 line · Gleb Natapov
Add save/restore of MSR for migration and cpuid bit.
It is there a way to test if async page faults are in use? if so, we can add a subsection instead of changing the cpuversion.
I think that at some point we are going to need a bitmap that indicates what MSR's have been used or something like that.
What do you think?
Later, Juan.
Quoted 4 lines · Juan Quintela
Quoted 1 line · Gleb Natapov
Add save/restore of MSR for migration and cpuid bit.
It is there a way to test if async page faults are in use?
Yes, msr != 0 -> need a subsection. Good idea.
Quoted 6 lines
if so, we can add a subsection instead of changing the cpuversion.
I think that at some point we are going to need a bitmap that indicates what MSR's have been used or something like that.
What do you think?
We just need to check if an msr is different from its default value (which we can get by reading msrs immediately after the initial reset).
Currently the reset code assumes msr reset value is zero, that's wrong.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 6 lines · Juan Quintela
Quoted 1 line · Gleb Natapov
Add save/restore of MSR for migration and cpuid bit.
It is there a way to test if async page faults are in use? if so, we can add a subsection instead of changing the cpuversion.
Yeah. Good idea. Forgot about our cool new subsection feature.
--
Gleb.
PATCH v2 1/1 Add support for async page fault to qemu
In reply to Gleb NatapovAdd save/restore of MSR for migration and cpuid bit.
---
v1->v2
- use vmstate subsection to migrate new msr.
qemu-kvm-x86.c +5 -0
@@ -678,6 +678,9 @@ static int get_msr_entry(struct kvm_msr_entry *entry, CPUState *env) env->mcg_ctl = entry->data;break ;#endif +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = entry->data; +break ;default :#ifdef KVM_CAP_MCE if (entry->index >= MSR_MC0_CTL &&
@@ -967,6 +970,7 @@ void kvm_arch_load_regs(CPUState *env, int level) }kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); }#ifdef KVM_CAP_MCE if (env->mcg_cap) {
@@ -1186,6 +1190,7 @@ void kvm_arch_save_regs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ;#ifdef KVM_CAP_MCE if (env->mcg_cap) {
target-i386/cpu.h +1 -0
@@ -669,6 +669,7 @@ typedef struct CPUX86State {#endif uint64_t system_time_msr;uint64_t wall_clock_msr; +uint64_t async_pf_en_msr;uint64_t tsc;
target-i386/cpuid.c +1 -1
@@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = { };static const char *kvm_feature_name[] = { -"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,NULL ,NULL ,NULL ,NULL , +"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,"kvm_asyncpf" ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,
target-i386/kvm.c +8 -0
@@ -151,6 +151,9 @@ struct kvm_para_features { #ifdef KVM_CAP_PV_MMU { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, #endif +#ifdef KVM_CAP_ASYNC_PF + { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, +#endif { -1, -1 } };
@@ -672,6 +675,7 @@ static int kvm_put_msrs(CPUState *env, int level)kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); } msr_data.info.nmsrs = n;
@@ -880,6 +884,7 @@ static int kvm_get_msrs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ; msr_data.info.nmsrs = n; ret =kvm_vcpu_ioctl (env,KVM_GET_MSRS , &msr_data);
@@ -926,6 +931,9 @@ static int kvm_get_msrs(CPUState *env)case MSR_VM_HSAVE_PA : env->vm_hsave = msrs[i].data;break ; +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = msrs[i].data; +break ; } }
target-i386/machine.c +26 -0
@@ -373,6 +373,24 @@ static int cpu_post_load(void *opaque, int version_id)return 0 ; } +static bool async_pf_msr_needed (void *opaque) +{ +CPUState *cpu = opaque; + +return cpu->async_pf_en_msr !=0 ; +} + +static const VMStateDescription vmstate_async_pf_msr = { + .name ="cpu/async_pf_msr" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINT64 (async_pf_en_msr, CPUState), +VMSTATE_END_OF_LIST () + } +}; +static const VMStateDescription vmstate_cpu = { .name ="cpu" , .version_id =CPU_SAVE_VERSION ,
@@ -476,6 +494,14 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_YMMH_REGS_VARS(ymmh_regs, CPUState, CPU_NB_REGS, 12),VMSTATE_END_OF_LIST ()/* The above list is not sorted /wrt version numbers, watch out! */ + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_async_pf_msr, + .needed = async_pf_msr_needed, + } , { +/* empty */ + } } };
--
Gleb.
Quoted 93 lines · Gleb Natapov
Add save/restore of MSR for migration and cpuid bit.
Signed-off-by Gleb Natapov <[email protected]>---
v1->v2
- use vmstate subsection to migrate new msr.qemu-kvm-x86.c +5
-0@@ -678,6 +678,9 @@ static int get_msr_entry(struct kvm_msr_entry *entry, CPUState *env) env->mcg_ctl = entry->data;break ;#endif +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = entry->data; +break ;default :#ifdef KVM_CAP_MCE if (entry->index >= MSR_MC0_CTL &&@@ -967,6 +970,7 @@ void kvm_arch_load_regs(CPUState *env, int level) }kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); }#ifdef KVM_CAP_MCE if (env->mcg_cap) {@@ -1186,6 +1190,7 @@ void kvm_arch_save_regs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ;#ifdef KVM_CAP_MCE if (env->mcg_cap) {target-i386/cpu.h +1
-0@@ -669,6 +669,7 @@ typedef struct CPUX86State {#endif uint64_t system_time_msr;uint64_t wall_clock_msr; +uint64_t async_pf_en_msr;uint64_t tsc;target-i386/cpuid.c +1
-1@@ -73,7 +73,7 @@ static const char *ext3_feature_name[] = { };static const char *kvm_feature_name[] = { -"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,NULL ,NULL ,NULL ,NULL , +"kvmclock" ,"kvm_nopiodelay" ,"kvm_mmu" ,NULL ,"kvm_asyncpf" ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,NULL ,target-i386/kvm.c +5
-0@@ -151,6 +151,9 @@ struct kvm_para_features { #ifdef KVM_CAP_PV_MMU { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, #endif +#ifdef KVM_CAP_ASYNC_PF + { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, +#endif { -1, -1 } };@@ -672,6 +675,7 @@ static int kvm_put_msrs(CPUState *env, int level)kvm_msr_entry_set (&msrs[n++],MSR_KVM_SYSTEM_TIME , env->system_time_msr);kvm_msr_entry_set (&msrs[n++],MSR_KVM_WALL_CLOCK , env->wall_clock_msr); +kvm_msr_entry_set (&msrs[n++],MSR_KVM_ASYNC_PF_EN , env->async_pf_en_msr); } msr_data.info.nmsrs = n;@@ -880,6 +884,7 @@ static int kvm_get_msrs(CPUState *env)#endif msrs[n++].index =MSR_KVM_SYSTEM_TIME ; msrs[n++].index =MSR_KVM_WALL_CLOCK ; + msrs[n++].index =MSR_KVM_ASYNC_PF_EN ; msr_data.info.nmsrs = n; ret =kvm_vcpu_ioctl (env,KVM_GET_MSRS , &msr_data);
target-i386/kvm.c static int kvm_get_msrs(CPUState *env) · line 937
Quoted 7 lines
target-i386/kvm.c +3
-0@@ -926,6 +931,9 @@ static int kvm_get_msrs(CPUState *env)case MSR_VM_HSAVE_PA : env->vm_hsave = msrs[i].data;break ; +case MSR_KVM_ASYNC_PF_EN : + env->async_pf_en_msr = msrs[i].data; +break ; }
I think this is going to break the build if MSR_KVM_ASYNC_PF_EN is not defined.
Please regenerate against uq/master.