|
@@ -783,12 +783,12 @@ EXPORT_SYMBOL_GPL(kvm_get_dr);
|
|
|
* kvm-specific. Those are put in the beginning of the list.
|
|
|
*/
|
|
|
|
|
|
-#define KVM_SAVE_MSRS_BEGIN 7
|
|
|
+#define KVM_SAVE_MSRS_BEGIN 8
|
|
|
static u32 msrs_to_save[] = {
|
|
|
MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
|
|
|
MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
|
|
|
HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
|
|
|
- HV_X64_MSR_APIC_ASSIST_PAGE,
|
|
|
+ HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN,
|
|
|
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
|
|
|
MSR_STAR,
|
|
|
#ifdef CONFIG_X86_64
|
|
@@ -1425,6 +1425,29 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
|
|
|
+{
|
|
|
+ gpa_t gpa = data & ~0x3f;
|
|
|
+
|
|
|
+ /* Bits 1:5 are resrved, Should be zero */
|
|
|
+ if (data & 0x3e)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ vcpu->arch.apf.msr_val = data;
|
|
|
+
|
|
|
+ if (!(data & KVM_ASYNC_PF_ENABLED)) {
|
|
|
+ kvm_clear_async_pf_completion_queue(vcpu);
|
|
|
+ kvm_async_pf_hash_reset(vcpu);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ kvm_async_pf_wakeup_all(vcpu);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
{
|
|
|
switch (msr) {
|
|
@@ -1506,6 +1529,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
+ case MSR_KVM_ASYNC_PF_EN:
|
|
|
+ if (kvm_pv_enable_async_pf(vcpu, data))
|
|
|
+ return 1;
|
|
|
+ break;
|
|
|
case MSR_IA32_MCG_CTL:
|
|
|
case MSR_IA32_MCG_STATUS:
|
|
|
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
|
|
@@ -1782,6 +1809,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
|
|
|
case MSR_KVM_SYSTEM_TIME_NEW:
|
|
|
data = vcpu->arch.time;
|
|
|
break;
|
|
|
+ case MSR_KVM_ASYNC_PF_EN:
|
|
|
+ data = vcpu->arch.apf.msr_val;
|
|
|
+ break;
|
|
|
case MSR_IA32_P5_MC_ADDR:
|
|
|
case MSR_IA32_P5_MC_TYPE:
|
|
|
case MSR_IA32_MCG_CAP:
|
|
@@ -1929,6 +1959,7 @@ int kvm_dev_ioctl_check_extension(long ext)
|
|
|
case KVM_CAP_DEBUGREGS:
|
|
|
case KVM_CAP_X86_ROBUST_SINGLESTEP:
|
|
|
case KVM_CAP_XSAVE:
|
|
|
+ case KVM_CAP_ASYNC_PF:
|
|
|
r = 1;
|
|
|
break;
|
|
|
case KVM_CAP_COALESCED_MMIO:
|
|
@@ -5792,6 +5823,8 @@ free_vcpu:
|
|
|
|
|
|
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
+ vcpu->arch.apf.msr_val = 0;
|
|
|
+
|
|
|
vcpu_load(vcpu);
|
|
|
kvm_mmu_unload(vcpu);
|
|
|
vcpu_put(vcpu);
|
|
@@ -5811,6 +5844,7 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
|
|
|
vcpu->arch.dr7 = DR7_FIXED_1;
|
|
|
|
|
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
|
|
+ vcpu->arch.apf.msr_val = 0;
|
|
|
|
|
|
kvm_clear_async_pf_completion_queue(vcpu);
|
|
|
kvm_async_pf_hash_reset(vcpu);
|