aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/kvm_psci.h2
-rw-r--r--arch/arm/kvm/handle_exit.c10
-rw-r--r--arch/arm/kvm/psci.c28
3 files changed, 24 insertions, 16 deletions
diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h
index 4c0e3e1d1597..6bda945d31fa 100644
--- a/arch/arm/include/asm/kvm_psci.h
+++ b/arch/arm/include/asm/kvm_psci.h
@@ -22,6 +22,6 @@
22#define KVM_ARM_PSCI_0_2 2 22#define KVM_ARM_PSCI_0_2 2
23 23
24int kvm_psci_version(struct kvm_vcpu *vcpu); 24int kvm_psci_version(struct kvm_vcpu *vcpu);
25bool kvm_psci_call(struct kvm_vcpu *vcpu); 25int kvm_psci_call(struct kvm_vcpu *vcpu);
26 26
27#endif /* __ARM_KVM_PSCI_H__ */ 27#endif /* __ARM_KVM_PSCI_H__ */
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 0de91fc6de0f..4c979d466cc1 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -38,14 +38,18 @@ static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
38 38
39static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run) 39static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
40{ 40{
41 int ret;
42
41 trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0), 43 trace_kvm_hvc(*vcpu_pc(vcpu), *vcpu_reg(vcpu, 0),
42 kvm_vcpu_hvc_get_imm(vcpu)); 44 kvm_vcpu_hvc_get_imm(vcpu));
43 45
44 if (kvm_psci_call(vcpu)) 46 ret = kvm_psci_call(vcpu);
47 if (ret < 0) {
48 kvm_inject_undefined(vcpu);
45 return 1; 49 return 1;
50 }
46 51
47 kvm_inject_undefined(vcpu); 52 return ret;
48 return 1;
49} 53}
50 54
51static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run) 55static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 8c42596cdbdf..14e6fa6c8e35 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -93,7 +93,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
93 return KVM_ARM_PSCI_0_1; 93 return KVM_ARM_PSCI_0_1;
94} 94}
95 95
96static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu) 96static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
97{ 97{
98 unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0); 98 unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
99 unsigned long val; 99 unsigned long val;
@@ -128,14 +128,14 @@ static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
128 val = PSCI_RET_NOT_SUPPORTED; 128 val = PSCI_RET_NOT_SUPPORTED;
129 break; 129 break;
130 default: 130 default:
131 return false; 131 return -EINVAL;
132 } 132 }
133 133
134 *vcpu_reg(vcpu, 0) = val; 134 *vcpu_reg(vcpu, 0) = val;
135 return true; 135 return 1;
136} 136}
137 137
138static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu) 138static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
139{ 139{
140 unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0); 140 unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
141 unsigned long val; 141 unsigned long val;
@@ -153,11 +153,11 @@ static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
153 val = PSCI_RET_NOT_SUPPORTED; 153 val = PSCI_RET_NOT_SUPPORTED;
154 break; 154 break;
155 default: 155 default:
156 return false; 156 return -EINVAL;
157 } 157 }
158 158
159 *vcpu_reg(vcpu, 0) = val; 159 *vcpu_reg(vcpu, 0) = val;
160 return true; 160 return 1;
161} 161}
162 162
163/** 163/**
@@ -165,12 +165,16 @@ static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
165 * @vcpu: Pointer to the VCPU struct 165 * @vcpu: Pointer to the VCPU struct
166 * 166 *
167 * Handle PSCI calls from guests through traps from HVC instructions. 167 * Handle PSCI calls from guests through traps from HVC instructions.
168 * The calling convention is similar to SMC calls to the secure world where 168 * The calling convention is similar to SMC calls to the secure world
169 * the function number is placed in r0 and this function returns true if the 169 * where the function number is placed in r0.
170 * function number specified in r0 is withing the PSCI range, and false 170 *
171 * otherwise. 171 * This function returns: > 0 (success), 0 (success but exit to user
172 * space), and < 0 (errors)
173 *
174 * Errors:
175 * -EINVAL: Unrecognized PSCI function
172 */ 176 */
173bool kvm_psci_call(struct kvm_vcpu *vcpu) 177int kvm_psci_call(struct kvm_vcpu *vcpu)
174{ 178{
175 switch (kvm_psci_version(vcpu)) { 179 switch (kvm_psci_version(vcpu)) {
176 case KVM_ARM_PSCI_0_2: 180 case KVM_ARM_PSCI_0_2:
@@ -178,6 +182,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
178 case KVM_ARM_PSCI_0_1: 182 case KVM_ARM_PSCI_0_1:
179 return kvm_psci_0_1_call(vcpu); 183 return kvm_psci_0_1_call(vcpu);
180 default: 184 default:
181 return false; 185 return -EINVAL;
182 }; 186 };
183} 187}