]>
Commit | Line | Data |
---|---|---|
68718636 GKH |
1 | From fe2a3027e74e40a3ece3a4c1e4e51403090a907a Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com> | |
3 | Date: Thu, 1 Feb 2018 22:16:21 +0100 | |
4 | Subject: KVM: x86: fix backward migration with async_PF | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Radim Krčmář <rkrcmar@redhat.com> | |
10 | ||
11 | commit fe2a3027e74e40a3ece3a4c1e4e51403090a907a upstream. | |
12 | ||
13 | Guests on new hypersiors might set KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT | |
14 | bit when enabling async_PF, but this bit is reserved on old hypervisors, | |
15 | which results in a failure upon migration. | |
16 | ||
17 | To avoid breaking different cases, we are checking for CPUID feature bit | |
18 | before enabling the feature and nothing else. | |
19 | ||
20 | Fixes: 52a5c155cf79 ("KVM: async_pf: Let guest support delivery of async_pf from guest mode") | |
21 | Cc: <stable@vger.kernel.org> | |
22 | Reviewed-by: Wanpeng Li <wanpengli@tencent.com> | |
23 | Reviewed-by: David Hildenbrand <david@redhat.com> | |
24 | Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> | |
25 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
26 | [jwang: port to 4.14] | |
27 | Signed-off-by: Jack Wang <jinpu.wang@profitbricks.com> | |
28 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
29 | --- | |
30 | Documentation/virtual/kvm/cpuid.txt | 4 ++++ | |
31 | Documentation/virtual/kvm/msr.txt | 3 ++- | |
32 | arch/x86/include/uapi/asm/kvm_para.h | 1 + | |
33 | arch/x86/kernel/kvm.c | 8 ++++---- | |
34 | arch/x86/kvm/cpuid.c | 3 ++- | |
35 | 5 files changed, 13 insertions(+), 6 deletions(-) | |
36 | ||
37 | --- a/Documentation/virtual/kvm/cpuid.txt | |
38 | +++ b/Documentation/virtual/kvm/cpuid.txt | |
39 | @@ -54,6 +54,10 @@ KVM_FEATURE_PV_UNHALT || | |
40 | || || before enabling paravirtualized | |
41 | || || spinlock support. | |
42 | ------------------------------------------------------------------------------ | |
43 | +KVM_FEATURE_ASYNC_PF_VMEXIT || 10 || paravirtualized async PF VM exit | |
44 | + || || can be enabled by setting bit 2 | |
45 | + || || when writing to msr 0x4b564d02 | |
46 | +------------------------------------------------------------------------------ | |
47 | KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side | |
48 | || || per-cpu warps are expected in | |
49 | || || kvmclock. | |
50 | --- a/Documentation/virtual/kvm/msr.txt | |
51 | +++ b/Documentation/virtual/kvm/msr.txt | |
52 | @@ -170,7 +170,8 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02 | |
53 | when asynchronous page faults are enabled on the vcpu 0 when | |
54 | disabled. Bit 1 is 1 if asynchronous page faults can be injected | |
55 | when vcpu is in cpl == 0. Bit 2 is 1 if asynchronous page faults | |
56 | - are delivered to L1 as #PF vmexits. | |
57 | + are delivered to L1 as #PF vmexits. Bit 2 can be set only if | |
58 | + KVM_FEATURE_ASYNC_PF_VMEXIT is present in CPUID. | |
59 | ||
60 | First 4 byte of 64 byte memory location will be written to by | |
61 | the hypervisor at the time of asynchronous page fault (APF) | |
62 | --- a/arch/x86/include/uapi/asm/kvm_para.h | |
63 | +++ b/arch/x86/include/uapi/asm/kvm_para.h | |
64 | @@ -25,6 +25,7 @@ | |
65 | #define KVM_FEATURE_STEAL_TIME 5 | |
66 | #define KVM_FEATURE_PV_EOI 6 | |
67 | #define KVM_FEATURE_PV_UNHALT 7 | |
68 | +#define KVM_FEATURE_ASYNC_PF_VMEXIT 10 | |
69 | ||
70 | /* The last 8 bits are used to indicate how to interpret the flags field | |
71 | * in pvclock structure. If no bits are set, all flags are ignored. | |
72 | --- a/arch/x86/kernel/kvm.c | |
73 | +++ b/arch/x86/kernel/kvm.c | |
74 | @@ -341,10 +341,10 @@ static void kvm_guest_cpu_init(void) | |
75 | #endif | |
76 | pa |= KVM_ASYNC_PF_ENABLED; | |
77 | ||
78 | - /* Async page fault support for L1 hypervisor is optional */ | |
79 | - if (wrmsr_safe(MSR_KVM_ASYNC_PF_EN, | |
80 | - (pa | KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT) & 0xffffffff, pa >> 32) < 0) | |
81 | - wrmsrl(MSR_KVM_ASYNC_PF_EN, pa); | |
82 | + if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_VMEXIT)) | |
83 | + pa |= KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT; | |
84 | + | |
85 | + wrmsrl(MSR_KVM_ASYNC_PF_EN, pa); | |
86 | __this_cpu_write(apf_reason.enabled, 1); | |
87 | printk(KERN_INFO"KVM setup async PF for cpu %d\n", | |
88 | smp_processor_id()); | |
89 | --- a/arch/x86/kvm/cpuid.c | |
90 | +++ b/arch/x86/kvm/cpuid.c | |
91 | @@ -597,7 +597,8 @@ static inline int __do_cpuid_ent(struct | |
92 | (1 << KVM_FEATURE_ASYNC_PF) | | |
93 | (1 << KVM_FEATURE_PV_EOI) | | |
94 | (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) | | |
95 | - (1 << KVM_FEATURE_PV_UNHALT); | |
96 | + (1 << KVM_FEATURE_PV_UNHALT) | | |
97 | + (1 << KVM_FEATURE_ASYNC_PF_VMEXIT); | |
98 | ||
99 | if (sched_info_on()) | |
100 | entry->eax |= (1 << KVM_FEATURE_STEAL_TIME); |