]>
Commit | Line | Data |
---|---|---|
1e614501 GKH |
1 | From foo@baz Tue Apr 17 14:06:43 CEST 2018 |
2 | From: Mark Rutland <mark.rutland@arm.com> | |
3 | Date: Thu, 12 Apr 2018 12:11:30 +0100 | |
9141df69 | 4 | Subject: arm/arm64: KVM: Turn kvm_psci_version into a static inline |
1e614501 GKH |
5 | To: stable@vger.kernel.org |
6 | Cc: mark.brown@linaro.org, ard.biesheuvel@linaro.org, marc.zyngier@arm.com, will.deacon@arm.com, catalin.marinas@arm.com, ghackmann@google.com, shankerd@codeaurora.org | |
7 | Message-ID: <20180412111138.40990-35-mark.rutland@arm.com> | |
8 | ||
9 | From: Mark Rutland <mark.rutland@arm.com> | |
10 | ||
11 | ||
12 | From: Marc Zyngier <marc.zyngier@arm.com> | |
13 | ||
14 | commit a4097b351118e821841941a79ec77d3ce3f1c5d9 upstream. | |
15 | ||
16 | We're about to need kvm_psci_version in HYP too. So let's turn it | |
17 | into a static inline, and pass the kvm structure as a second | |
18 | parameter (so that HYP can do a kern_hyp_va on it). | |
19 | ||
20 | Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> | |
21 | Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> | |
22 | Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> | |
23 | Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> | |
24 | [v4.9: account for files moved to virt/ upstream] | |
25 | Signed-off-by: Mark Rutland <mark.rutland@arm.com> [v4.9 backport] | |
26 | Tested-by: Greg Hackmann <ghackmann@google.com> | |
27 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
28 | --- | |
29 | arch/arm/kvm/psci.c | 12 ++---------- | |
30 | arch/arm64/kvm/hyp/switch.c | 18 +++++++++++------- | |
31 | include/kvm/arm_psci.h | 21 ++++++++++++++++++++- | |
32 | 3 files changed, 33 insertions(+), 18 deletions(-) | |
33 | ||
34 | --- a/arch/arm/kvm/psci.c | |
35 | +++ b/arch/arm/kvm/psci.c | |
36 | @@ -120,7 +120,7 @@ static unsigned long kvm_psci_vcpu_on(st | |
37 | if (!vcpu) | |
38 | return PSCI_RET_INVALID_PARAMS; | |
39 | if (!vcpu->arch.power_off) { | |
40 | - if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1) | |
41 | + if (kvm_psci_version(source_vcpu, kvm) != KVM_ARM_PSCI_0_1) | |
42 | return PSCI_RET_ALREADY_ON; | |
43 | else | |
44 | return PSCI_RET_INVALID_PARAMS; | |
45 | @@ -230,14 +230,6 @@ static void kvm_psci_system_reset(struct | |
46 | kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET); | |
47 | } | |
48 | ||
49 | -int kvm_psci_version(struct kvm_vcpu *vcpu) | |
50 | -{ | |
51 | - if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) | |
52 | - return KVM_ARM_PSCI_LATEST; | |
53 | - | |
54 | - return KVM_ARM_PSCI_0_1; | |
55 | -} | |
56 | - | |
57 | static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) | |
58 | { | |
59 | struct kvm *kvm = vcpu->kvm; | |
60 | @@ -395,7 +387,7 @@ static int kvm_psci_0_1_call(struct kvm_ | |
61 | */ | |
62 | static int kvm_psci_call(struct kvm_vcpu *vcpu) | |
63 | { | |
64 | - switch (kvm_psci_version(vcpu)) { | |
65 | + switch (kvm_psci_version(vcpu, vcpu->kvm)) { | |
66 | case KVM_ARM_PSCI_1_0: | |
67 | return kvm_psci_1_0_call(vcpu); | |
68 | case KVM_ARM_PSCI_0_2: | |
69 | --- a/arch/arm64/kvm/hyp/switch.c | |
70 | +++ b/arch/arm64/kvm/hyp/switch.c | |
71 | @@ -19,6 +19,8 @@ | |
72 | #include <linux/jump_label.h> | |
73 | #include <uapi/linux/psci.h> | |
74 | ||
75 | +#include <kvm/arm_psci.h> | |
76 | + | |
77 | #include <asm/kvm_asm.h> | |
78 | #include <asm/kvm_emulate.h> | |
79 | #include <asm/kvm_hyp.h> | |
80 | @@ -311,14 +313,16 @@ again: | |
81 | ||
82 | if (exit_code == ARM_EXCEPTION_TRAP && | |
83 | (kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_HVC64 || | |
84 | - kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_HVC32) && | |
85 | - vcpu_get_reg(vcpu, 0) == PSCI_0_2_FN_PSCI_VERSION) { | |
86 | - u64 val = PSCI_RET_NOT_SUPPORTED; | |
87 | - if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) | |
88 | - val = 2; | |
89 | + kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_HVC32)) { | |
90 | + u32 val = vcpu_get_reg(vcpu, 0); | |
91 | ||
92 | - vcpu_set_reg(vcpu, 0, val); | |
93 | - goto again; | |
94 | + if (val == PSCI_0_2_FN_PSCI_VERSION) { | |
95 | + val = kvm_psci_version(vcpu, kern_hyp_va(vcpu->kvm)); | |
96 | + if (unlikely(val == KVM_ARM_PSCI_0_1)) | |
97 | + val = PSCI_RET_NOT_SUPPORTED; | |
98 | + vcpu_set_reg(vcpu, 0, val); | |
99 | + goto again; | |
100 | + } | |
101 | } | |
102 | ||
103 | if (static_branch_unlikely(&vgic_v2_cpuif_trap) && | |
104 | --- a/include/kvm/arm_psci.h | |
105 | +++ b/include/kvm/arm_psci.h | |
106 | @@ -18,6 +18,7 @@ | |
107 | #ifndef __KVM_ARM_PSCI_H__ | |
108 | #define __KVM_ARM_PSCI_H__ | |
109 | ||
110 | +#include <linux/kvm_host.h> | |
111 | #include <uapi/linux/psci.h> | |
112 | ||
113 | #define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1) | |
114 | @@ -26,7 +27,25 @@ | |
115 | ||
116 | #define KVM_ARM_PSCI_LATEST KVM_ARM_PSCI_1_0 | |
117 | ||
118 | -int kvm_psci_version(struct kvm_vcpu *vcpu); | |
119 | +/* | |
120 | + * We need the KVM pointer independently from the vcpu as we can call | |
121 | + * this from HYP, and need to apply kern_hyp_va on it... | |
122 | + */ | |
123 | +static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm) | |
124 | +{ | |
125 | + /* | |
126 | + * Our PSCI implementation stays the same across versions from | |
127 | + * v0.2 onward, only adding the few mandatory functions (such | |
128 | + * as FEATURES with 1.0) that are required by newer | |
129 | + * revisions. It is thus safe to return the latest. | |
130 | + */ | |
131 | + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) | |
132 | + return KVM_ARM_PSCI_LATEST; | |
133 | + | |
134 | + return KVM_ARM_PSCI_0_1; | |
135 | +} | |
136 | + | |
137 | + | |
138 | int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); | |
139 | ||
140 | #endif /* __KVM_ARM_PSCI_H__ */ |