1 // SPDX-License-Identifier: GPL-2.0 1 2 // Copyright (C) 2019 Arm Ltd. 3 4 #include <linux/arm-smccc.h> 5 #include <linux/kvm_host.h> 6 7 #include <asm/kvm_emulate.h> 8 9 #include <kvm/arm_hypercalls.h> 10 #include <kvm/arm_psci.h> 11 12 #define KVM_ARM_SMCCC_STD_FEATURES 13 GENMASK(KVM_REG_ARM_STD_BMAP_BIT_COUNT 14 #define KVM_ARM_SMCCC_STD_HYP_FEATURES 15 GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_C 16 #define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES 17 GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BI 18 19 static void kvm_ptp_get_time(struct kvm_vcpu * 20 { 21 struct system_time_snapshot systime_sn 22 u64 cycles = ~0UL; 23 u32 feature; 24 25 /* 26 * system time and counter value must 27 * time to keep consistency and precis 28 */ 29 ktime_get_snapshot(&systime_snapshot); 30 31 /* 32 * This is only valid if the current c 33 * architected counter, as this is the 34 * can see. 35 */ 36 if (systime_snapshot.cs_id != CSID_ARM 37 return; 38 39 /* 40 * The guest selects one of the two re 41 * (virtual or physical) with the firs 42 * call. In case the identifier is not 43 */ 44 feature = smccc_get_arg1(vcpu); 45 switch (feature) { 46 case KVM_PTP_VIRT_COUNTER: 47 cycles = systime_snapshot.cycl 48 break; 49 case KVM_PTP_PHYS_COUNTER: 50 cycles = systime_snapshot.cycl 51 break; 52 default: 53 return; 54 } 55 56 /* 57 * This relies on the top bit of val[0 58 * valid values of system time, becaus 59 * in the future (about 292 years from 60 * nobody will give a damn about it). 61 */ 62 val[0] = upper_32_bits(systime_snapsho 63 val[1] = lower_32_bits(systime_snapsho 64 val[2] = upper_32_bits(cycles); 65 val[3] = lower_32_bits(cycles); 66 } 67 68 static bool kvm_smccc_default_allowed(u32 func 69 { 70 switch (func_id) { 71 /* 72 * List of function-ids that are not g 73 * feature firmware registers, and are 74 * servicing the call by default. 75 */ 76 case ARM_SMCCC_VERSION_FUNC_ID: 77 case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: 78 return true; 79 default: 80 /* PSCI 0.2 and up is in the 0 81 if (ARM_SMCCC_OWNER_NUM(func_i 82 ARM_SMCCC_FUNC_NUM(func_id 83 return true; 84 85 /* 86 * KVM's PSCI 0.1 doesn't comp 87 * its own function-id base an 88 */ 89 if (func_id >= KVM_PSCI_FN(0) 90 return true; 91 92 return false; 93 } 94 } 95 96 static bool kvm_smccc_test_fw_bmap(struct kvm_ 97 { 98 struct kvm_smccc_features *smccc_feat 99 100 switch (func_id) { 101 case ARM_SMCCC_TRNG_VERSION: 102 case ARM_SMCCC_TRNG_FEATURES: 103 case ARM_SMCCC_TRNG_GET_UUID: 104 case ARM_SMCCC_TRNG_RND32: 105 case ARM_SMCCC_TRNG_RND64: 106 return test_bit(KVM_REG_ARM_ST 107 &smccc_feat->s 108 case ARM_SMCCC_HV_PV_TIME_FEATURES: 109 case ARM_SMCCC_HV_PV_TIME_ST: 110 return test_bit(KVM_REG_ARM_ST 111 &smccc_feat->s 112 case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES 113 case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUN 114 return test_bit(KVM_REG_ARM_VE 115 &smccc_feat->v 116 case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC 117 return test_bit(KVM_REG_ARM_VE 118 &smccc_feat->v 119 default: 120 return false; 121 } 122 } 123 124 #define SMC32_ARCH_RANGE_BEGIN ARM_SMCCC_VERS 125 #define SMC32_ARCH_RANGE_END ARM_SMCCC_CALL 126 127 128 129 #define SMC64_ARCH_RANGE_BEGIN ARM_SMCCC_CALL 130 131 132 #define SMC64_ARCH_RANGE_END ARM_SMCCC_CALL 133 134 135 136 static int kvm_smccc_filter_insert_reserved(st 137 { 138 int r; 139 140 /* 141 * Prevent userspace from handling any 142 * range, avoiding the risk of misrepr 143 * to the guest. 144 */ 145 r = mtree_insert_range(&kvm->arch.smcc 146 SMC32_ARCH_RANG 147 xa_mk_value(KVM 148 GFP_KERNEL_ACCO 149 if (r) 150 goto out_destroy; 151 152 r = mtree_insert_range(&kvm->arch.smcc 153 SMC64_ARCH_RANG 154 xa_mk_value(KVM 155 GFP_KERNEL_ACCO 156 if (r) 157 goto out_destroy; 158 159 return 0; 160 out_destroy: 161 mtree_destroy(&kvm->arch.smccc_filter) 162 return r; 163 } 164 165 static bool kvm_smccc_filter_configured(struct 166 { 167 return !mtree_empty(&kvm->arch.smccc_f 168 } 169 170 static int kvm_smccc_set_filter(struct kvm *kv 171 { 172 const void *zero_page = page_to_virt(Z 173 struct kvm_smccc_filter filter; 174 u32 start, end; 175 int r; 176 177 if (copy_from_user(&filter, uaddr, siz 178 return -EFAULT; 179 180 if (memcmp(filter.pad, zero_page, size 181 return -EINVAL; 182 183 start = filter.base; 184 end = start + filter.nr_functions - 1; 185 186 if (end < start || filter.action >= NR 187 return -EINVAL; 188 189 mutex_lock(&kvm->arch.config_lock); 190 191 if (kvm_vm_has_ran_once(kvm)) { 192 r = -EBUSY; 193 goto out_unlock; 194 } 195 196 if (!kvm_smccc_filter_configured(kvm)) 197 r = kvm_smccc_filter_insert_re 198 if (WARN_ON_ONCE(r)) 199 goto out_unlock; 200 } 201 202 r = mtree_insert_range(&kvm->arch.smcc 203 xa_mk_value(fil 204 out_unlock: 205 mutex_unlock(&kvm->arch.config_lock); 206 return r; 207 } 208 209 static u8 kvm_smccc_filter_get_action(struct k 210 { 211 unsigned long idx = func_id; 212 void *val; 213 214 if (!kvm_smccc_filter_configured(kvm)) 215 return KVM_SMCCC_FILTER_HANDLE 216 217 /* 218 * But where's the error handling, you 219 * 220 * mt_find() returns NULL if no entry 221 * to match KVM_SMCCC_FILTER_HANDLE. 222 */ 223 val = mt_find(&kvm->arch.smccc_filter, 224 return xa_to_value(val); 225 } 226 227 static u8 kvm_smccc_get_action(struct kvm_vcpu 228 { 229 /* 230 * Intervening actions in the SMCCC fi 231 * pseudo-firmware register bitmaps. 232 */ 233 u8 action = kvm_smccc_filter_get_actio 234 if (action != KVM_SMCCC_FILTER_HANDLE) 235 return action; 236 237 if (kvm_smccc_test_fw_bmap(vcpu, func_ 238 kvm_smccc_default_allowed(func_id) 239 return KVM_SMCCC_FILTER_HANDLE 240 241 return KVM_SMCCC_FILTER_DENY; 242 } 243 244 static void kvm_prepare_hypercall_exit(struct 245 { 246 u8 ec = ESR_ELx_EC(kvm_vcpu_get_esr(vc 247 struct kvm_run *run = vcpu->run; 248 u64 flags = 0; 249 250 if (ec == ESR_ELx_EC_SMC32 || ec == ES 251 flags |= KVM_HYPERCALL_EXIT_SM 252 253 if (!kvm_vcpu_trap_il_is32bit(vcpu)) 254 flags |= KVM_HYPERCALL_EXIT_16 255 256 run->exit_reason = KVM_EXIT_HYPERCALL; 257 run->hypercall = (typeof(run->hypercal 258 .nr = func_id, 259 .flags = flags, 260 }; 261 } 262 263 int kvm_smccc_call_handler(struct kvm_vcpu *vc 264 { 265 struct kvm_smccc_features *smccc_feat 266 u32 func_id = smccc_get_function(vcpu) 267 u64 val[4] = {SMCCC_RET_NOT_SUPPORTED} 268 u32 feature; 269 u8 action; 270 gpa_t gpa; 271 272 action = kvm_smccc_get_action(vcpu, fu 273 switch (action) { 274 case KVM_SMCCC_FILTER_HANDLE: 275 break; 276 case KVM_SMCCC_FILTER_DENY: 277 goto out; 278 case KVM_SMCCC_FILTER_FWD_TO_USER: 279 kvm_prepare_hypercall_exit(vcp 280 return 0; 281 default: 282 WARN_RATELIMIT(1, "Unhandled S 283 goto out; 284 } 285 286 switch (func_id) { 287 case ARM_SMCCC_VERSION_FUNC_ID: 288 val[0] = ARM_SMCCC_VERSION_1_1 289 break; 290 case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: 291 feature = smccc_get_arg1(vcpu) 292 switch (feature) { 293 case ARM_SMCCC_ARCH_WORKAROUND 294 switch (arm64_get_spec 295 case SPECTRE_VULNERABL 296 break; 297 case SPECTRE_MITIGATED 298 val[0] = SMCCC 299 break; 300 case SPECTRE_UNAFFECTE 301 val[0] = SMCCC 302 break; 303 } 304 break; 305 case ARM_SMCCC_ARCH_WORKAROUND 306 switch (arm64_get_spec 307 case SPECTRE_VULNERABL 308 break; 309 case SPECTRE_MITIGATED 310 /* 311 * SSBS everyw 312 * support, as 313 * indicated t 314 * safe. 315 * 316 * Otherwise, 317 * to the gues 318 * guest stays 319 */ 320 if (kvm_has_fe 321 break; 322 fallthrough; 323 case SPECTRE_UNAFFECTE 324 val[0] = SMCCC 325 break; 326 } 327 break; 328 case ARM_SMCCC_ARCH_WORKAROUND 329 switch (arm64_get_spec 330 case SPECTRE_VULNERABL 331 break; 332 case SPECTRE_MITIGATED 333 val[0] = SMCCC 334 break; 335 case SPECTRE_UNAFFECTE 336 val[0] = SMCCC 337 break; 338 } 339 break; 340 case ARM_SMCCC_HV_PV_TIME_FEAT 341 if (test_bit(KVM_REG_A 342 &smccc_fe 343 val[0] = SMCCC 344 break; 345 } 346 break; 347 case ARM_SMCCC_HV_PV_TIME_FEATURES: 348 val[0] = kvm_hypercall_pv_feat 349 break; 350 case ARM_SMCCC_HV_PV_TIME_ST: 351 gpa = kvm_init_stolen_time(vcp 352 if (gpa != INVALID_GPA) 353 val[0] = gpa; 354 break; 355 case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUN 356 val[0] = ARM_SMCCC_VENDOR_HYP_ 357 val[1] = ARM_SMCCC_VENDOR_HYP_ 358 val[2] = ARM_SMCCC_VENDOR_HYP_ 359 val[3] = ARM_SMCCC_VENDOR_HYP_ 360 break; 361 case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES 362 val[0] = smccc_feat->vendor_hy 363 break; 364 case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC 365 kvm_ptp_get_time(vcpu, val); 366 break; 367 case ARM_SMCCC_TRNG_VERSION: 368 case ARM_SMCCC_TRNG_FEATURES: 369 case ARM_SMCCC_TRNG_GET_UUID: 370 case ARM_SMCCC_TRNG_RND32: 371 case ARM_SMCCC_TRNG_RND64: 372 return kvm_trng_call(vcpu); 373 default: 374 return kvm_psci_call(vcpu); 375 } 376 377 out: 378 smccc_set_retval(vcpu, val[0], val[1], 379 return 1; 380 } 381 382 static const u64 kvm_arm_fw_reg_ids[] = { 383 KVM_REG_ARM_PSCI_VERSION, 384 KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, 385 KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, 386 KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, 387 KVM_REG_ARM_STD_BMAP, 388 KVM_REG_ARM_STD_HYP_BMAP, 389 KVM_REG_ARM_VENDOR_HYP_BMAP, 390 }; 391 392 void kvm_arm_init_hypercalls(struct kvm *kvm) 393 { 394 struct kvm_smccc_features *smccc_feat 395 396 smccc_feat->std_bmap = KVM_ARM_SMCCC_S 397 smccc_feat->std_hyp_bmap = KVM_ARM_SMC 398 smccc_feat->vendor_hyp_bmap = KVM_ARM_ 399 400 mt_init(&kvm->arch.smccc_filter); 401 } 402 403 void kvm_arm_teardown_hypercalls(struct kvm *k 404 { 405 mtree_destroy(&kvm->arch.smccc_filter) 406 } 407 408 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *v 409 { 410 return ARRAY_SIZE(kvm_arm_fw_reg_ids); 411 } 412 413 int kvm_arm_copy_fw_reg_indices(struct kvm_vcp 414 { 415 int i; 416 417 for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_ 418 if (put_user(kvm_arm_fw_reg_id 419 return -EFAULT; 420 } 421 422 return 0; 423 } 424 425 #define KVM_REG_FEATURE_LEVEL_MASK GENMAS 426 427 /* 428 * Convert the workaround level into an easy-t 429 * values mean better protection. 430 */ 431 static int get_kernel_wa_level(struct kvm_vcpu 432 { 433 switch (regid) { 434 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 435 switch (arm64_get_spectre_v2_s 436 case SPECTRE_VULNERABLE: 437 return KVM_REG_ARM_SMC 438 case SPECTRE_MITIGATED: 439 return KVM_REG_ARM_SMC 440 case SPECTRE_UNAFFECTED: 441 return KVM_REG_ARM_SMC 442 } 443 return KVM_REG_ARM_SMCCC_ARCH_ 444 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 445 switch (arm64_get_spectre_v4_s 446 case SPECTRE_MITIGATED: 447 /* 448 * As for the hypercal 449 * don't have any FW m 450 * all times. 451 */ 452 if (kvm_has_feat(vcpu- 453 return KVM_REG 454 fallthrough; 455 case SPECTRE_UNAFFECTED: 456 return KVM_REG_ARM_SMC 457 case SPECTRE_VULNERABLE: 458 return KVM_REG_ARM_SMC 459 } 460 break; 461 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 462 switch (arm64_get_spectre_bhb_ 463 case SPECTRE_VULNERABLE: 464 return KVM_REG_ARM_SMC 465 case SPECTRE_MITIGATED: 466 return KVM_REG_ARM_SMC 467 case SPECTRE_UNAFFECTED: 468 return KVM_REG_ARM_SMC 469 } 470 return KVM_REG_ARM_SMCCC_ARCH_ 471 } 472 473 return -EINVAL; 474 } 475 476 int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, 477 { 478 struct kvm_smccc_features *smccc_feat 479 void __user *uaddr = (void __user *)(l 480 u64 val; 481 482 switch (reg->id) { 483 case KVM_REG_ARM_PSCI_VERSION: 484 val = kvm_psci_version(vcpu); 485 break; 486 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 487 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 488 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 489 val = get_kernel_wa_level(vcpu 490 break; 491 case KVM_REG_ARM_STD_BMAP: 492 val = READ_ONCE(smccc_feat->st 493 break; 494 case KVM_REG_ARM_STD_HYP_BMAP: 495 val = READ_ONCE(smccc_feat->st 496 break; 497 case KVM_REG_ARM_VENDOR_HYP_BMAP: 498 val = READ_ONCE(smccc_feat->ve 499 break; 500 default: 501 return -ENOENT; 502 } 503 504 if (copy_to_user(uaddr, &val, KVM_REG_ 505 return -EFAULT; 506 507 return 0; 508 } 509 510 static int kvm_arm_set_fw_reg_bmap(struct kvm_ 511 { 512 int ret = 0; 513 struct kvm *kvm = vcpu->kvm; 514 struct kvm_smccc_features *smccc_feat 515 unsigned long *fw_reg_bmap, fw_reg_fea 516 517 switch (reg_id) { 518 case KVM_REG_ARM_STD_BMAP: 519 fw_reg_bmap = &smccc_feat->std 520 fw_reg_features = KVM_ARM_SMCC 521 break; 522 case KVM_REG_ARM_STD_HYP_BMAP: 523 fw_reg_bmap = &smccc_feat->std 524 fw_reg_features = KVM_ARM_SMCC 525 break; 526 case KVM_REG_ARM_VENDOR_HYP_BMAP: 527 fw_reg_bmap = &smccc_feat->ven 528 fw_reg_features = KVM_ARM_SMCC 529 break; 530 default: 531 return -ENOENT; 532 } 533 534 /* Check for unsupported bit */ 535 if (val & ~fw_reg_features) 536 return -EINVAL; 537 538 mutex_lock(&kvm->arch.config_lock); 539 540 if (kvm_vm_has_ran_once(kvm) && val != 541 ret = -EBUSY; 542 goto out; 543 } 544 545 WRITE_ONCE(*fw_reg_bmap, val); 546 out: 547 mutex_unlock(&kvm->arch.config_lock); 548 return ret; 549 } 550 551 int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, 552 { 553 void __user *uaddr = (void __user *)(l 554 u64 val; 555 int wa_level; 556 557 if (KVM_REG_SIZE(reg->id) != sizeof(va 558 return -ENOENT; 559 if (copy_from_user(&val, uaddr, KVM_RE 560 return -EFAULT; 561 562 switch (reg->id) { 563 case KVM_REG_ARM_PSCI_VERSION: 564 { 565 bool wants_02; 566 567 wants_02 = vcpu_has_feature(vc 568 569 switch (val) { 570 case KVM_ARM_PSCI_0_1: 571 if (wants_02) 572 return -EINVAL 573 vcpu->kvm->arch.psci_v 574 return 0; 575 case KVM_ARM_PSCI_0_2: 576 case KVM_ARM_PSCI_1_0: 577 case KVM_ARM_PSCI_1_1: 578 if (!wants_02) 579 return -EINVAL 580 vcpu->kvm->arch.psci_v 581 return 0; 582 } 583 break; 584 } 585 586 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 587 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 588 if (val & ~KVM_REG_FEATURE_LEV 589 return -EINVAL; 590 591 if (get_kernel_wa_level(vcpu, 592 return -EINVAL; 593 594 return 0; 595 596 case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND 597 if (val & ~(KVM_REG_FEATURE_LE 598 KVM_REG_ARM_SMCCC_ 599 return -EINVAL; 600 601 /* The enabled bit must not be 602 if ((val & KVM_REG_ARM_SMCCC_A 603 (val & KVM_REG_FEATURE_LEV 604 return -EINVAL; 605 606 /* 607 * Map all the possible incomi 608 * really want to deal with. 609 */ 610 switch (val & KVM_REG_FEATURE_ 611 case KVM_REG_ARM_SMCCC_ARCH_WO 612 case KVM_REG_ARM_SMCCC_ARCH_WO 613 wa_level = KVM_REG_ARM 614 break; 615 case KVM_REG_ARM_SMCCC_ARCH_WO 616 case KVM_REG_ARM_SMCCC_ARCH_WO 617 wa_level = KVM_REG_ARM 618 break; 619 default: 620 return -EINVAL; 621 } 622 623 /* 624 * We can deal with NOT_AVAIL 625 * other way around. 626 */ 627 if (get_kernel_wa_level(vcpu, 628 return -EINVAL; 629 630 return 0; 631 case KVM_REG_ARM_STD_BMAP: 632 case KVM_REG_ARM_STD_HYP_BMAP: 633 case KVM_REG_ARM_VENDOR_HYP_BMAP: 634 return kvm_arm_set_fw_reg_bmap 635 default: 636 return -ENOENT; 637 } 638 639 return -EINVAL; 640 } 641 642 int kvm_vm_smccc_has_attr(struct kvm *kvm, str 643 { 644 switch (attr->attr) { 645 case KVM_ARM_VM_SMCCC_FILTER: 646 return 0; 647 default: 648 return -ENXIO; 649 } 650 } 651 652 int kvm_vm_smccc_set_attr(struct kvm *kvm, str 653 { 654 void __user *uaddr = (void __user *)at 655 656 switch (attr->attr) { 657 case KVM_ARM_VM_SMCCC_FILTER: 658 return kvm_smccc_set_filter(kv 659 default: 660 return -ENXIO; 661 } 662 } 663
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.