aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-10-14 05:22:50 -0400
committerAvi Kivity <avi@redhat.com>2011-01-12 04:23:12 -0500
commit344d9588a9df06182684168be4f1408b55c7da3e (patch)
tree16890e3f0f10ac767265e650a1d6d38b78780040 /arch
parentca3f10172eea9b95bbb66487656f3c3e93855702 (diff)
KVM: Add PV MSR to enable asynchronous page faults delivery.
Guest enables async PF vcpu functionality using this MSR. Reviewed-by: Rik van Riel <riel@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/include/asm/kvm_para.h4
-rw-r--r--arch/x86/kvm/x86.c38
3 files changed, 42 insertions, 2 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c3076bcf5ef7..0d7039804b4c 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -419,6 +419,8 @@ struct kvm_vcpu_arch {
419 struct { 419 struct {
420 bool halted; 420 bool halted;
421 gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)]; 421 gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)];
422 struct gfn_to_hva_cache data;
423 u64 msr_val;
422 } apf; 424 } apf;
423}; 425};
424 426
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index e3faaaf4301e..8662ae0a035c 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -20,6 +20,7 @@
20 * are available. The use of 0x11 and 0x12 is deprecated 20 * are available. The use of 0x11 and 0x12 is deprecated
21 */ 21 */
22#define KVM_FEATURE_CLOCKSOURCE2 3 22#define KVM_FEATURE_CLOCKSOURCE2 3
23#define KVM_FEATURE_ASYNC_PF 4
23 24
24/* The last 8 bits are used to indicate how to interpret the flags field 25/* The last 8 bits are used to indicate how to interpret the flags field
25 * in pvclock structure. If no bits are set, all flags are ignored. 26 * in pvclock structure. If no bits are set, all flags are ignored.
@@ -32,9 +33,12 @@
32/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */ 33/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */
33#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00 34#define MSR_KVM_WALL_CLOCK_NEW 0x4b564d00
34#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 35#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
36#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
35 37
36#define KVM_MAX_MMU_OP_BATCH 32 38#define KVM_MAX_MMU_OP_BATCH 32
37 39
40#define KVM_ASYNC_PF_ENABLED (1 << 0)
41
38/* Operations for KVM_HC_MMU_OP */ 42/* Operations for KVM_HC_MMU_OP */
39#define KVM_MMU_OP_WRITE_PTE 1 43#define KVM_MMU_OP_WRITE_PTE 1
40#define KVM_MMU_OP_FLUSH_TLB 2 44#define KVM_MMU_OP_FLUSH_TLB 2
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bd254779d1cc..063c07296764 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -783,12 +783,12 @@ EXPORT_SYMBOL_GPL(kvm_get_dr);
783 * kvm-specific. Those are put in the beginning of the list. 783 * kvm-specific. Those are put in the beginning of the list.
784 */ 784 */
785 785
786#define KVM_SAVE_MSRS_BEGIN 7 786#define KVM_SAVE_MSRS_BEGIN 8
787static u32 msrs_to_save[] = { 787static u32 msrs_to_save[] = {
788 MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, 788 MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
789 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, 789 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
790 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, 790 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
791 HV_X64_MSR_APIC_ASSIST_PAGE, 791 HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN,
792 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, 792 MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
793 MSR_STAR, 793 MSR_STAR,
794#ifdef CONFIG_X86_64 794#ifdef CONFIG_X86_64
@@ -1425,6 +1425,29 @@ static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1425 return 0; 1425 return 0;
1426} 1426}
1427 1427
1428static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
1429{
1430 gpa_t gpa = data & ~0x3f;
1431
1432 /* Bits 1:5 are resrved, Should be zero */
1433 if (data & 0x3e)
1434 return 1;
1435
1436 vcpu->arch.apf.msr_val = data;
1437
1438 if (!(data & KVM_ASYNC_PF_ENABLED)) {
1439 kvm_clear_async_pf_completion_queue(vcpu);
1440 kvm_async_pf_hash_reset(vcpu);
1441 return 0;
1442 }
1443
1444 if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
1445 return 1;
1446
1447 kvm_async_pf_wakeup_all(vcpu);
1448 return 0;
1449}
1450
1428int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1451int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1429{ 1452{
1430 switch (msr) { 1453 switch (msr) {
@@ -1506,6 +1529,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1506 } 1529 }
1507 break; 1530 break;
1508 } 1531 }
1532 case MSR_KVM_ASYNC_PF_EN:
1533 if (kvm_pv_enable_async_pf(vcpu, data))
1534 return 1;
1535 break;
1509 case MSR_IA32_MCG_CTL: 1536 case MSR_IA32_MCG_CTL:
1510 case MSR_IA32_MCG_STATUS: 1537 case MSR_IA32_MCG_STATUS:
1511 case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: 1538 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)
1782 case MSR_KVM_SYSTEM_TIME_NEW: 1809 case MSR_KVM_SYSTEM_TIME_NEW:
1783 data = vcpu->arch.time; 1810 data = vcpu->arch.time;
1784 break; 1811 break;
1812 case MSR_KVM_ASYNC_PF_EN:
1813 data = vcpu->arch.apf.msr_val;
1814 break;
1785 case MSR_IA32_P5_MC_ADDR: 1815 case MSR_IA32_P5_MC_ADDR:
1786 case MSR_IA32_P5_MC_TYPE: 1816 case MSR_IA32_P5_MC_TYPE:
1787 case MSR_IA32_MCG_CAP: 1817 case MSR_IA32_MCG_CAP:
@@ -1929,6 +1959,7 @@ int kvm_dev_ioctl_check_extension(long ext)
1929 case KVM_CAP_DEBUGREGS: 1959 case KVM_CAP_DEBUGREGS:
1930 case KVM_CAP_X86_ROBUST_SINGLESTEP: 1960 case KVM_CAP_X86_ROBUST_SINGLESTEP:
1931 case KVM_CAP_XSAVE: 1961 case KVM_CAP_XSAVE:
1962 case KVM_CAP_ASYNC_PF:
1932 r = 1; 1963 r = 1;
1933 break; 1964 break;
1934 case KVM_CAP_COALESCED_MMIO: 1965 case KVM_CAP_COALESCED_MMIO:
@@ -5792,6 +5823,8 @@ free_vcpu:
5792 5823
5793void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) 5824void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
5794{ 5825{
5826 vcpu->arch.apf.msr_val = 0;
5827
5795 vcpu_load(vcpu); 5828 vcpu_load(vcpu);
5796 kvm_mmu_unload(vcpu); 5829 kvm_mmu_unload(vcpu);
5797 vcpu_put(vcpu); 5830 vcpu_put(vcpu);
@@ -5811,6 +5844,7 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
5811 vcpu->arch.dr7 = DR7_FIXED_1; 5844 vcpu->arch.dr7 = DR7_FIXED_1;
5812 5845
5813 kvm_make_request(KVM_REQ_EVENT, vcpu); 5846 kvm_make_request(KVM_REQ_EVENT, vcpu);
5847 vcpu->arch.apf.msr_val = 0;
5814 5848
5815 kvm_clear_async_pf_completion_queue(vcpu); 5849 kvm_clear_async_pf_completion_queue(vcpu);
5816 kvm_async_pf_hash_reset(vcpu); 5850 kvm_async_pf_hash_reset(vcpu);