1/* 2 * Copyright (C) 2012 - ARM Ltd 3 * Author: Marc Zyngier <marc.zyngier@arm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include <linux/preempt.h> 19#include <linux/kvm_host.h> 20#include <linux/wait.h> 21 22#include <asm/cputype.h> 23#include <asm/kvm_emulate.h> 24#include <asm/kvm_psci.h> 25#include <asm/kvm_host.h> 26 27#include <uapi/linux/psci.h> 28 29/* 30 * This is an implementation of the Power State Coordination Interface 31 * as described in ARM document number ARM DEN 0022A. 32 */ 33 34#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1) 35 36static unsigned long psci_affinity_mask(unsigned long affinity_level) 37{ 38 if (affinity_level <= 3) 39 return MPIDR_HWID_BITMASK & AFFINITY_MASK(affinity_level); 40 41 return 0; 42} 43 44static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu) 45{ 46 /* 47 * NOTE: For simplicity, we make VCPU suspend emulation to be 48 * same-as WFI (Wait-for-interrupt) emulation. 49 * 50 * This means for KVM the wakeup events are interrupts and 51 * this is consistent with intended use of StateID as described 52 * in section 5.4.1 of PSCI v0.2 specification (ARM DEN 0022A). 53 * 54 * Further, we also treat power-down request to be same as 55 * stand-by request as-per section 5.4.2 clause 3 of PSCI v0.2 56 * specification (ARM DEN 0022A). This means all suspend states 57 * for KVM will preserve the register state. 58 */ 59 kvm_vcpu_block(vcpu); 60 61 return PSCI_RET_SUCCESS; 62} 63 64static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu) 65{ 66 vcpu->arch.power_off = true; 67} 68 69static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) 70{ 71 struct kvm *kvm = source_vcpu->kvm; 72 struct kvm_vcpu *vcpu = NULL; 73 wait_queue_head_t *wq; 74 unsigned long cpu_id; 75 unsigned long context_id; 76 phys_addr_t target_pc; 77 78 cpu_id = vcpu_get_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK; 79 if (vcpu_mode_is_32bit(source_vcpu)) 80 cpu_id &= ~((u32) 0); 81 82 vcpu = kvm_mpidr_to_vcpu(kvm, cpu_id); 83 84 /* 85 * Make sure the caller requested a valid CPU and that the CPU is 86 * turned off. 87 */ 88 if (!vcpu) 89 return PSCI_RET_INVALID_PARAMS; 90 if (!vcpu->arch.power_off) { 91 if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1) 92 return PSCI_RET_ALREADY_ON; 93 else 94 return PSCI_RET_INVALID_PARAMS; 95 } 96 97 target_pc = vcpu_get_reg(source_vcpu, 2); 98 context_id = vcpu_get_reg(source_vcpu, 3); 99 100 kvm_reset_vcpu(vcpu); 101 102 /* Gracefully handle Thumb2 entry point */ 103 if (vcpu_mode_is_32bit(vcpu) && (target_pc & 1)) { 104 target_pc &= ~((phys_addr_t) 1); 105 vcpu_set_thumb(vcpu); 106 } 107 108 /* Propagate caller endianness */ 109 if (kvm_vcpu_is_be(source_vcpu)) 110 kvm_vcpu_set_be(vcpu); 111 112 *vcpu_pc(vcpu) = target_pc; 113 /* 114 * NOTE: We always update r0 (or x0) because for PSCI v0.1 115 * the general puspose registers are undefined upon CPU_ON. 116 */ 117 vcpu_set_reg(vcpu, 0, context_id); 118 vcpu->arch.power_off = false; 119 smp_mb(); /* Make sure the above is visible */ 120 121 wq = kvm_arch_vcpu_wq(vcpu); 122 wake_up_interruptible(wq); 123 124 return PSCI_RET_SUCCESS; 125} 126 127static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu) 128{ 129 int i, matching_cpus = 0; 130 unsigned long mpidr; 131 unsigned long target_affinity; 132 unsigned long target_affinity_mask; 133 unsigned long lowest_affinity_level; 134 struct kvm *kvm = vcpu->kvm; 135 struct kvm_vcpu *tmp; 136 137 target_affinity = vcpu_get_reg(vcpu, 1); 138 lowest_affinity_level = vcpu_get_reg(vcpu, 2); 139 140 /* Determine target affinity mask */ 141 target_affinity_mask = psci_affinity_mask(lowest_affinity_level); 142 if (!target_affinity_mask) 143 return PSCI_RET_INVALID_PARAMS; 144 145 /* Ignore other bits of target affinity */ 146 target_affinity &= target_affinity_mask; 147 148 /* 149 * If one or more VCPU matching target affinity are running 150 * then ON else OFF 151 */ 152 kvm_for_each_vcpu(i, tmp, kvm) { 153 mpidr = kvm_vcpu_get_mpidr_aff(tmp); 154 if ((mpidr & target_affinity_mask) == target_affinity) { 155 matching_cpus++; 156 if (!tmp->arch.power_off) 157 return PSCI_0_2_AFFINITY_LEVEL_ON; 158 } 159 } 160 161 if (!matching_cpus) 162 return PSCI_RET_INVALID_PARAMS; 163 164 return PSCI_0_2_AFFINITY_LEVEL_OFF; 165} 166 167static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type) 168{ 169 int i; 170 struct kvm_vcpu *tmp; 171 172 /* 173 * The KVM ABI specifies that a system event exit may call KVM_RUN 174 * again and may perform shutdown/reboot at a later time that when the 175 * actual request is made. Since we are implementing PSCI and a 176 * caller of PSCI reboot and shutdown expects that the system shuts 177 * down or reboots immediately, let's make sure that VCPUs are not run 178 * after this call is handled and before the VCPUs have been 179 * re-initialized. 180 */ 181 kvm_for_each_vcpu(i, tmp, vcpu->kvm) { 182 tmp->arch.power_off = true; 183 kvm_vcpu_kick(tmp); 184 } 185 186 memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); 187 vcpu->run->system_event.type = type; 188 vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; 189} 190 191static void kvm_psci_system_off(struct kvm_vcpu *vcpu) 192{ 193 kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN); 194} 195 196static void kvm_psci_system_reset(struct kvm_vcpu *vcpu) 197{ 198 kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET); 199} 200 201int kvm_psci_version(struct kvm_vcpu *vcpu) 202{ 203 if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) 204 return KVM_ARM_PSCI_0_2; 205 206 return KVM_ARM_PSCI_0_1; 207} 208 209static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu) 210{ 211 int ret = 1; 212 unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0); 213 unsigned long val; 214 215 switch (psci_fn) { 216 case PSCI_0_2_FN_PSCI_VERSION: 217 /* 218 * Bits[31:16] = Major Version = 0 219 * Bits[15:0] = Minor Version = 2 220 */ 221 val = 2; 222 break; 223 case PSCI_0_2_FN_CPU_SUSPEND: 224 case PSCI_0_2_FN64_CPU_SUSPEND: 225 val = kvm_psci_vcpu_suspend(vcpu); 226 break; 227 case PSCI_0_2_FN_CPU_OFF: 228 kvm_psci_vcpu_off(vcpu); 229 val = PSCI_RET_SUCCESS; 230 break; 231 case PSCI_0_2_FN_CPU_ON: 232 case PSCI_0_2_FN64_CPU_ON: 233 val = kvm_psci_vcpu_on(vcpu); 234 break; 235 case PSCI_0_2_FN_AFFINITY_INFO: 236 case PSCI_0_2_FN64_AFFINITY_INFO: 237 val = kvm_psci_vcpu_affinity_info(vcpu); 238 break; 239 case PSCI_0_2_FN_MIGRATE_INFO_TYPE: 240 /* 241 * Trusted OS is MP hence does not require migration 242 * or 243 * Trusted OS is not present 244 */ 245 val = PSCI_0_2_TOS_MP; 246 break; 247 case PSCI_0_2_FN_SYSTEM_OFF: 248 kvm_psci_system_off(vcpu); 249 /* 250 * We should'nt be going back to guest VCPU after 251 * receiving SYSTEM_OFF request. 252 * 253 * If user space accidently/deliberately resumes 254 * guest VCPU after SYSTEM_OFF request then guest 255 * VCPU should see internal failure from PSCI return 256 * value. To achieve this, we preload r0 (or x0) with 257 * PSCI return value INTERNAL_FAILURE. 258 */ 259 val = PSCI_RET_INTERNAL_FAILURE; 260 ret = 0; 261 break; 262 case PSCI_0_2_FN_SYSTEM_RESET: 263 kvm_psci_system_reset(vcpu); 264 /* 265 * Same reason as SYSTEM_OFF for preloading r0 (or x0) 266 * with PSCI return value INTERNAL_FAILURE. 267 */ 268 val = PSCI_RET_INTERNAL_FAILURE; 269 ret = 0; 270 break; 271 default: 272 val = PSCI_RET_NOT_SUPPORTED; 273 break; 274 } 275 276 vcpu_set_reg(vcpu, 0, val); 277 return ret; 278} 279 280static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu) 281{ 282 unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0); 283 unsigned long val; 284 285 switch (psci_fn) { 286 case KVM_PSCI_FN_CPU_OFF: 287 kvm_psci_vcpu_off(vcpu); 288 val = PSCI_RET_SUCCESS; 289 break; 290 case KVM_PSCI_FN_CPU_ON: 291 val = kvm_psci_vcpu_on(vcpu); 292 break; 293 default: 294 val = PSCI_RET_NOT_SUPPORTED; 295 break; 296 } 297 298 vcpu_set_reg(vcpu, 0, val); 299 return 1; 300} 301 302/** 303 * kvm_psci_call - handle PSCI call if r0 value is in range 304 * @vcpu: Pointer to the VCPU struct 305 * 306 * Handle PSCI calls from guests through traps from HVC instructions. 307 * The calling convention is similar to SMC calls to the secure world 308 * where the function number is placed in r0. 309 * 310 * This function returns: > 0 (success), 0 (success but exit to user 311 * space), and < 0 (errors) 312 * 313 * Errors: 314 * -EINVAL: Unrecognized PSCI function 315 */ 316int kvm_psci_call(struct kvm_vcpu *vcpu) 317{ 318 switch (kvm_psci_version(vcpu)) { 319 case KVM_ARM_PSCI_0_2: 320 return kvm_psci_0_2_call(vcpu); 321 case KVM_ARM_PSCI_0_1: 322 return kvm_psci_0_1_call(vcpu); 323 default: 324 return -EINVAL; 325 }; 326} 327