aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-10-14 05:22:55 -0400
committerAvi Kivity <avi@redhat.com>2011-01-12 04:23:21 -0500
commit6adba527420651b6cacaf392541c09fb108711a2 (patch)
tree1f81e4fc0bdf46b39ed62587a493f085633e8ac1
parent6c047cd982f944fa63b2d96de2a06463d113f9fa (diff)
KVM: Let host know whether the guest can handle async PF in non-userspace context.
If guest can detect that it runs in non-preemptable context it can handle async PFs at any time, so let host know that it can send async PF even if guest cpu is not in userspace. Acked-by: Rik van Riel <riel@redhat.com> Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--Documentation/kvm/msr.txt5
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/include/asm/kvm_para.h1
-rw-r--r--arch/x86/kernel/kvm.c3
-rw-r--r--arch/x86/kvm/x86.c5
5 files changed, 11 insertions, 4 deletions
diff --git a/Documentation/kvm/msr.txt b/Documentation/kvm/msr.txt
index e67b4a8783df..d079aed27e03 100644
--- a/Documentation/kvm/msr.txt
+++ b/Documentation/kvm/msr.txt
@@ -154,9 +154,10 @@ MSR_KVM_SYSTEM_TIME: 0x12
154MSR_KVM_ASYNC_PF_EN: 0x4b564d02 154MSR_KVM_ASYNC_PF_EN: 0x4b564d02
155 data: Bits 63-6 hold 64-byte aligned physical address of a 155 data: Bits 63-6 hold 64-byte aligned physical address of a
156 64 byte memory area which must be in guest RAM and must be 156 64 byte memory area which must be in guest RAM and must be
157 zeroed. Bits 5-1 are reserved and should be zero. Bit 0 is 1 157 zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1
158 when asynchronous page faults are enabled on the vcpu 0 when 158 when asynchronous page faults are enabled on the vcpu 0 when
159 disabled. 159 disabled. Bit 2 is 1 if asynchronous page faults can be injected
160 when vcpu is in cpl == 0.
160 161
161 First 4 byte of 64 byte memory location will be written to by 162 First 4 byte of 64 byte memory location will be written to by
162 the hypervisor at the time of asynchronous page fault (APF) 163 the hypervisor at the time of asynchronous page fault (APF)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 167375cc49ff..b2ea42870e47 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -422,6 +422,7 @@ struct kvm_vcpu_arch {
422 struct gfn_to_hva_cache data; 422 struct gfn_to_hva_cache data;
423 u64 msr_val; 423 u64 msr_val;
424 u32 id; 424 u32 id;
425 bool send_user_only;
425 } apf; 426 } apf;
426}; 427};
427 428
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index fbfd3679bc18..d3a1a4805ab8 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -38,6 +38,7 @@
38#define KVM_MAX_MMU_OP_BATCH 32 38#define KVM_MAX_MMU_OP_BATCH 32
39 39
40#define KVM_ASYNC_PF_ENABLED (1 << 0) 40#define KVM_ASYNC_PF_ENABLED (1 << 0)
41#define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
41 42
42/* Operations for KVM_HC_MMU_OP */ 43/* Operations for KVM_HC_MMU_OP */
43#define KVM_MMU_OP_WRITE_PTE 1 44#define KVM_MMU_OP_WRITE_PTE 1
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 47ea93e6b0d8..91b3d650898c 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -449,6 +449,9 @@ void __cpuinit kvm_guest_cpu_init(void)
449 if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) { 449 if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) {
450 u64 pa = __pa(&__get_cpu_var(apf_reason)); 450 u64 pa = __pa(&__get_cpu_var(apf_reason));
451 451
452#ifdef CONFIG_PREEMPT
453 pa |= KVM_ASYNC_PF_SEND_ALWAYS;
454#endif
452 wrmsrl(MSR_KVM_ASYNC_PF_EN, pa | KVM_ASYNC_PF_ENABLED); 455 wrmsrl(MSR_KVM_ASYNC_PF_EN, pa | KVM_ASYNC_PF_ENABLED);
453 __get_cpu_var(apf_reason).enabled = 1; 456 __get_cpu_var(apf_reason).enabled = 1;
454 printk(KERN_INFO"KVM setup async PF for cpu %d\n", 457 printk(KERN_INFO"KVM setup async PF for cpu %d\n",
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ac4c368afd40..fff70b50725c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1429,8 +1429,8 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
1429{ 1429{
1430 gpa_t gpa = data & ~0x3f; 1430 gpa_t gpa = data & ~0x3f;
1431 1431
1432 /* Bits 1:5 are resrved, Should be zero */ 1432 /* Bits 2:5 are resrved, Should be zero */
1433 if (data & 0x3e) 1433 if (data & 0x3c)
1434 return 1; 1434 return 1;
1435 1435
1436 vcpu->arch.apf.msr_val = data; 1436 vcpu->arch.apf.msr_val = data;
@@ -1444,6 +1444,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
1444 if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) 1444 if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa))
1445 return 1; 1445 return 1;
1446 1446
1447 vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS);
1447 kvm_async_pf_wakeup_all(vcpu); 1448 kvm_async_pf_wakeup_all(vcpu);
1448 return 0; 1449 return 0;
1449} 1450}