Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'kvmarm-5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 updates for 5.20:

- Unwinder implementations for both nVHE modes (classic and
protected), complete with an overflow stack

- Rework of the sysreg access from userspace, with a complete
rewrite of the vgic-v3 view to allign with the rest of the
infrastructure

- Disagregation of the vcpu flags in separate sets to better track
their use model.

- A fix for the GICv2-on-v3 selftest

- A small set of cosmetic fixes

+1596 -954
+16
arch/arm64/include/asm/kvm_asm.h
··· 176 176 unsigned long vtcr; 177 177 }; 178 178 179 + /* 180 + * Used by the host in EL1 to dump the nVHE hypervisor backtrace on 181 + * hyp_panic() in non-protected mode. 182 + * 183 + * @stack_base: hyp VA of the hyp_stack base. 184 + * @overflow_stack_base: hyp VA of the hyp_overflow_stack base. 185 + * @fp: hyp FP where the backtrace begins. 186 + * @pc: hyp PC where the backtrace begins. 187 + */ 188 + struct kvm_nvhe_stacktrace_info { 189 + unsigned long stack_base; 190 + unsigned long overflow_stack_base; 191 + unsigned long fp; 192 + unsigned long pc; 193 + }; 194 + 179 195 /* Translate a kernel address @ptr into its equivalent linear mapping */ 180 196 #define kvm_ksym_ref(ptr) \ 181 197 ({ \
+10 -1
arch/arm64/include/asm/kvm_emulate.h
··· 473 473 474 474 static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu) 475 475 { 476 - vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC; 476 + WARN_ON(vcpu_get_flag(vcpu, PENDING_EXCEPTION)); 477 + vcpu_set_flag(vcpu, INCREMENT_PC); 477 478 } 479 + 480 + #define kvm_pend_exception(v, e) \ 481 + do { \ 482 + WARN_ON(vcpu_get_flag((v), INCREMENT_PC)); \ 483 + vcpu_set_flag((v), PENDING_EXCEPTION); \ 484 + vcpu_set_flag((v), e); \ 485 + } while (0) 486 + 478 487 479 488 static inline bool vcpu_has_feature(struct kvm_vcpu *vcpu, int feature) 480 489 {
+148 -57
arch/arm64/include/asm/kvm_host.h
··· 325 325 /* Exception Information */ 326 326 struct kvm_vcpu_fault_info fault; 327 327 328 - /* Miscellaneous vcpu state flags */ 329 - u64 flags; 328 + /* Ownership of the FP regs */ 329 + enum { 330 + FP_STATE_FREE, 331 + FP_STATE_HOST_OWNED, 332 + FP_STATE_GUEST_OWNED, 333 + } fp_state; 334 + 335 + /* Configuration flags, set once and for all before the vcpu can run */ 336 + u8 cflags; 337 + 338 + /* Input flags to the hypervisor code, potentially cleared after use */ 339 + u8 iflags; 340 + 341 + /* State flags for kernel bookkeeping, unused by the hypervisor code */ 342 + u8 sflags; 343 + 344 + /* 345 + * Don't run the guest (internal implementation need). 346 + * 347 + * Contrary to the flags above, this is set/cleared outside of 348 + * a vcpu context, and thus cannot be mixed with the flags 349 + * themselves (or the flag accesses need to be made atomic). 350 + */ 351 + bool pause; 330 352 331 353 /* 332 354 * We maintain more than a single set of debug registers to support ··· 398 376 /* vcpu power state */ 399 377 struct kvm_mp_state mp_state; 400 378 401 - /* Don't run the guest (internal implementation need) */ 402 - bool pause; 403 - 404 379 /* Cache some mmu pages needed inside spinlock regions */ 405 380 struct kvm_mmu_memory_cache mmu_page_cache; 406 381 ··· 411 392 /* Additional reset state */ 412 393 struct vcpu_reset_state reset_state; 413 394 414 - /* True when deferrable sysregs are loaded on the physical CPU, 415 - * see kvm_vcpu_load_sysregs_vhe and kvm_vcpu_put_sysregs_vhe. */ 416 - bool sysregs_loaded_on_cpu; 417 - 418 395 /* Guest PV state */ 419 396 struct { 420 397 u64 last_steal; 421 398 gpa_t base; 422 399 } steal; 423 400 }; 401 + 402 + /* 403 + * Each 'flag' is composed of a comma-separated triplet: 404 + * 405 + * - the flag-set it belongs to in the vcpu->arch structure 406 + * - the value for that flag 407 + * - the mask for that flag 408 + * 409 + * __vcpu_single_flag() builds such a triplet for a single-bit flag. 410 + * unpack_vcpu_flag() extract the flag value from the triplet for 411 + * direct use outside of the flag accessors. 412 + */ 413 + #define __vcpu_single_flag(_set, _f) _set, (_f), (_f) 414 + 415 + #define __unpack_flag(_set, _f, _m) _f 416 + #define unpack_vcpu_flag(...) __unpack_flag(__VA_ARGS__) 417 + 418 + #define __build_check_flag(v, flagset, f, m) \ 419 + do { \ 420 + typeof(v->arch.flagset) *_fset; \ 421 + \ 422 + /* Check that the flags fit in the mask */ \ 423 + BUILD_BUG_ON(HWEIGHT(m) != HWEIGHT((f) | (m))); \ 424 + /* Check that the flags fit in the type */ \ 425 + BUILD_BUG_ON((sizeof(*_fset) * 8) <= __fls(m)); \ 426 + } while (0) 427 + 428 + #define __vcpu_get_flag(v, flagset, f, m) \ 429 + ({ \ 430 + __build_check_flag(v, flagset, f, m); \ 431 + \ 432 + v->arch.flagset & (m); \ 433 + }) 434 + 435 + #define __vcpu_set_flag(v, flagset, f, m) \ 436 + do { \ 437 + typeof(v->arch.flagset) *fset; \ 438 + \ 439 + __build_check_flag(v, flagset, f, m); \ 440 + \ 441 + fset = &v->arch.flagset; \ 442 + if (HWEIGHT(m) > 1) \ 443 + *fset &= ~(m); \ 444 + *fset |= (f); \ 445 + } while (0) 446 + 447 + #define __vcpu_clear_flag(v, flagset, f, m) \ 448 + do { \ 449 + typeof(v->arch.flagset) *fset; \ 450 + \ 451 + __build_check_flag(v, flagset, f, m); \ 452 + \ 453 + fset = &v->arch.flagset; \ 454 + *fset &= ~(m); \ 455 + } while (0) 456 + 457 + #define vcpu_get_flag(v, ...) __vcpu_get_flag((v), __VA_ARGS__) 458 + #define vcpu_set_flag(v, ...) __vcpu_set_flag((v), __VA_ARGS__) 459 + #define vcpu_clear_flag(v, ...) __vcpu_clear_flag((v), __VA_ARGS__) 460 + 461 + /* SVE exposed to guest */ 462 + #define GUEST_HAS_SVE __vcpu_single_flag(cflags, BIT(0)) 463 + /* SVE config completed */ 464 + #define VCPU_SVE_FINALIZED __vcpu_single_flag(cflags, BIT(1)) 465 + /* PTRAUTH exposed to guest */ 466 + #define GUEST_HAS_PTRAUTH __vcpu_single_flag(cflags, BIT(2)) 467 + 468 + /* Exception pending */ 469 + #define PENDING_EXCEPTION __vcpu_single_flag(iflags, BIT(0)) 470 + /* 471 + * PC increment. Overlaps with EXCEPT_MASK on purpose so that it can't 472 + * be set together with an exception... 473 + */ 474 + #define INCREMENT_PC __vcpu_single_flag(iflags, BIT(1)) 475 + /* Target EL/MODE (not a single flag, but let's abuse the macro) */ 476 + #define EXCEPT_MASK __vcpu_single_flag(iflags, GENMASK(3, 1)) 477 + 478 + /* Helpers to encode exceptions with minimum fuss */ 479 + #define __EXCEPT_MASK_VAL unpack_vcpu_flag(EXCEPT_MASK) 480 + #define __EXCEPT_SHIFT __builtin_ctzl(__EXCEPT_MASK_VAL) 481 + #define __vcpu_except_flags(_f) iflags, (_f << __EXCEPT_SHIFT), __EXCEPT_MASK_VAL 482 + 483 + /* 484 + * When PENDING_EXCEPTION is set, EXCEPT_MASK can take the following 485 + * values: 486 + * 487 + * For AArch32 EL1: 488 + */ 489 + #define EXCEPT_AA32_UND __vcpu_except_flags(0) 490 + #define EXCEPT_AA32_IABT __vcpu_except_flags(1) 491 + #define EXCEPT_AA32_DABT __vcpu_except_flags(2) 492 + /* For AArch64: */ 493 + #define EXCEPT_AA64_EL1_SYNC __vcpu_except_flags(0) 494 + #define EXCEPT_AA64_EL1_IRQ __vcpu_except_flags(1) 495 + #define EXCEPT_AA64_EL1_FIQ __vcpu_except_flags(2) 496 + #define EXCEPT_AA64_EL1_SERR __vcpu_except_flags(3) 497 + /* For AArch64 with NV (one day): */ 498 + #define EXCEPT_AA64_EL2_SYNC __vcpu_except_flags(4) 499 + #define EXCEPT_AA64_EL2_IRQ __vcpu_except_flags(5) 500 + #define EXCEPT_AA64_EL2_FIQ __vcpu_except_flags(6) 501 + #define EXCEPT_AA64_EL2_SERR __vcpu_except_flags(7) 502 + /* Guest debug is live */ 503 + #define DEBUG_DIRTY __vcpu_single_flag(iflags, BIT(4)) 504 + /* Save SPE context if active */ 505 + #define DEBUG_STATE_SAVE_SPE __vcpu_single_flag(iflags, BIT(5)) 506 + /* Save TRBE context if active */ 507 + #define DEBUG_STATE_SAVE_TRBE __vcpu_single_flag(iflags, BIT(6)) 508 + 509 + /* SVE enabled for host EL0 */ 510 + #define HOST_SVE_ENABLED __vcpu_single_flag(sflags, BIT(0)) 511 + /* SME enabled for EL0 */ 512 + #define HOST_SME_ENABLED __vcpu_single_flag(sflags, BIT(1)) 513 + /* Physical CPU not in supported_cpus */ 514 + #define ON_UNSUPPORTED_CPU __vcpu_single_flag(sflags, BIT(2)) 515 + /* WFIT instruction trapped */ 516 + #define IN_WFIT __vcpu_single_flag(sflags, BIT(3)) 517 + /* vcpu system registers loaded on physical CPU */ 518 + #define SYSREGS_ON_CPU __vcpu_single_flag(sflags, BIT(4)) 424 519 425 520 /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ 426 521 #define vcpu_sve_pffr(vcpu) (kern_hyp_va((vcpu)->arch.sve_state) + \ ··· 556 423 __size_ret; \ 557 424 }) 558 425 559 - /* vcpu_arch flags field values: */ 560 - #define KVM_ARM64_DEBUG_DIRTY (1 << 0) 561 - #define KVM_ARM64_FP_ENABLED (1 << 1) /* guest FP regs loaded */ 562 - #define KVM_ARM64_FP_HOST (1 << 2) /* host FP regs loaded */ 563 - #define KVM_ARM64_HOST_SVE_ENABLED (1 << 4) /* SVE enabled for EL0 */ 564 - #define KVM_ARM64_GUEST_HAS_SVE (1 << 5) /* SVE exposed to guest */ 565 - #define KVM_ARM64_VCPU_SVE_FINALIZED (1 << 6) /* SVE config completed */ 566 - #define KVM_ARM64_GUEST_HAS_PTRAUTH (1 << 7) /* PTRAUTH exposed to guest */ 567 - #define KVM_ARM64_PENDING_EXCEPTION (1 << 8) /* Exception pending */ 568 - /* 569 - * Overlaps with KVM_ARM64_EXCEPT_MASK on purpose so that it can't be 570 - * set together with an exception... 571 - */ 572 - #define KVM_ARM64_INCREMENT_PC (1 << 9) /* Increment PC */ 573 - #define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ 574 - /* 575 - * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can 576 - * take the following values: 577 - * 578 - * For AArch32 EL1: 579 - */ 580 - #define KVM_ARM64_EXCEPT_AA32_UND (0 << 9) 581 - #define KVM_ARM64_EXCEPT_AA32_IABT (1 << 9) 582 - #define KVM_ARM64_EXCEPT_AA32_DABT (2 << 9) 583 - /* For AArch64: */ 584 - #define KVM_ARM64_EXCEPT_AA64_ELx_SYNC (0 << 9) 585 - #define KVM_ARM64_EXCEPT_AA64_ELx_IRQ (1 << 9) 586 - #define KVM_ARM64_EXCEPT_AA64_ELx_FIQ (2 << 9) 587 - #define KVM_ARM64_EXCEPT_AA64_ELx_SERR (3 << 9) 588 - #define KVM_ARM64_EXCEPT_AA64_EL1 (0 << 11) 589 - #define KVM_ARM64_EXCEPT_AA64_EL2 (1 << 11) 590 - 591 - #define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */ 592 - #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE (1 << 13) /* Save TRBE context if active */ 593 - #define KVM_ARM64_FP_FOREIGN_FPSTATE (1 << 14) 594 - #define KVM_ARM64_ON_UNSUPPORTED_CPU (1 << 15) /* Physical CPU not in supported_cpus */ 595 - #define KVM_ARM64_HOST_SME_ENABLED (1 << 16) /* SME enabled for EL0 */ 596 - #define KVM_ARM64_WFIT (1 << 17) /* WFIT instruction trapped */ 597 - 598 426 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \ 599 427 KVM_GUESTDBG_USE_SW_BP | \ 600 428 KVM_GUESTDBG_USE_HW | \ 601 429 KVM_GUESTDBG_SINGLESTEP) 602 430 603 431 #define vcpu_has_sve(vcpu) (system_supports_sve() && \ 604 - ((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_SVE)) 432 + vcpu_get_flag(vcpu, GUEST_HAS_SVE)) 605 433 606 434 #ifdef CONFIG_ARM64_PTR_AUTH 607 435 #define vcpu_has_ptrauth(vcpu) \ 608 436 ((cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) || \ 609 437 cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) && \ 610 - (vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_PTRAUTH) 438 + vcpu_get_flag(vcpu, GUEST_HAS_PTRAUTH)) 611 439 #else 612 440 #define vcpu_has_ptrauth(vcpu) false 613 441 #endif 614 442 615 443 #define vcpu_on_unsupported_cpu(vcpu) \ 616 - ((vcpu)->arch.flags & KVM_ARM64_ON_UNSUPPORTED_CPU) 444 + vcpu_get_flag(vcpu, ON_UNSUPPORTED_CPU) 617 445 618 446 #define vcpu_set_on_unsupported_cpu(vcpu) \ 619 - ((vcpu)->arch.flags |= KVM_ARM64_ON_UNSUPPORTED_CPU) 447 + vcpu_set_flag(vcpu, ON_UNSUPPORTED_CPU) 620 448 621 449 #define vcpu_clear_on_unsupported_cpu(vcpu) \ 622 - ((vcpu)->arch.flags &= ~KVM_ARM64_ON_UNSUPPORTED_CPU) 450 + vcpu_clear_flag(vcpu, ON_UNSUPPORTED_CPU) 623 451 624 452 #define vcpu_gp_regs(v) (&(v)->arch.ctxt.regs) 625 453 ··· 714 620 715 621 unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu); 716 622 int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); 717 - int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); 718 - int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); 719 623 720 624 int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu, 721 625 struct kvm_vcpu_events *events); ··· 923 831 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature); 924 832 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); 925 833 926 - #define kvm_arm_vcpu_sve_finalized(vcpu) \ 927 - ((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED) 834 + #define kvm_arm_vcpu_sve_finalized(vcpu) vcpu_get_flag(vcpu, VCPU_SVE_FINALIZED) 928 835 929 836 #define kvm_has_mte(kvm) \ 930 837 (system_supports_mte() && \
+8
arch/arm64/include/asm/memory.h
··· 114 114 #define OVERFLOW_STACK_SIZE SZ_4K 115 115 116 116 /* 117 + * With the minimum frame size of [x29, x30], exactly half the combined 118 + * sizes of the hyp and overflow stacks is the maximum size needed to 119 + * save the unwinded stacktrace; plus an additional entry to delimit the 120 + * end. 121 + */ 122 + #define NVHE_STACKTRACE_SIZE ((OVERFLOW_STACK_SIZE + PAGE_SIZE) / 2 + sizeof(long)) 123 + 124 + /* 117 125 * Alignment of kernel segments (e.g. .text, .data). 118 126 * 119 127 * 4 KB granule: 16 level 3 entries, with contiguous bit
+2 -60
arch/arm64/include/asm/stacktrace.h
··· 8 8 #include <linux/percpu.h> 9 9 #include <linux/sched.h> 10 10 #include <linux/sched/task_stack.h> 11 - #include <linux/types.h> 12 11 #include <linux/llist.h> 13 12 14 13 #include <asm/memory.h> 14 + #include <asm/pointer_auth.h> 15 15 #include <asm/ptrace.h> 16 16 #include <asm/sdei.h> 17 17 18 - enum stack_type { 19 - STACK_TYPE_UNKNOWN, 20 - STACK_TYPE_TASK, 21 - STACK_TYPE_IRQ, 22 - STACK_TYPE_OVERFLOW, 23 - STACK_TYPE_SDEI_NORMAL, 24 - STACK_TYPE_SDEI_CRITICAL, 25 - __NR_STACK_TYPES 26 - }; 27 - 28 - struct stack_info { 29 - unsigned long low; 30 - unsigned long high; 31 - enum stack_type type; 32 - }; 18 + #include <asm/stacktrace/common.h> 33 19 34 20 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk, 35 21 const char *loglvl); 36 22 37 23 DECLARE_PER_CPU(unsigned long *, irq_stack_ptr); 38 - 39 - static inline bool on_stack(unsigned long sp, unsigned long size, 40 - unsigned long low, unsigned long high, 41 - enum stack_type type, struct stack_info *info) 42 - { 43 - if (!low) 44 - return false; 45 - 46 - if (sp < low || sp + size < sp || sp + size > high) 47 - return false; 48 - 49 - if (info) { 50 - info->low = low; 51 - info->high = high; 52 - info->type = type; 53 - } 54 - return true; 55 - } 56 24 57 25 static inline bool on_irq_stack(unsigned long sp, unsigned long size, 58 26 struct stack_info *info) ··· 56 88 static inline bool on_overflow_stack(unsigned long sp, unsigned long size, 57 89 struct stack_info *info) { return false; } 58 90 #endif 59 - 60 - 61 - /* 62 - * We can only safely access per-cpu stacks from current in a non-preemptible 63 - * context. 64 - */ 65 - static inline bool on_accessible_stack(const struct task_struct *tsk, 66 - unsigned long sp, unsigned long size, 67 - struct stack_info *info) 68 - { 69 - if (info) 70 - info->type = STACK_TYPE_UNKNOWN; 71 - 72 - if (on_task_stack(tsk, sp, size, info)) 73 - return true; 74 - if (tsk != current || preemptible()) 75 - return false; 76 - if (on_irq_stack(sp, size, info)) 77 - return true; 78 - if (on_overflow_stack(sp, size, info)) 79 - return true; 80 - if (on_sdei_stack(sp, size, info)) 81 - return true; 82 - 83 - return false; 84 - } 85 91 86 92 #endif /* __ASM_STACKTRACE_H */
+199
arch/arm64/include/asm/stacktrace/common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Common arm64 stack unwinder code. 4 + * 5 + * To implement a new arm64 stack unwinder: 6 + * 1) Include this header 7 + * 8 + * 2) Call into unwind_next_common() from your top level unwind 9 + * function, passing it the validation and translation callbacks 10 + * (though the later can be NULL if no translation is required). 11 + * 12 + * See: arch/arm64/kernel/stacktrace.c for the reference implementation. 13 + * 14 + * Copyright (C) 2012 ARM Ltd. 15 + */ 16 + #ifndef __ASM_STACKTRACE_COMMON_H 17 + #define __ASM_STACKTRACE_COMMON_H 18 + 19 + #include <linux/bitmap.h> 20 + #include <linux/bitops.h> 21 + #include <linux/kprobes.h> 22 + #include <linux/types.h> 23 + 24 + enum stack_type { 25 + STACK_TYPE_UNKNOWN, 26 + STACK_TYPE_TASK, 27 + STACK_TYPE_IRQ, 28 + STACK_TYPE_OVERFLOW, 29 + STACK_TYPE_SDEI_NORMAL, 30 + STACK_TYPE_SDEI_CRITICAL, 31 + STACK_TYPE_HYP, 32 + __NR_STACK_TYPES 33 + }; 34 + 35 + struct stack_info { 36 + unsigned long low; 37 + unsigned long high; 38 + enum stack_type type; 39 + }; 40 + 41 + /* 42 + * A snapshot of a frame record or fp/lr register values, along with some 43 + * accounting information necessary for robust unwinding. 44 + * 45 + * @fp: The fp value in the frame record (or the real fp) 46 + * @pc: The lr value in the frame record (or the real lr) 47 + * 48 + * @stacks_done: Stacks which have been entirely unwound, for which it is no 49 + * longer valid to unwind to. 50 + * 51 + * @prev_fp: The fp that pointed to this frame record, or a synthetic value 52 + * of 0. This is used to ensure that within a stack, each 53 + * subsequent frame record is at an increasing address. 54 + * @prev_type: The type of stack this frame record was on, or a synthetic 55 + * value of STACK_TYPE_UNKNOWN. This is used to detect a 56 + * transition from one stack to another. 57 + * 58 + * @kr_cur: When KRETPROBES is selected, holds the kretprobe instance 59 + * associated with the most recently encountered replacement lr 60 + * value. 61 + * 62 + * @task: The task being unwound. 63 + */ 64 + struct unwind_state { 65 + unsigned long fp; 66 + unsigned long pc; 67 + DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES); 68 + unsigned long prev_fp; 69 + enum stack_type prev_type; 70 + #ifdef CONFIG_KRETPROBES 71 + struct llist_node *kr_cur; 72 + #endif 73 + struct task_struct *task; 74 + }; 75 + 76 + static inline bool on_stack(unsigned long sp, unsigned long size, 77 + unsigned long low, unsigned long high, 78 + enum stack_type type, struct stack_info *info) 79 + { 80 + if (!low) 81 + return false; 82 + 83 + if (sp < low || sp + size < sp || sp + size > high) 84 + return false; 85 + 86 + if (info) { 87 + info->low = low; 88 + info->high = high; 89 + info->type = type; 90 + } 91 + return true; 92 + } 93 + 94 + static inline void unwind_init_common(struct unwind_state *state, 95 + struct task_struct *task) 96 + { 97 + state->task = task; 98 + #ifdef CONFIG_KRETPROBES 99 + state->kr_cur = NULL; 100 + #endif 101 + 102 + /* 103 + * Prime the first unwind. 104 + * 105 + * In unwind_next() we'll check that the FP points to a valid stack, 106 + * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be 107 + * treated as a transition to whichever stack that happens to be. The 108 + * prev_fp value won't be used, but we set it to 0 such that it is 109 + * definitely not an accessible stack address. 110 + */ 111 + bitmap_zero(state->stacks_done, __NR_STACK_TYPES); 112 + state->prev_fp = 0; 113 + state->prev_type = STACK_TYPE_UNKNOWN; 114 + } 115 + 116 + /* 117 + * stack_trace_translate_fp_fn() - Translates a non-kernel frame pointer to 118 + * a kernel address. 119 + * 120 + * @fp: the frame pointer to be updated to its kernel address. 121 + * @type: the stack type associated with frame pointer @fp 122 + * 123 + * Returns true and success and @fp is updated to the corresponding 124 + * kernel virtual address; otherwise returns false. 125 + */ 126 + typedef bool (*stack_trace_translate_fp_fn)(unsigned long *fp, 127 + enum stack_type type); 128 + 129 + /* 130 + * on_accessible_stack_fn() - Check whether a stack range is on any 131 + * of the possible stacks. 132 + * 133 + * @tsk: task whose stack is being unwound 134 + * @sp: stack address being checked 135 + * @size: size of the stack range being checked 136 + * @info: stack unwinding context 137 + */ 138 + typedef bool (*on_accessible_stack_fn)(const struct task_struct *tsk, 139 + unsigned long sp, unsigned long size, 140 + struct stack_info *info); 141 + 142 + static inline int unwind_next_common(struct unwind_state *state, 143 + struct stack_info *info, 144 + on_accessible_stack_fn accessible, 145 + stack_trace_translate_fp_fn translate_fp) 146 + { 147 + unsigned long fp = state->fp, kern_fp = fp; 148 + struct task_struct *tsk = state->task; 149 + 150 + if (fp & 0x7) 151 + return -EINVAL; 152 + 153 + if (!accessible(tsk, fp, 16, info)) 154 + return -EINVAL; 155 + 156 + if (test_bit(info->type, state->stacks_done)) 157 + return -EINVAL; 158 + 159 + /* 160 + * If fp is not from the current address space perform the necessary 161 + * translation before dereferencing it to get the next fp. 162 + */ 163 + if (translate_fp && !translate_fp(&kern_fp, info->type)) 164 + return -EINVAL; 165 + 166 + /* 167 + * As stacks grow downward, any valid record on the same stack must be 168 + * at a strictly higher address than the prior record. 169 + * 170 + * Stacks can nest in several valid orders, e.g. 171 + * 172 + * TASK -> IRQ -> OVERFLOW -> SDEI_NORMAL 173 + * TASK -> SDEI_NORMAL -> SDEI_CRITICAL -> OVERFLOW 174 + * HYP -> OVERFLOW 175 + * 176 + * ... but the nesting itself is strict. Once we transition from one 177 + * stack to another, it's never valid to unwind back to that first 178 + * stack. 179 + */ 180 + if (info->type == state->prev_type) { 181 + if (fp <= state->prev_fp) 182 + return -EINVAL; 183 + } else { 184 + __set_bit(state->prev_type, state->stacks_done); 185 + } 186 + 187 + /* 188 + * Record this frame record's values and location. The prev_fp and 189 + * prev_type are only meaningful to the next unwind_next() invocation. 190 + */ 191 + state->fp = READ_ONCE(*(unsigned long *)(kern_fp)); 192 + state->pc = READ_ONCE(*(unsigned long *)(kern_fp + 8)); 193 + state->prev_fp = fp; 194 + state->prev_type = info->type; 195 + 196 + return 0; 197 + } 198 + 199 + #endif /* __ASM_STACKTRACE_COMMON_H */
+55
arch/arm64/include/asm/stacktrace/nvhe.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * KVM nVHE hypervisor stack tracing support. 4 + * 5 + * The unwinder implementation depends on the nVHE mode: 6 + * 7 + * 1) Non-protected nVHE mode - the host can directly access the 8 + * HYP stack pages and unwind the HYP stack in EL1. This saves having 9 + * to allocate shared buffers for the host to read the unwinded 10 + * stacktrace. 11 + * 12 + * 2) pKVM (protected nVHE) mode - the host cannot directly access 13 + * the HYP memory. The stack is unwinded in EL2 and dumped to a shared 14 + * buffer where the host can read and print the stacktrace. 15 + * 16 + * Copyright (C) 2022 Google LLC 17 + */ 18 + #ifndef __ASM_STACKTRACE_NVHE_H 19 + #define __ASM_STACKTRACE_NVHE_H 20 + 21 + #include <asm/stacktrace/common.h> 22 + 23 + /* 24 + * kvm_nvhe_unwind_init - Start an unwind from the given nVHE HYP fp and pc 25 + * 26 + * @state : unwind_state to initialize 27 + * @fp : frame pointer at which to start the unwinding. 28 + * @pc : program counter at which to start the unwinding. 29 + */ 30 + static inline void kvm_nvhe_unwind_init(struct unwind_state *state, 31 + unsigned long fp, 32 + unsigned long pc) 33 + { 34 + unwind_init_common(state, NULL); 35 + 36 + state->fp = fp; 37 + state->pc = pc; 38 + } 39 + 40 + #ifndef __KVM_NVHE_HYPERVISOR__ 41 + /* 42 + * Conventional (non-protected) nVHE HYP stack unwinder 43 + * 44 + * In non-protected mode, the unwinding is done from kernel proper context 45 + * (by the host in EL1). 46 + */ 47 + 48 + DECLARE_KVM_NVHE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack); 49 + DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_info); 50 + DECLARE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); 51 + 52 + void kvm_nvhe_dump_backtrace(unsigned long hyp_offset); 53 + 54 + #endif /* __KVM_NVHE_HYPERVISOR__ */ 55 + #endif /* __ASM_STACKTRACE_NVHE_H */
+5
arch/arm64/kernel/Makefile
··· 14 14 CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong 15 15 CFLAGS_syscall.o += -fno-stack-protector 16 16 17 + # When KASAN is enabled, a stack trace is recorded for every alloc/free, which 18 + # can significantly impact performance. Avoid instrumenting the stack trace 19 + # collection code to minimize this impact. 20 + KASAN_SANITIZE_stacktrace.o := n 21 + 17 22 # It's not safe to invoke KCOV when portions of the kernel environment aren't 18 23 # available or are out-of-sync with HW state. Since `noinstr` doesn't always 19 24 # inhibit KCOV instrumentation, disable it for the entire compilation unit.
+86 -102
arch/arm64/kernel/stacktrace.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/export.h> 9 9 #include <linux/ftrace.h> 10 - #include <linux/kprobes.h> 11 10 #include <linux/sched.h> 12 11 #include <linux/sched/debug.h> 13 12 #include <linux/sched/task_stack.h> 14 13 #include <linux/stacktrace.h> 15 14 16 15 #include <asm/irq.h> 17 - #include <asm/pointer_auth.h> 18 16 #include <asm/stack_pointer.h> 19 17 #include <asm/stacktrace.h> 20 18 21 19 /* 22 - * A snapshot of a frame record or fp/lr register values, along with some 23 - * accounting information necessary for robust unwinding. 20 + * Start an unwind from a pt_regs. 24 21 * 25 - * @fp: The fp value in the frame record (or the real fp) 26 - * @pc: The lr value in the frame record (or the real lr) 22 + * The unwind will begin at the PC within the regs. 27 23 * 28 - * @stacks_done: Stacks which have been entirely unwound, for which it is no 29 - * longer valid to unwind to. 30 - * 31 - * @prev_fp: The fp that pointed to this frame record, or a synthetic value 32 - * of 0. This is used to ensure that within a stack, each 33 - * subsequent frame record is at an increasing address. 34 - * @prev_type: The type of stack this frame record was on, or a synthetic 35 - * value of STACK_TYPE_UNKNOWN. This is used to detect a 36 - * transition from one stack to another. 37 - * 38 - * @kr_cur: When KRETPROBES is selected, holds the kretprobe instance 39 - * associated with the most recently encountered replacement lr 40 - * value. 24 + * The regs must be on a stack currently owned by the calling task. 41 25 */ 42 - struct unwind_state { 43 - unsigned long fp; 44 - unsigned long pc; 45 - DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES); 46 - unsigned long prev_fp; 47 - enum stack_type prev_type; 48 - #ifdef CONFIG_KRETPROBES 49 - struct llist_node *kr_cur; 50 - #endif 51 - }; 52 - 53 - static notrace void unwind_init(struct unwind_state *state, unsigned long fp, 54 - unsigned long pc) 26 + static inline void unwind_init_from_regs(struct unwind_state *state, 27 + struct pt_regs *regs) 55 28 { 56 - state->fp = fp; 57 - state->pc = pc; 58 - #ifdef CONFIG_KRETPROBES 59 - state->kr_cur = NULL; 60 - #endif 29 + unwind_init_common(state, current); 61 30 62 - /* 63 - * Prime the first unwind. 64 - * 65 - * In unwind_next() we'll check that the FP points to a valid stack, 66 - * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be 67 - * treated as a transition to whichever stack that happens to be. The 68 - * prev_fp value won't be used, but we set it to 0 such that it is 69 - * definitely not an accessible stack address. 70 - */ 71 - bitmap_zero(state->stacks_done, __NR_STACK_TYPES); 72 - state->prev_fp = 0; 73 - state->prev_type = STACK_TYPE_UNKNOWN; 31 + state->fp = regs->regs[29]; 32 + state->pc = regs->pc; 74 33 } 75 - NOKPROBE_SYMBOL(unwind_init); 34 + 35 + /* 36 + * Start an unwind from a caller. 37 + * 38 + * The unwind will begin at the caller of whichever function this is inlined 39 + * into. 40 + * 41 + * The function which invokes this must be noinline. 42 + */ 43 + static __always_inline void unwind_init_from_caller(struct unwind_state *state) 44 + { 45 + unwind_init_common(state, current); 46 + 47 + state->fp = (unsigned long)__builtin_frame_address(1); 48 + state->pc = (unsigned long)__builtin_return_address(0); 49 + } 50 + 51 + /* 52 + * Start an unwind from a blocked task. 53 + * 54 + * The unwind will begin at the blocked tasks saved PC (i.e. the caller of 55 + * cpu_switch_to()). 56 + * 57 + * The caller should ensure the task is blocked in cpu_switch_to() for the 58 + * duration of the unwind, or the unwind will be bogus. It is never valid to 59 + * call this for the current task. 60 + */ 61 + static inline void unwind_init_from_task(struct unwind_state *state, 62 + struct task_struct *task) 63 + { 64 + unwind_init_common(state, task); 65 + 66 + state->fp = thread_saved_fp(task); 67 + state->pc = thread_saved_pc(task); 68 + } 69 + 70 + /* 71 + * We can only safely access per-cpu stacks from current in a non-preemptible 72 + * context. 73 + */ 74 + static bool on_accessible_stack(const struct task_struct *tsk, 75 + unsigned long sp, unsigned long size, 76 + struct stack_info *info) 77 + { 78 + if (info) 79 + info->type = STACK_TYPE_UNKNOWN; 80 + 81 + if (on_task_stack(tsk, sp, size, info)) 82 + return true; 83 + if (tsk != current || preemptible()) 84 + return false; 85 + if (on_irq_stack(sp, size, info)) 86 + return true; 87 + if (on_overflow_stack(sp, size, info)) 88 + return true; 89 + if (on_sdei_stack(sp, size, info)) 90 + return true; 91 + 92 + return false; 93 + } 76 94 77 95 /* 78 96 * Unwind from one frame record (A) to the next frame record (B). ··· 99 81 * records (e.g. a cycle), determined based on the location and fp value of A 100 82 * and the location (but not the fp value) of B. 101 83 */ 102 - static int notrace unwind_next(struct task_struct *tsk, 103 - struct unwind_state *state) 84 + static int notrace unwind_next(struct unwind_state *state) 104 85 { 86 + struct task_struct *tsk = state->task; 105 87 unsigned long fp = state->fp; 106 88 struct stack_info info; 89 + int err; 107 90 108 91 /* Final frame; nothing to unwind */ 109 92 if (fp == (unsigned long)task_pt_regs(tsk)->stackframe) 110 93 return -ENOENT; 111 94 112 - if (fp & 0x7) 113 - return -EINVAL; 114 - 115 - if (!on_accessible_stack(tsk, fp, 16, &info)) 116 - return -EINVAL; 117 - 118 - if (test_bit(info.type, state->stacks_done)) 119 - return -EINVAL; 120 - 121 - /* 122 - * As stacks grow downward, any valid record on the same stack must be 123 - * at a strictly higher address than the prior record. 124 - * 125 - * Stacks can nest in several valid orders, e.g. 126 - * 127 - * TASK -> IRQ -> OVERFLOW -> SDEI_NORMAL 128 - * TASK -> SDEI_NORMAL -> SDEI_CRITICAL -> OVERFLOW 129 - * 130 - * ... but the nesting itself is strict. Once we transition from one 131 - * stack to another, it's never valid to unwind back to that first 132 - * stack. 133 - */ 134 - if (info.type == state->prev_type) { 135 - if (fp <= state->prev_fp) 136 - return -EINVAL; 137 - } else { 138 - set_bit(state->prev_type, state->stacks_done); 139 - } 140 - 141 - /* 142 - * Record this frame record's values and location. The prev_fp and 143 - * prev_type are only meaningful to the next unwind_next() invocation. 144 - */ 145 - state->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); 146 - state->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); 147 - state->prev_fp = fp; 148 - state->prev_type = info.type; 95 + err = unwind_next_common(state, &info, on_accessible_stack, NULL); 96 + if (err) 97 + return err; 149 98 150 99 state->pc = ptrauth_strip_insn_pac(state->pc); 151 100 ··· 142 157 } 143 158 NOKPROBE_SYMBOL(unwind_next); 144 159 145 - static void notrace unwind(struct task_struct *tsk, 146 - struct unwind_state *state, 160 + static void notrace unwind(struct unwind_state *state, 147 161 stack_trace_consume_fn consume_entry, void *cookie) 148 162 { 149 163 while (1) { ··· 150 166 151 167 if (!consume_entry(cookie, state->pc)) 152 168 break; 153 - ret = unwind_next(tsk, state); 169 + ret = unwind_next(state); 154 170 if (ret < 0) 155 171 break; 156 172 } ··· 196 212 { 197 213 struct unwind_state state; 198 214 199 - if (regs) 200 - unwind_init(&state, regs->regs[29], regs->pc); 201 - else if (task == current) 202 - unwind_init(&state, 203 - (unsigned long)__builtin_frame_address(1), 204 - (unsigned long)__builtin_return_address(0)); 205 - else 206 - unwind_init(&state, thread_saved_fp(task), 207 - thread_saved_pc(task)); 215 + if (regs) { 216 + if (task != current) 217 + return; 218 + unwind_init_from_regs(&state, regs); 219 + } else if (task == current) { 220 + unwind_init_from_caller(&state); 221 + } else { 222 + unwind_init_from_task(&state, task); 223 + } 208 224 209 - unwind(task, &state, consume_entry, cookie); 225 + unwind(&state, consume_entry, cookie); 210 226 }
+13
arch/arm64/kvm/Kconfig
··· 56 56 57 57 If unsure, say N. 58 58 59 + config PROTECTED_NVHE_STACKTRACE 60 + bool "Protected KVM hypervisor stacktraces" 61 + depends on NVHE_EL2_DEBUG 62 + default n 63 + help 64 + Say Y here to enable pKVM hypervisor stacktraces on hyp_panic() 65 + 66 + If using protected nVHE mode, but cannot afford the associated 67 + memory cost (less than 0.75 page per CPU) of pKVM stacktraces, 68 + say N. 69 + 70 + If unsure, or not using protected nVHE (pKVM), say N. 71 + 59 72 endif # VIRTUALIZATION
+1 -1
arch/arm64/kvm/Makefile
··· 12 12 13 13 kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \ 14 14 inject_fault.o va_layout.o handle_exit.o \ 15 - guest.o debug.o reset.o sys_regs.o \ 15 + guest.o debug.o reset.o sys_regs.o stacktrace.o \ 16 16 vgic-sys-reg-v3.o fpsimd.o pkvm.o \ 17 17 arch_timer.o trng.o vmid.o \ 18 18 vgic/vgic.o vgic/vgic-init.o \
+1 -1
arch/arm64/kvm/arch_timer.c
··· 242 242 static bool vcpu_has_wfit_active(struct kvm_vcpu *vcpu) 243 243 { 244 244 return (cpus_have_final_cap(ARM64_HAS_WFXT) && 245 - (vcpu->arch.flags & KVM_ARM64_WFIT)); 245 + vcpu_get_flag(vcpu, IN_WFIT)); 246 246 } 247 247 248 248 static u64 wfit_delay_ns(struct kvm_vcpu *vcpu)
+12 -13
arch/arm64/kvm/arm.c
··· 49 49 50 50 DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector); 51 51 52 - static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); 52 + DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page); 53 53 unsigned long kvm_arm_hyp_percpu_base[NR_CPUS]; 54 54 DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); 55 55 ··· 329 329 bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); 330 330 331 331 vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO; 332 + 333 + /* 334 + * Default value for the FP state, will be overloaded at load 335 + * time if we support FP (pretty likely) 336 + */ 337 + vcpu->arch.fp_state = FP_STATE_FREE; 332 338 333 339 /* Set up the timer */ 334 340 kvm_timer_vcpu_init(vcpu); ··· 665 659 preempt_enable(); 666 660 667 661 kvm_vcpu_halt(vcpu); 668 - vcpu->arch.flags &= ~KVM_ARM64_WFIT; 662 + vcpu_clear_flag(vcpu, IN_WFIT); 669 663 kvm_clear_request(KVM_REQ_UNHALT, vcpu); 670 664 671 665 preempt_disable(); ··· 1021 1015 * the vcpu state. Note that this relies on __kvm_adjust_pc() 1022 1016 * being preempt-safe on VHE. 1023 1017 */ 1024 - if (unlikely(vcpu->arch.flags & (KVM_ARM64_PENDING_EXCEPTION | 1025 - KVM_ARM64_INCREMENT_PC))) 1018 + if (unlikely(vcpu_get_flag(vcpu, PENDING_EXCEPTION) || 1019 + vcpu_get_flag(vcpu, INCREMENT_PC))) 1026 1020 kvm_call_hyp(__kvm_adjust_pc, vcpu); 1027 1021 1028 1022 vcpu_put(vcpu); ··· 1420 1414 static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, 1421 1415 struct kvm_arm_device_addr *dev_addr) 1422 1416 { 1423 - unsigned long dev_id, type; 1424 - 1425 - dev_id = (dev_addr->id & KVM_ARM_DEVICE_ID_MASK) >> 1426 - KVM_ARM_DEVICE_ID_SHIFT; 1427 - type = (dev_addr->id & KVM_ARM_DEVICE_TYPE_MASK) >> 1428 - KVM_ARM_DEVICE_TYPE_SHIFT; 1429 - 1430 - switch (dev_id) { 1417 + switch (FIELD_GET(KVM_ARM_DEVICE_ID_MASK, dev_addr->id)) { 1431 1418 case KVM_ARM_DEVICE_VGIC_V2: 1432 1419 if (!vgic_present) 1433 1420 return -ENXIO; 1434 - return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); 1421 + return kvm_set_legacy_vgic_v2_addr(kvm, dev_addr); 1435 1422 default: 1436 1423 return -ENODEV; 1437 1424 }
+12 -13
arch/arm64/kvm/debug.c
··· 104 104 * Trap debug register access when one of the following is true: 105 105 * - Userspace is using the hardware to debug the guest 106 106 * (KVM_GUESTDBG_USE_HW is set). 107 - * - The guest is not using debug (KVM_ARM64_DEBUG_DIRTY is clear). 107 + * - The guest is not using debug (DEBUG_DIRTY clear). 108 108 * - The guest has enabled the OS Lock (debug exceptions are blocked). 109 109 */ 110 110 if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) || 111 - !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY) || 111 + !vcpu_get_flag(vcpu, DEBUG_DIRTY) || 112 112 kvm_vcpu_os_lock_enabled(vcpu)) 113 113 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 114 114 ··· 147 147 * debug related registers. 148 148 * 149 149 * Additionally, KVM only traps guest accesses to the debug registers if 150 - * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY 151 - * flag on vcpu->arch.flags). Since the guest must not interfere 150 + * the guest is not actively using them (see the DEBUG_DIRTY 151 + * flag on vcpu->arch.iflags). Since the guest must not interfere 152 152 * with the hardware state when debugging the guest, we must ensure that 153 153 * trapping is enabled whenever we are debugging the guest using the 154 154 * debug registers. ··· 205 205 * 206 206 * We simply switch the debug_ptr to point to our new 207 207 * external_debug_state which has been populated by the 208 - * debug ioctl. The existing KVM_ARM64_DEBUG_DIRTY 209 - * mechanism ensures the registers are updated on the 210 - * world switch. 208 + * debug ioctl. The existing DEBUG_DIRTY mechanism ensures 209 + * the registers are updated on the world switch. 211 210 */ 212 211 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 213 212 /* Enable breakpoints/watchpoints */ ··· 215 216 vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 216 217 217 218 vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; 218 - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 219 + vcpu_set_flag(vcpu, DEBUG_DIRTY); 219 220 220 221 trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 221 222 &vcpu->arch.debug_ptr->dbg_bcr[0], ··· 245 246 246 247 /* If KDE or MDE are set, perform a full save/restore cycle. */ 247 248 if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) 248 - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 249 + vcpu_set_flag(vcpu, DEBUG_DIRTY); 249 250 250 251 /* Write mdcr_el2 changes since vcpu_load on VHE systems */ 251 252 if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) ··· 297 298 */ 298 299 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) && 299 300 !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT))) 300 - vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_SPE; 301 + vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE); 301 302 302 303 /* Check if we have TRBE implemented and available at the host */ 303 304 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRBE_SHIFT) && 304 305 !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG)) 305 - vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_TRBE; 306 + vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 306 307 } 307 308 308 309 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) 309 310 { 310 - vcpu->arch.flags &= ~(KVM_ARM64_DEBUG_STATE_SAVE_SPE | 311 - KVM_ARM64_DEBUG_STATE_SAVE_TRBE); 311 + vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE); 312 + vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 312 313 }
+20 -19
arch/arm64/kvm/fpsimd.c
··· 77 77 BUG_ON(!current->mm); 78 78 BUG_ON(test_thread_flag(TIF_SVE)); 79 79 80 - vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED; 81 - vcpu->arch.flags |= KVM_ARM64_FP_HOST; 80 + if (!system_supports_fpsimd()) 81 + return; 82 82 83 - vcpu->arch.flags &= ~KVM_ARM64_HOST_SVE_ENABLED; 83 + vcpu->arch.fp_state = FP_STATE_HOST_OWNED; 84 + 85 + vcpu_clear_flag(vcpu, HOST_SVE_ENABLED); 84 86 if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN) 85 - vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED; 87 + vcpu_set_flag(vcpu, HOST_SVE_ENABLED); 86 88 87 89 /* 88 90 * We don't currently support SME guests but if we leave ··· 96 94 * operations. Do this for ZA as well for now for simplicity. 97 95 */ 98 96 if (system_supports_sme()) { 99 - vcpu->arch.flags &= ~KVM_ARM64_HOST_SME_ENABLED; 97 + vcpu_clear_flag(vcpu, HOST_SME_ENABLED); 100 98 if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN) 101 - vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED; 99 + vcpu_set_flag(vcpu, HOST_SME_ENABLED); 102 100 103 - if (read_sysreg_s(SYS_SVCR) & 104 - (SVCR_SM_MASK | SVCR_ZA_MASK)) { 105 - vcpu->arch.flags &= ~KVM_ARM64_FP_HOST; 101 + if (read_sysreg_s(SYS_SVCR) & (SVCR_SM_MASK | SVCR_ZA_MASK)) { 102 + vcpu->arch.fp_state = FP_STATE_FREE; 106 103 fpsimd_save_and_flush_cpu_state(); 107 104 } 108 105 } 109 106 } 110 107 111 108 /* 112 - * Called just before entering the guest once we are no longer 113 - * preemptable. Syncs the host's TIF_FOREIGN_FPSTATE with the KVM 114 - * mirror of the flag used by the hypervisor. 109 + * Called just before entering the guest once we are no longer preemptable 110 + * and interrupts are disabled. If we have managed to run anything using 111 + * FP while we were preemptible (such as off the back of an interrupt), 112 + * then neither the host nor the guest own the FP hardware (and it was the 113 + * responsibility of the code that used FP to save the existing state). 115 114 */ 116 115 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu) 117 116 { 118 117 if (test_thread_flag(TIF_FOREIGN_FPSTATE)) 119 - vcpu->arch.flags |= KVM_ARM64_FP_FOREIGN_FPSTATE; 120 - else 121 - vcpu->arch.flags &= ~KVM_ARM64_FP_FOREIGN_FPSTATE; 118 + vcpu->arch.fp_state = FP_STATE_FREE; 122 119 } 123 120 124 121 /* ··· 131 130 { 132 131 WARN_ON_ONCE(!irqs_disabled()); 133 132 134 - if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) { 133 + if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) { 135 134 /* 136 135 * Currently we do not support SME guests so SVCR is 137 136 * always 0 and we just need a variable to point to. ··· 164 163 */ 165 164 if (has_vhe() && system_supports_sme()) { 166 165 /* Also restore EL0 state seen on entry */ 167 - if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED) 166 + if (vcpu_get_flag(vcpu, HOST_SME_ENABLED)) 168 167 sysreg_clear_set(CPACR_EL1, 0, 169 168 CPACR_EL1_SMEN_EL0EN | 170 169 CPACR_EL1_SMEN_EL1EN); ··· 174 173 CPACR_EL1_SMEN_EL1EN); 175 174 } 176 175 177 - if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) { 176 + if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) { 178 177 if (vcpu_has_sve(vcpu)) { 179 178 __vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR); 180 179 ··· 193 192 * for EL0. To avoid spurious traps, restore the trap state 194 193 * seen by kvm_arch_vcpu_load_fp(): 195 194 */ 196 - if (vcpu->arch.flags & KVM_ARM64_HOST_SVE_ENABLED) 195 + if (vcpu_get_flag(vcpu, HOST_SVE_ENABLED)) 197 196 sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_ZEN_EL0EN); 198 197 else 199 198 sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
+7 -3
arch/arm64/kvm/handle_exit.c
··· 17 17 #include <asm/kvm_emulate.h> 18 18 #include <asm/kvm_mmu.h> 19 19 #include <asm/debug-monitors.h> 20 + #include <asm/stacktrace/nvhe.h> 20 21 #include <asm/traps.h> 21 22 22 23 #include <kvm/arm_hypercalls.h> ··· 121 120 kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu)); 122 121 } else { 123 122 if (esr & ESR_ELx_WFx_ISS_WFxT) 124 - vcpu->arch.flags |= KVM_ARM64_WFIT; 123 + vcpu_set_flag(vcpu, IN_WFIT); 125 124 126 125 kvm_vcpu_wfi(vcpu); 127 126 } ··· 348 347 kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); 349 348 else 350 349 kvm_err("nVHE hyp BUG at: [<%016llx>] %pB!\n", panic_addr, 351 - (void *)panic_addr); 350 + (void *)(panic_addr + kaslr_offset())); 352 351 } else { 353 352 kvm_err("nVHE hyp panic at: [<%016llx>] %pB!\n", panic_addr, 354 - (void *)panic_addr); 353 + (void *)(panic_addr + kaslr_offset())); 355 354 } 355 + 356 + /* Dump the nVHE hypervisor backtrace */ 357 + kvm_nvhe_dump_backtrace(hyp_offset); 356 358 357 359 /* 358 360 * Hyp has panicked and we're going to handle that by panicking the
+11 -12
arch/arm64/kvm/hyp/exception.c
··· 303 303 static void kvm_inject_exception(struct kvm_vcpu *vcpu) 304 304 { 305 305 if (vcpu_el1_is_32bit(vcpu)) { 306 - switch (vcpu->arch.flags & KVM_ARM64_EXCEPT_MASK) { 307 - case KVM_ARM64_EXCEPT_AA32_UND: 306 + switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) { 307 + case unpack_vcpu_flag(EXCEPT_AA32_UND): 308 308 enter_exception32(vcpu, PSR_AA32_MODE_UND, 4); 309 309 break; 310 - case KVM_ARM64_EXCEPT_AA32_IABT: 310 + case unpack_vcpu_flag(EXCEPT_AA32_IABT): 311 311 enter_exception32(vcpu, PSR_AA32_MODE_ABT, 12); 312 312 break; 313 - case KVM_ARM64_EXCEPT_AA32_DABT: 313 + case unpack_vcpu_flag(EXCEPT_AA32_DABT): 314 314 enter_exception32(vcpu, PSR_AA32_MODE_ABT, 16); 315 315 break; 316 316 default: ··· 318 318 break; 319 319 } 320 320 } else { 321 - switch (vcpu->arch.flags & KVM_ARM64_EXCEPT_MASK) { 322 - case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC | 323 - KVM_ARM64_EXCEPT_AA64_EL1): 321 + switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) { 322 + case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC): 324 323 enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync); 325 324 break; 326 325 default: ··· 339 340 */ 340 341 void __kvm_adjust_pc(struct kvm_vcpu *vcpu) 341 342 { 342 - if (vcpu->arch.flags & KVM_ARM64_PENDING_EXCEPTION) { 343 + if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) { 343 344 kvm_inject_exception(vcpu); 344 - vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION | 345 - KVM_ARM64_EXCEPT_MASK); 346 - } else if (vcpu->arch.flags & KVM_ARM64_INCREMENT_PC) { 345 + vcpu_clear_flag(vcpu, PENDING_EXCEPTION); 346 + vcpu_clear_flag(vcpu, EXCEPT_MASK); 347 + } else if (vcpu_get_flag(vcpu, INCREMENT_PC)) { 347 348 kvm_skip_instr(vcpu); 348 - vcpu->arch.flags &= ~KVM_ARM64_INCREMENT_PC; 349 + vcpu_clear_flag(vcpu, INCREMENT_PC); 349 350 } 350 351 }
+3 -3
arch/arm64/kvm/hyp/include/hyp/debug-sr.h
··· 132 132 struct kvm_guest_debug_arch *host_dbg; 133 133 struct kvm_guest_debug_arch *guest_dbg; 134 134 135 - if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) 135 + if (!vcpu_get_flag(vcpu, DEBUG_DIRTY)) 136 136 return; 137 137 138 138 host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; ··· 151 151 struct kvm_guest_debug_arch *host_dbg; 152 152 struct kvm_guest_debug_arch *guest_dbg; 153 153 154 - if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) 154 + if (!vcpu_get_flag(vcpu, DEBUG_DIRTY)) 155 155 return; 156 156 157 157 host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; ··· 162 162 __debug_save_state(guest_dbg, guest_ctxt); 163 163 __debug_restore_state(host_dbg, host_ctxt); 164 164 165 - vcpu->arch.flags &= ~KVM_ARM64_DEBUG_DIRTY; 165 + vcpu_clear_flag(vcpu, DEBUG_DIRTY); 166 166 } 167 167 168 168 #endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
+5 -19
arch/arm64/kvm/hyp/include/hyp/switch.h
··· 37 37 extern struct kvm_exception_table_entry __start___kvm_ex_table; 38 38 extern struct kvm_exception_table_entry __stop___kvm_ex_table; 39 39 40 - /* Check whether the FP regs were dirtied while in the host-side run loop: */ 41 - static inline bool update_fp_enabled(struct kvm_vcpu *vcpu) 40 + /* Check whether the FP regs are owned by the guest */ 41 + static inline bool guest_owns_fp_regs(struct kvm_vcpu *vcpu) 42 42 { 43 - /* 44 - * When the system doesn't support FP/SIMD, we cannot rely on 45 - * the _TIF_FOREIGN_FPSTATE flag. However, we always inject an 46 - * abort on the very first access to FP and thus we should never 47 - * see KVM_ARM64_FP_ENABLED. For added safety, make sure we always 48 - * trap the accesses. 49 - */ 50 - if (!system_supports_fpsimd() || 51 - vcpu->arch.flags & KVM_ARM64_FP_FOREIGN_FPSTATE) 52 - vcpu->arch.flags &= ~(KVM_ARM64_FP_ENABLED | 53 - KVM_ARM64_FP_HOST); 54 - 55 - return !!(vcpu->arch.flags & KVM_ARM64_FP_ENABLED); 43 + return vcpu->arch.fp_state == FP_STATE_GUEST_OWNED; 56 44 } 57 45 58 46 /* Save the 32-bit only FPSIMD system register state */ ··· 179 191 isb(); 180 192 181 193 /* Write out the host state if it's in the registers */ 182 - if (vcpu->arch.flags & KVM_ARM64_FP_HOST) { 194 + if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED) 183 195 __fpsimd_save_state(vcpu->arch.host_fpsimd_state); 184 - vcpu->arch.flags &= ~KVM_ARM64_FP_HOST; 185 - } 186 196 187 197 /* Restore the guest state */ 188 198 if (sve_guest) ··· 192 206 if (!(read_sysreg(hcr_el2) & HCR_RW)) 193 207 write_sysreg(__vcpu_sys_reg(vcpu, FPEXC32_EL2), fpexc32_el2); 194 208 195 - vcpu->arch.flags |= KVM_ARM64_FP_ENABLED; 209 + vcpu->arch.fp_state = FP_STATE_GUEST_OWNED; 196 210 197 211 return true; 198 212 }
+2 -2
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
··· 195 195 __vcpu_sys_reg(vcpu, DACR32_EL2) = read_sysreg(dacr32_el2); 196 196 __vcpu_sys_reg(vcpu, IFSR32_EL2) = read_sysreg(ifsr32_el2); 197 197 198 - if (has_vhe() || vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY) 198 + if (has_vhe() || vcpu_get_flag(vcpu, DEBUG_DIRTY)) 199 199 __vcpu_sys_reg(vcpu, DBGVCR32_EL2) = read_sysreg(dbgvcr32_el2); 200 200 } 201 201 ··· 212 212 write_sysreg(__vcpu_sys_reg(vcpu, DACR32_EL2), dacr32_el2); 213 213 write_sysreg(__vcpu_sys_reg(vcpu, IFSR32_EL2), ifsr32_el2); 214 214 215 - if (has_vhe() || vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY) 215 + if (has_vhe() || vcpu_get_flag(vcpu, DEBUG_DIRTY)) 216 216 write_sysreg(__vcpu_sys_reg(vcpu, DBGVCR32_EL2), dbgvcr32_el2); 217 217 } 218 218
+7 -7
arch/arm64/kvm/hyp/nvhe/Makefile
··· 12 12 lib-objs := clear_page.o copy_page.o memcpy.o memset.o 13 13 lib-objs := $(addprefix ../../../lib/, $(lib-objs)) 14 14 15 - obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \ 15 + hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \ 16 16 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o page_alloc.o \ 17 - cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o 18 - obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ 17 + cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o 18 + hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ 19 19 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o 20 - obj-$(CONFIG_DEBUG_LIST) += list_debug.o 21 - obj-y += $(lib-objs) 20 + hyp-obj-$(CONFIG_DEBUG_LIST) += list_debug.o 21 + hyp-obj-y += $(lib-objs) 22 22 23 23 ## 24 24 ## Build rules for compiling nVHE hyp code ··· 26 26 ## file containing all nVHE hyp code and data. 27 27 ## 28 28 29 - hyp-obj := $(patsubst %.o,%.nvhe.o,$(obj-y)) 29 + hyp-obj := $(patsubst %.o,%.nvhe.o,$(hyp-obj-y)) 30 30 obj-y := kvm_nvhe.o 31 - extra-y := $(hyp-obj) kvm_nvhe.tmp.o kvm_nvhe.rel.o hyp.lds hyp-reloc.S hyp-reloc.o 31 + targets += $(hyp-obj) kvm_nvhe.tmp.o kvm_nvhe.rel.o hyp.lds hyp-reloc.S hyp-reloc.o 32 32 33 33 # 1) Compile all source files to `.nvhe.o` object files. The file extension 34 34 # avoids file name clashes for files shared with VHE.
+4 -4
arch/arm64/kvm/hyp/nvhe/debug-sr.c
··· 84 84 void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) 85 85 { 86 86 /* Disable and flush SPE data generation */ 87 - if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) 87 + if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE)) 88 88 __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); 89 89 /* Disable and flush Self-Hosted Trace generation */ 90 - if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) 90 + if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE)) 91 91 __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); 92 92 } 93 93 ··· 98 98 99 99 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) 100 100 { 101 - if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) 101 + if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE)) 102 102 __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); 103 - if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) 103 + if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE)) 104 104 __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); 105 105 } 106 106
+2 -7
arch/arm64/kvm/hyp/nvhe/host.S
··· 177 177 b hyp_panic 178 178 179 179 .L__hyp_sp_overflow\@: 180 - /* 181 - * Reset SP to the top of the stack, to allow handling the hyp_panic. 182 - * This corrupts the stack but is ok, since we won't be attempting 183 - * any unwinding here. 184 - */ 185 - ldr_this_cpu x0, kvm_init_params + NVHE_INIT_STACK_HYP_VA, x1 186 - mov sp, x0 180 + /* Switch to the overflow stack */ 181 + adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0 187 182 188 183 b hyp_panic_bad_stack 189 184 ASM_BUG()
+160
arch/arm64/kvm/hyp/nvhe/stacktrace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * KVM nVHE hypervisor stack tracing support. 4 + * 5 + * Copyright (C) 2022 Google LLC 6 + */ 7 + #include <asm/kvm_asm.h> 8 + #include <asm/kvm_hyp.h> 9 + #include <asm/memory.h> 10 + #include <asm/percpu.h> 11 + 12 + DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack) 13 + __aligned(16); 14 + 15 + DEFINE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_info); 16 + 17 + /* 18 + * hyp_prepare_backtrace - Prepare non-protected nVHE backtrace. 19 + * 20 + * @fp : frame pointer at which to start the unwinding. 21 + * @pc : program counter at which to start the unwinding. 22 + * 23 + * Save the information needed by the host to unwind the non-protected 24 + * nVHE hypervisor stack in EL1. 25 + */ 26 + static void hyp_prepare_backtrace(unsigned long fp, unsigned long pc) 27 + { 28 + struct kvm_nvhe_stacktrace_info *stacktrace_info = this_cpu_ptr(&kvm_stacktrace_info); 29 + struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params); 30 + 31 + stacktrace_info->stack_base = (unsigned long)(params->stack_hyp_va - PAGE_SIZE); 32 + stacktrace_info->overflow_stack_base = (unsigned long)this_cpu_ptr(overflow_stack); 33 + stacktrace_info->fp = fp; 34 + stacktrace_info->pc = pc; 35 + } 36 + 37 + #ifdef CONFIG_PROTECTED_NVHE_STACKTRACE 38 + #include <asm/stacktrace/nvhe.h> 39 + 40 + DEFINE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], pkvm_stacktrace); 41 + 42 + static bool on_overflow_stack(unsigned long sp, unsigned long size, 43 + struct stack_info *info) 44 + { 45 + unsigned long low = (unsigned long)this_cpu_ptr(overflow_stack); 46 + unsigned long high = low + OVERFLOW_STACK_SIZE; 47 + 48 + return on_stack(sp, size, low, high, STACK_TYPE_OVERFLOW, info); 49 + } 50 + 51 + static bool on_hyp_stack(unsigned long sp, unsigned long size, 52 + struct stack_info *info) 53 + { 54 + struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params); 55 + unsigned long high = params->stack_hyp_va; 56 + unsigned long low = high - PAGE_SIZE; 57 + 58 + return on_stack(sp, size, low, high, STACK_TYPE_HYP, info); 59 + } 60 + 61 + static bool on_accessible_stack(const struct task_struct *tsk, 62 + unsigned long sp, unsigned long size, 63 + struct stack_info *info) 64 + { 65 + if (info) 66 + info->type = STACK_TYPE_UNKNOWN; 67 + 68 + return (on_overflow_stack(sp, size, info) || 69 + on_hyp_stack(sp, size, info)); 70 + } 71 + 72 + static int unwind_next(struct unwind_state *state) 73 + { 74 + struct stack_info info; 75 + 76 + return unwind_next_common(state, &info, on_accessible_stack, NULL); 77 + } 78 + 79 + static void notrace unwind(struct unwind_state *state, 80 + stack_trace_consume_fn consume_entry, 81 + void *cookie) 82 + { 83 + while (1) { 84 + int ret; 85 + 86 + if (!consume_entry(cookie, state->pc)) 87 + break; 88 + ret = unwind_next(state); 89 + if (ret < 0) 90 + break; 91 + } 92 + } 93 + 94 + /* 95 + * pkvm_save_backtrace_entry - Saves a protected nVHE HYP stacktrace entry 96 + * 97 + * @arg : index of the entry in the stacktrace buffer 98 + * @where : the program counter corresponding to the stack frame 99 + * 100 + * Save the return address of a stack frame to the shared stacktrace buffer. 101 + * The host can access this shared buffer from EL1 to dump the backtrace. 102 + */ 103 + static bool pkvm_save_backtrace_entry(void *arg, unsigned long where) 104 + { 105 + unsigned long *stacktrace = this_cpu_ptr(pkvm_stacktrace); 106 + int *idx = (int *)arg; 107 + 108 + /* 109 + * Need 2 free slots: 1 for current entry and 1 for the 110 + * delimiter. 111 + */ 112 + if (*idx > ARRAY_SIZE(pkvm_stacktrace) - 2) 113 + return false; 114 + 115 + stacktrace[*idx] = where; 116 + stacktrace[++*idx] = 0UL; 117 + 118 + return true; 119 + } 120 + 121 + /* 122 + * pkvm_save_backtrace - Saves the protected nVHE HYP stacktrace 123 + * 124 + * @fp : frame pointer at which to start the unwinding. 125 + * @pc : program counter at which to start the unwinding. 126 + * 127 + * Save the unwinded stack addresses to the shared stacktrace buffer. 128 + * The host can access this shared buffer from EL1 to dump the backtrace. 129 + */ 130 + static void pkvm_save_backtrace(unsigned long fp, unsigned long pc) 131 + { 132 + struct unwind_state state; 133 + int idx = 0; 134 + 135 + kvm_nvhe_unwind_init(&state, fp, pc); 136 + 137 + unwind(&state, pkvm_save_backtrace_entry, &idx); 138 + } 139 + #else /* !CONFIG_PROTECTED_NVHE_STACKTRACE */ 140 + static void pkvm_save_backtrace(unsigned long fp, unsigned long pc) 141 + { 142 + } 143 + #endif /* CONFIG_PROTECTED_NVHE_STACKTRACE */ 144 + 145 + /* 146 + * kvm_nvhe_prepare_backtrace - prepare to dump the nVHE backtrace 147 + * 148 + * @fp : frame pointer at which to start the unwinding. 149 + * @pc : program counter at which to start the unwinding. 150 + * 151 + * Saves the information needed by the host to dump the nVHE hypervisor 152 + * backtrace. 153 + */ 154 + void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc) 155 + { 156 + if (is_protected_kvm_enabled()) 157 + pkvm_save_backtrace(fp, pc); 158 + else 159 + hyp_prepare_backtrace(fp, pc); 160 + }
+10 -4
arch/arm64/kvm/hyp/nvhe/switch.c
··· 34 34 DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt); 35 35 DEFINE_PER_CPU(unsigned long, kvm_hyp_vector); 36 36 37 + extern void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc); 38 + 37 39 static void __activate_traps(struct kvm_vcpu *vcpu) 38 40 { 39 41 u64 val; ··· 45 43 46 44 val = vcpu->arch.cptr_el2; 47 45 val |= CPTR_EL2_TTA | CPTR_EL2_TAM; 48 - if (!update_fp_enabled(vcpu)) { 46 + if (!guest_owns_fp_regs(vcpu)) { 49 47 val |= CPTR_EL2_TFP | CPTR_EL2_TZ; 50 48 __activate_traps_fpsimd32(vcpu); 51 49 } ··· 125 123 } 126 124 127 125 cptr = CPTR_EL2_DEFAULT; 128 - if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED)) 126 + if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) 129 127 cptr |= CPTR_EL2_TZ; 130 128 if (cpus_have_final_cap(ARM64_SME)) 131 129 cptr &= ~CPTR_EL2_TSM; ··· 337 335 338 336 __sysreg_restore_state_nvhe(host_ctxt); 339 337 340 - if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) 338 + if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) 341 339 __fpsimd_save_fpexc32(vcpu); 342 340 343 341 __debug_switch_to_host(vcpu); ··· 377 375 __sysreg_restore_state_nvhe(host_ctxt); 378 376 } 379 377 378 + /* Prepare to dump kvm nvhe hyp stacktrace */ 379 + kvm_nvhe_prepare_backtrace((unsigned long)__builtin_frame_address(0), 380 + _THIS_IP_); 381 + 380 382 __hyp_do_panic(host_ctxt, spsr, elr, par); 381 383 unreachable(); 382 384 } ··· 392 386 393 387 asmlinkage void kvm_unexpected_el2_exception(void) 394 388 { 395 - return __kvm_unexpected_el2_exception(); 389 + __kvm_unexpected_el2_exception(); 396 390 }
+1 -3
arch/arm64/kvm/hyp/nvhe/sys_regs.c
··· 38 38 *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR); 39 39 *vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR); 40 40 41 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 | 42 - KVM_ARM64_EXCEPT_AA64_ELx_SYNC | 43 - KVM_ARM64_PENDING_EXCEPTION); 41 + kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC); 44 42 45 43 __kvm_adjust_pc(vcpu); 46 44
+3 -3
arch/arm64/kvm/hyp/vhe/switch.c
··· 55 55 56 56 val |= CPTR_EL2_TAM; 57 57 58 - if (update_fp_enabled(vcpu)) { 58 + if (guest_owns_fp_regs(vcpu)) { 59 59 if (vcpu_has_sve(vcpu)) 60 60 val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN; 61 61 } else { ··· 175 175 176 176 sysreg_restore_host_state_vhe(host_ctxt); 177 177 178 - if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) 178 + if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) 179 179 __fpsimd_save_fpexc32(vcpu); 180 180 181 181 __debug_switch_to_host(vcpu); ··· 249 249 250 250 asmlinkage void kvm_unexpected_el2_exception(void) 251 251 { 252 - return __kvm_unexpected_el2_exception(); 252 + __kvm_unexpected_el2_exception(); 253 253 }
+2 -2
arch/arm64/kvm/hyp/vhe/sysreg-sr.c
··· 79 79 __sysreg_restore_user_state(guest_ctxt); 80 80 __sysreg_restore_el1_state(guest_ctxt); 81 81 82 - vcpu->arch.sysregs_loaded_on_cpu = true; 82 + vcpu_set_flag(vcpu, SYSREGS_ON_CPU); 83 83 84 84 activate_traps_vhe_load(vcpu); 85 85 } ··· 110 110 /* Restore host user state */ 111 111 __sysreg_restore_user_state(host_ctxt); 112 112 113 - vcpu->arch.sysregs_loaded_on_cpu = false; 113 + vcpu_clear_flag(vcpu, SYSREGS_ON_CPU); 114 114 }
+5 -12
arch/arm64/kvm/inject_fault.c
··· 20 20 bool is_aarch32 = vcpu_mode_is_32bit(vcpu); 21 21 u64 esr = 0; 22 22 23 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 | 24 - KVM_ARM64_EXCEPT_AA64_ELx_SYNC | 25 - KVM_ARM64_PENDING_EXCEPTION); 23 + kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC); 26 24 27 25 vcpu_write_sys_reg(vcpu, addr, FAR_EL1); 28 26 ··· 50 52 { 51 53 u64 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); 52 54 53 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 | 54 - KVM_ARM64_EXCEPT_AA64_ELx_SYNC | 55 - KVM_ARM64_PENDING_EXCEPTION); 55 + kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC); 56 56 57 57 /* 58 58 * Build an unknown exception, depending on the instruction ··· 69 73 70 74 static void inject_undef32(struct kvm_vcpu *vcpu) 71 75 { 72 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_UND | 73 - KVM_ARM64_PENDING_EXCEPTION); 76 + kvm_pend_exception(vcpu, EXCEPT_AA32_UND); 74 77 } 75 78 76 79 /* ··· 92 97 far = vcpu_read_sys_reg(vcpu, FAR_EL1); 93 98 94 99 if (is_pabt) { 95 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_IABT | 96 - KVM_ARM64_PENDING_EXCEPTION); 100 + kvm_pend_exception(vcpu, EXCEPT_AA32_IABT); 97 101 far &= GENMASK(31, 0); 98 102 far |= (u64)addr << 32; 99 103 vcpu_write_sys_reg(vcpu, fsr, IFSR32_EL2); 100 104 } else { /* !iabt */ 101 - vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA32_DABT | 102 - KVM_ARM64_PENDING_EXCEPTION); 105 + kvm_pend_exception(vcpu, EXCEPT_AA32_DABT); 103 106 far &= GENMASK(63, 32); 104 107 far |= addr; 105 108 vcpu_write_sys_reg(vcpu, fsr, ESR_EL1);
+3 -3
arch/arm64/kvm/reset.c
··· 81 81 * KVM_REG_ARM64_SVE_VLS. Allocation is deferred until 82 82 * kvm_arm_vcpu_finalize(), which freezes the configuration. 83 83 */ 84 - vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_SVE; 84 + vcpu_set_flag(vcpu, GUEST_HAS_SVE); 85 85 86 86 return 0; 87 87 } ··· 120 120 } 121 121 122 122 vcpu->arch.sve_state = buf; 123 - vcpu->arch.flags |= KVM_ARM64_VCPU_SVE_FINALIZED; 123 + vcpu_set_flag(vcpu, VCPU_SVE_FINALIZED); 124 124 return 0; 125 125 } 126 126 ··· 177 177 !system_has_full_ptr_auth()) 178 178 return -EINVAL; 179 179 180 - vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_PTRAUTH; 180 + vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH); 181 181 return 0; 182 182 } 183 183
+218
arch/arm64/kvm/stacktrace.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * KVM nVHE hypervisor stack tracing support. 4 + * 5 + * The unwinder implementation depends on the nVHE mode: 6 + * 7 + * 1) Non-protected nVHE mode - the host can directly access the 8 + * HYP stack pages and unwind the HYP stack in EL1. This saves having 9 + * to allocate shared buffers for the host to read the unwinded 10 + * stacktrace. 11 + * 12 + * 2) pKVM (protected nVHE) mode - the host cannot directly access 13 + * the HYP memory. The stack is unwinded in EL2 and dumped to a shared 14 + * buffer where the host can read and print the stacktrace. 15 + * 16 + * Copyright (C) 2022 Google LLC 17 + */ 18 + 19 + #include <linux/kvm.h> 20 + #include <linux/kvm_host.h> 21 + 22 + #include <asm/stacktrace/nvhe.h> 23 + 24 + /* 25 + * kvm_nvhe_stack_kern_va - Convert KVM nVHE HYP stack addresses to a kernel VAs 26 + * 27 + * The nVHE hypervisor stack is mapped in the flexible 'private' VA range, to 28 + * allow for guard pages below the stack. Consequently, the fixed offset address 29 + * translation macros won't work here. 30 + * 31 + * The kernel VA is calculated as an offset from the kernel VA of the hypervisor 32 + * stack base. 33 + * 34 + * Returns true on success and updates @addr to its corresponding kernel VA; 35 + * otherwise returns false. 36 + */ 37 + static bool kvm_nvhe_stack_kern_va(unsigned long *addr, 38 + enum stack_type type) 39 + { 40 + struct kvm_nvhe_stacktrace_info *stacktrace_info; 41 + unsigned long hyp_base, kern_base, hyp_offset; 42 + 43 + stacktrace_info = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info); 44 + 45 + switch (type) { 46 + case STACK_TYPE_HYP: 47 + kern_base = (unsigned long)*this_cpu_ptr(&kvm_arm_hyp_stack_page); 48 + hyp_base = (unsigned long)stacktrace_info->stack_base; 49 + break; 50 + case STACK_TYPE_OVERFLOW: 51 + kern_base = (unsigned long)this_cpu_ptr_nvhe_sym(overflow_stack); 52 + hyp_base = (unsigned long)stacktrace_info->overflow_stack_base; 53 + break; 54 + default: 55 + return false; 56 + } 57 + 58 + hyp_offset = *addr - hyp_base; 59 + 60 + *addr = kern_base + hyp_offset; 61 + 62 + return true; 63 + } 64 + 65 + static bool on_overflow_stack(unsigned long sp, unsigned long size, 66 + struct stack_info *info) 67 + { 68 + struct kvm_nvhe_stacktrace_info *stacktrace_info 69 + = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info); 70 + unsigned long low = (unsigned long)stacktrace_info->overflow_stack_base; 71 + unsigned long high = low + OVERFLOW_STACK_SIZE; 72 + 73 + return on_stack(sp, size, low, high, STACK_TYPE_OVERFLOW, info); 74 + } 75 + 76 + static bool on_hyp_stack(unsigned long sp, unsigned long size, 77 + struct stack_info *info) 78 + { 79 + struct kvm_nvhe_stacktrace_info *stacktrace_info 80 + = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info); 81 + unsigned long low = (unsigned long)stacktrace_info->stack_base; 82 + unsigned long high = low + PAGE_SIZE; 83 + 84 + return on_stack(sp, size, low, high, STACK_TYPE_HYP, info); 85 + } 86 + 87 + static bool on_accessible_stack(const struct task_struct *tsk, 88 + unsigned long sp, unsigned long size, 89 + struct stack_info *info) 90 + { 91 + if (info) 92 + info->type = STACK_TYPE_UNKNOWN; 93 + 94 + return (on_overflow_stack(sp, size, info) || 95 + on_hyp_stack(sp, size, info)); 96 + } 97 + 98 + static int unwind_next(struct unwind_state *state) 99 + { 100 + struct stack_info info; 101 + 102 + return unwind_next_common(state, &info, on_accessible_stack, 103 + kvm_nvhe_stack_kern_va); 104 + } 105 + 106 + static void unwind(struct unwind_state *state, 107 + stack_trace_consume_fn consume_entry, void *cookie) 108 + { 109 + while (1) { 110 + int ret; 111 + 112 + if (!consume_entry(cookie, state->pc)) 113 + break; 114 + ret = unwind_next(state); 115 + if (ret < 0) 116 + break; 117 + } 118 + } 119 + 120 + /* 121 + * kvm_nvhe_dump_backtrace_entry - Symbolize and print an nVHE backtrace entry 122 + * 123 + * @arg : the hypervisor offset, used for address translation 124 + * @where : the program counter corresponding to the stack frame 125 + */ 126 + static bool kvm_nvhe_dump_backtrace_entry(void *arg, unsigned long where) 127 + { 128 + unsigned long va_mask = GENMASK_ULL(vabits_actual - 1, 0); 129 + unsigned long hyp_offset = (unsigned long)arg; 130 + 131 + /* Mask tags and convert to kern addr */ 132 + where = (where & va_mask) + hyp_offset; 133 + kvm_err(" [<%016lx>] %pB\n", where, (void *)(where + kaslr_offset())); 134 + 135 + return true; 136 + } 137 + 138 + static void kvm_nvhe_dump_backtrace_start(void) 139 + { 140 + kvm_err("nVHE call trace:\n"); 141 + } 142 + 143 + static void kvm_nvhe_dump_backtrace_end(void) 144 + { 145 + kvm_err("---[ end nVHE call trace ]---\n"); 146 + } 147 + 148 + /* 149 + * hyp_dump_backtrace - Dump the non-protected nVHE backtrace. 150 + * 151 + * @hyp_offset: hypervisor offset, used for address translation. 152 + * 153 + * The host can directly access HYP stack pages in non-protected 154 + * mode, so the unwinding is done directly from EL1. This removes 155 + * the need for shared buffers between host and hypervisor for 156 + * the stacktrace. 157 + */ 158 + static void hyp_dump_backtrace(unsigned long hyp_offset) 159 + { 160 + struct kvm_nvhe_stacktrace_info *stacktrace_info; 161 + struct unwind_state state; 162 + 163 + stacktrace_info = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info); 164 + 165 + kvm_nvhe_unwind_init(&state, stacktrace_info->fp, stacktrace_info->pc); 166 + 167 + kvm_nvhe_dump_backtrace_start(); 168 + unwind(&state, kvm_nvhe_dump_backtrace_entry, (void *)hyp_offset); 169 + kvm_nvhe_dump_backtrace_end(); 170 + } 171 + 172 + #ifdef CONFIG_PROTECTED_NVHE_STACKTRACE 173 + DECLARE_KVM_NVHE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], 174 + pkvm_stacktrace); 175 + 176 + /* 177 + * pkvm_dump_backtrace - Dump the protected nVHE HYP backtrace. 178 + * 179 + * @hyp_offset: hypervisor offset, used for address translation. 180 + * 181 + * Dumping of the pKVM HYP backtrace is done by reading the 182 + * stack addresses from the shared stacktrace buffer, since the 183 + * host cannot directly access hypervisor memory in protected 184 + * mode. 185 + */ 186 + static void pkvm_dump_backtrace(unsigned long hyp_offset) 187 + { 188 + unsigned long *stacktrace 189 + = (unsigned long *) this_cpu_ptr_nvhe_sym(pkvm_stacktrace); 190 + int i; 191 + 192 + kvm_nvhe_dump_backtrace_start(); 193 + /* The saved stacktrace is terminated by a null entry */ 194 + for (i = 0; 195 + i < ARRAY_SIZE(kvm_nvhe_sym(pkvm_stacktrace)) && stacktrace[i]; 196 + i++) 197 + kvm_nvhe_dump_backtrace_entry((void *)hyp_offset, stacktrace[i]); 198 + kvm_nvhe_dump_backtrace_end(); 199 + } 200 + #else /* !CONFIG_PROTECTED_NVHE_STACKTRACE */ 201 + static void pkvm_dump_backtrace(unsigned long hyp_offset) 202 + { 203 + kvm_err("Cannot dump pKVM nVHE stacktrace: !CONFIG_PROTECTED_NVHE_STACKTRACE\n"); 204 + } 205 + #endif /* CONFIG_PROTECTED_NVHE_STACKTRACE */ 206 + 207 + /* 208 + * kvm_nvhe_dump_backtrace - Dump KVM nVHE hypervisor backtrace. 209 + * 210 + * @hyp_offset: hypervisor offset, used for address translation. 211 + */ 212 + void kvm_nvhe_dump_backtrace(unsigned long hyp_offset) 213 + { 214 + if (is_protected_kvm_enabled()) 215 + pkvm_dump_backtrace(hyp_offset); 216 + else 217 + hyp_dump_backtrace(hyp_offset); 218 + }
+120 -174
arch/arm64/kvm/sys_regs.c
··· 34 34 #include "trace.h" 35 35 36 36 /* 37 - * All of this file is extremely similar to the ARM coproc.c, but the 38 - * types are different. My gut feeling is that it should be pretty 39 - * easy to merge, but that would be an ABI breakage -- again. VFP 40 - * would also need to be abstracted. 41 - * 42 37 * For AArch32, we only take care of what is being trapped. Anything 43 38 * that has to do with init and userspace access has to go via the 44 39 * 64bit interface. 45 40 */ 46 41 47 - static int reg_from_user(u64 *val, const void __user *uaddr, u64 id); 48 - static int reg_to_user(void __user *uaddr, const u64 *val, u64 id); 49 42 static u64 sys_reg_to_index(const struct sys_reg_desc *reg); 50 43 51 44 static bool read_from_write_only(struct kvm_vcpu *vcpu, ··· 65 72 { 66 73 u64 val = 0x8badf00d8badf00d; 67 74 68 - if (vcpu->arch.sysregs_loaded_on_cpu && 75 + if (vcpu_get_flag(vcpu, SYSREGS_ON_CPU) && 69 76 __vcpu_read_sys_reg_from_cpu(reg, &val)) 70 77 return val; 71 78 ··· 74 81 75 82 void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) 76 83 { 77 - if (vcpu->arch.sysregs_loaded_on_cpu && 84 + if (vcpu_get_flag(vcpu, SYSREGS_ON_CPU) && 78 85 __vcpu_write_sys_reg_to_cpu(val, reg)) 79 86 return; 80 87 ··· 314 321 } 315 322 316 323 static int set_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 317 - const struct kvm_one_reg *reg, void __user *uaddr) 324 + u64 val) 318 325 { 319 - u64 id = sys_reg_to_index(rd); 320 - u64 val; 321 - int err; 322 - 323 - err = reg_from_user(&val, uaddr, id); 324 - if (err) 325 - return err; 326 - 327 326 /* 328 327 * The only modifiable bit is the OSLK bit. Refuse the write if 329 328 * userspace attempts to change any other bit in the register. ··· 372 387 { 373 388 if (p->is_write) { 374 389 vcpu_write_sys_reg(vcpu, p->regval, r->reg); 375 - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 390 + vcpu_set_flag(vcpu, DEBUG_DIRTY); 376 391 } else { 377 392 p->regval = vcpu_read_sys_reg(vcpu, r->reg); 378 393 } ··· 388 403 * A 32 bit write to a debug register leave top bits alone 389 404 * A 32 bit read from a debug register only returns the bottom bits 390 405 * 391 - * All writes will set the KVM_ARM64_DEBUG_DIRTY flag to ensure the 392 - * hyp.S code switches between host and guest values in future. 406 + * All writes will set the DEBUG_DIRTY flag to ensure the hyp code 407 + * switches between host and guest values in future. 393 408 */ 394 409 static void reg_to_dbg(struct kvm_vcpu *vcpu, 395 410 struct sys_reg_params *p, ··· 405 420 val |= (p->regval & (mask >> shift)) << shift; 406 421 *dbg_reg = val; 407 422 408 - vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; 423 + vcpu_set_flag(vcpu, DEBUG_DIRTY); 409 424 } 410 425 411 426 static void dbg_to_reg(struct kvm_vcpu *vcpu, ··· 436 451 } 437 452 438 453 static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 439 - const struct kvm_one_reg *reg, void __user *uaddr) 454 + u64 val) 440 455 { 441 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; 442 - 443 - if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) 444 - return -EFAULT; 456 + vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = val; 445 457 return 0; 446 458 } 447 459 448 460 static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 449 - const struct kvm_one_reg *reg, void __user *uaddr) 461 + u64 *val) 450 462 { 451 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; 452 - 453 - if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) 454 - return -EFAULT; 463 + *val = vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; 455 464 return 0; 456 465 } 457 466 ··· 472 493 } 473 494 474 495 static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 475 - const struct kvm_one_reg *reg, void __user *uaddr) 496 + u64 val) 476 497 { 477 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; 478 - 479 - if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) 480 - return -EFAULT; 481 - 498 + vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = val; 482 499 return 0; 483 500 } 484 501 485 502 static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 486 - const struct kvm_one_reg *reg, void __user *uaddr) 503 + u64 *val) 487 504 { 488 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; 489 - 490 - if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) 491 - return -EFAULT; 505 + *val = vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; 492 506 return 0; 493 507 } 494 508 ··· 509 537 } 510 538 511 539 static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 512 - const struct kvm_one_reg *reg, void __user *uaddr) 540 + u64 val) 513 541 { 514 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; 515 - 516 - if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) 517 - return -EFAULT; 542 + vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = val; 518 543 return 0; 519 544 } 520 545 521 546 static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 522 - const struct kvm_one_reg *reg, void __user *uaddr) 547 + u64 *val) 523 548 { 524 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; 525 - 526 - if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) 527 - return -EFAULT; 549 + *val = vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; 528 550 return 0; 529 551 } 530 552 ··· 545 579 } 546 580 547 581 static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 548 - const struct kvm_one_reg *reg, void __user *uaddr) 582 + u64 val) 549 583 { 550 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; 551 - 552 - if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) 553 - return -EFAULT; 584 + vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = val; 554 585 return 0; 555 586 } 556 587 557 588 static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 558 - const struct kvm_one_reg *reg, void __user *uaddr) 589 + u64 *val) 559 590 { 560 - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; 561 - 562 - if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) 563 - return -EFAULT; 591 + *val = vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; 564 592 return 0; 565 593 } 566 594 ··· 1187 1227 1188 1228 static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, 1189 1229 const struct sys_reg_desc *rd, 1190 - const struct kvm_one_reg *reg, void __user *uaddr) 1230 + u64 val) 1191 1231 { 1192 - const u64 id = sys_reg_to_index(rd); 1193 1232 u8 csv2, csv3; 1194 - int err; 1195 - u64 val; 1196 - 1197 - err = reg_from_user(&val, uaddr, id); 1198 - if (err) 1199 - return err; 1200 1233 1201 1234 /* 1202 1235 * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as ··· 1215 1262 return -EINVAL; 1216 1263 1217 1264 vcpu->kvm->arch.pfr0_csv2 = csv2; 1218 - vcpu->kvm->arch.pfr0_csv3 = csv3 ; 1265 + vcpu->kvm->arch.pfr0_csv3 = csv3; 1219 1266 1220 1267 return 0; 1221 1268 } ··· 1228 1275 * to be changed. 1229 1276 */ 1230 1277 static int __get_id_reg(const struct kvm_vcpu *vcpu, 1231 - const struct sys_reg_desc *rd, void __user *uaddr, 1278 + const struct sys_reg_desc *rd, u64 *val, 1232 1279 bool raz) 1233 1280 { 1234 - const u64 id = sys_reg_to_index(rd); 1235 - const u64 val = read_id_reg(vcpu, rd, raz); 1236 - 1237 - return reg_to_user(uaddr, &val, id); 1281 + *val = read_id_reg(vcpu, rd, raz); 1282 + return 0; 1238 1283 } 1239 1284 1240 1285 static int __set_id_reg(const struct kvm_vcpu *vcpu, 1241 - const struct sys_reg_desc *rd, void __user *uaddr, 1286 + const struct sys_reg_desc *rd, u64 val, 1242 1287 bool raz) 1243 1288 { 1244 - const u64 id = sys_reg_to_index(rd); 1245 - int err; 1246 - u64 val; 1247 - 1248 - err = reg_from_user(&val, uaddr, id); 1249 - if (err) 1250 - return err; 1251 - 1252 1289 /* This is what we mean by invariant: you can't change it. */ 1253 1290 if (val != read_id_reg(vcpu, rd, raz)) 1254 1291 return -EINVAL; ··· 1247 1304 } 1248 1305 1249 1306 static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 1250 - const struct kvm_one_reg *reg, void __user *uaddr) 1307 + u64 *val) 1251 1308 { 1252 1309 bool raz = sysreg_visible_as_raz(vcpu, rd); 1253 1310 1254 - return __get_id_reg(vcpu, rd, uaddr, raz); 1311 + return __get_id_reg(vcpu, rd, val, raz); 1255 1312 } 1256 1313 1257 1314 static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 1258 - const struct kvm_one_reg *reg, void __user *uaddr) 1315 + u64 val) 1259 1316 { 1260 1317 bool raz = sysreg_visible_as_raz(vcpu, rd); 1261 1318 1262 - return __set_id_reg(vcpu, rd, uaddr, raz); 1319 + return __set_id_reg(vcpu, rd, val, raz); 1263 1320 } 1264 1321 1265 1322 static int set_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 1266 - const struct kvm_one_reg *reg, void __user *uaddr) 1323 + u64 val) 1267 1324 { 1268 - return __set_id_reg(vcpu, rd, uaddr, true); 1325 + return __set_id_reg(vcpu, rd, val, true); 1269 1326 } 1270 1327 1271 1328 static int get_raz_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 1272 - const struct kvm_one_reg *reg, void __user *uaddr) 1329 + u64 *val) 1273 1330 { 1274 - const u64 id = sys_reg_to_index(rd); 1275 - const u64 val = 0; 1276 - 1277 - return reg_to_user(uaddr, &val, id); 1331 + *val = 0; 1332 + return 0; 1278 1333 } 1279 1334 1280 1335 static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 1281 - const struct kvm_one_reg *reg, void __user *uaddr) 1336 + u64 val) 1282 1337 { 1283 - int err; 1284 - u64 val; 1285 - 1286 - /* Perform the access even if we are going to ignore the value */ 1287 - err = reg_from_user(&val, uaddr, sys_reg_to_index(rd)); 1288 - if (err) 1289 - return err; 1290 - 1291 1338 return 0; 1292 1339 } 1293 1340 ··· 2572 2639 } 2573 2640 } 2574 2641 2575 - const struct sys_reg_desc *find_reg_by_id(u64 id, 2576 - struct sys_reg_params *params, 2577 - const struct sys_reg_desc table[], 2578 - unsigned int num) 2642 + const struct sys_reg_desc *get_reg_by_id(u64 id, 2643 + const struct sys_reg_desc table[], 2644 + unsigned int num) 2579 2645 { 2580 - if (!index_to_params(id, params)) 2646 + struct sys_reg_params params; 2647 + 2648 + if (!index_to_params(id, &params)) 2581 2649 return NULL; 2582 2650 2583 - return find_reg(params, table, num); 2651 + return find_reg(&params, table, num); 2584 2652 } 2585 2653 2586 2654 /* Decode an index value, and find the sys_reg_desc entry. */ 2587 - static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu, 2588 - u64 id) 2655 + static const struct sys_reg_desc * 2656 + id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id, 2657 + const struct sys_reg_desc table[], unsigned int num) 2658 + 2589 2659 { 2590 2660 const struct sys_reg_desc *r; 2591 - struct sys_reg_params params; 2592 2661 2593 2662 /* We only do sys_reg for now. */ 2594 2663 if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM64_SYSREG) 2595 2664 return NULL; 2596 2665 2597 - if (!index_to_params(id, &params)) 2598 - return NULL; 2599 - 2600 - r = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); 2666 + r = get_reg_by_id(id, table, num); 2601 2667 2602 2668 /* Not saved in the sys_reg array and not otherwise accessible? */ 2603 - if (r && !(r->reg || r->get_user)) 2669 + if (r && (!(r->reg || r->get_user) || sysreg_hidden(vcpu, r))) 2604 2670 r = NULL; 2605 2671 2606 2672 return r; ··· 2639 2707 { SYS_DESC(SYS_CTR_EL0), NULL, get_ctr_el0 }, 2640 2708 }; 2641 2709 2642 - static int reg_from_user(u64 *val, const void __user *uaddr, u64 id) 2710 + static int get_invariant_sys_reg(u64 id, u64 __user *uaddr) 2643 2711 { 2644 - if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0) 2645 - return -EFAULT; 2646 - return 0; 2647 - } 2648 - 2649 - static int reg_to_user(void __user *uaddr, const u64 *val, u64 id) 2650 - { 2651 - if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0) 2652 - return -EFAULT; 2653 - return 0; 2654 - } 2655 - 2656 - static int get_invariant_sys_reg(u64 id, void __user *uaddr) 2657 - { 2658 - struct sys_reg_params params; 2659 2712 const struct sys_reg_desc *r; 2660 2713 2661 - r = find_reg_by_id(id, &params, invariant_sys_regs, 2662 - ARRAY_SIZE(invariant_sys_regs)); 2714 + r = get_reg_by_id(id, invariant_sys_regs, 2715 + ARRAY_SIZE(invariant_sys_regs)); 2663 2716 if (!r) 2664 2717 return -ENOENT; 2665 2718 2666 - return reg_to_user(uaddr, &r->val, id); 2719 + return put_user(r->val, uaddr); 2667 2720 } 2668 2721 2669 - static int set_invariant_sys_reg(u64 id, void __user *uaddr) 2722 + static int set_invariant_sys_reg(u64 id, u64 __user *uaddr) 2670 2723 { 2671 - struct sys_reg_params params; 2672 2724 const struct sys_reg_desc *r; 2673 - int err; 2674 - u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */ 2725 + u64 val; 2675 2726 2676 - r = find_reg_by_id(id, &params, invariant_sys_regs, 2677 - ARRAY_SIZE(invariant_sys_regs)); 2727 + r = get_reg_by_id(id, invariant_sys_regs, 2728 + ARRAY_SIZE(invariant_sys_regs)); 2678 2729 if (!r) 2679 2730 return -ENOENT; 2680 2731 2681 - err = reg_from_user(&val, uaddr, id); 2682 - if (err) 2683 - return err; 2732 + if (get_user(val, uaddr)) 2733 + return -EFAULT; 2684 2734 2685 2735 /* This is what we mean by invariant: you can't change it. */ 2686 2736 if (r->val != val) ··· 2753 2839 } 2754 2840 } 2755 2841 2842 + int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, 2843 + const struct sys_reg_desc table[], unsigned int num) 2844 + { 2845 + u64 __user *uaddr = (u64 __user *)(unsigned long)reg->addr; 2846 + const struct sys_reg_desc *r; 2847 + u64 val; 2848 + int ret; 2849 + 2850 + r = id_to_sys_reg_desc(vcpu, reg->id, table, num); 2851 + if (!r) 2852 + return -ENOENT; 2853 + 2854 + if (r->get_user) { 2855 + ret = (r->get_user)(vcpu, r, &val); 2856 + } else { 2857 + val = __vcpu_sys_reg(vcpu, r->reg); 2858 + ret = 0; 2859 + } 2860 + 2861 + if (!ret) 2862 + ret = put_user(val, uaddr); 2863 + 2864 + return ret; 2865 + } 2866 + 2756 2867 int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 2757 2868 { 2758 - const struct sys_reg_desc *r; 2759 2869 void __user *uaddr = (void __user *)(unsigned long)reg->addr; 2870 + int err; 2760 2871 2761 2872 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) 2762 2873 return demux_c15_get(reg->id, uaddr); 2763 2874 2764 - if (KVM_REG_SIZE(reg->id) != sizeof(__u64)) 2765 - return -ENOENT; 2875 + err = get_invariant_sys_reg(reg->id, uaddr); 2876 + if (err != -ENOENT) 2877 + return err; 2766 2878 2767 - r = index_to_sys_reg_desc(vcpu, reg->id); 2879 + return kvm_sys_reg_get_user(vcpu, reg, 2880 + sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); 2881 + } 2882 + 2883 + int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, 2884 + const struct sys_reg_desc table[], unsigned int num) 2885 + { 2886 + u64 __user *uaddr = (u64 __user *)(unsigned long)reg->addr; 2887 + const struct sys_reg_desc *r; 2888 + u64 val; 2889 + int ret; 2890 + 2891 + if (get_user(val, uaddr)) 2892 + return -EFAULT; 2893 + 2894 + r = id_to_sys_reg_desc(vcpu, reg->id, table, num); 2768 2895 if (!r) 2769 - return get_invariant_sys_reg(reg->id, uaddr); 2770 - 2771 - /* Check for regs disabled by runtime config */ 2772 - if (sysreg_hidden(vcpu, r)) 2773 2896 return -ENOENT; 2774 2897 2775 - if (r->get_user) 2776 - return (r->get_user)(vcpu, r, reg, uaddr); 2898 + if (r->set_user) { 2899 + ret = (r->set_user)(vcpu, r, val); 2900 + } else { 2901 + __vcpu_sys_reg(vcpu, r->reg) = val; 2902 + ret = 0; 2903 + } 2777 2904 2778 - return reg_to_user(uaddr, &__vcpu_sys_reg(vcpu, r->reg), reg->id); 2905 + return ret; 2779 2906 } 2780 2907 2781 2908 int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 2782 2909 { 2783 - const struct sys_reg_desc *r; 2784 2910 void __user *uaddr = (void __user *)(unsigned long)reg->addr; 2911 + int err; 2785 2912 2786 2913 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX) 2787 2914 return demux_c15_set(reg->id, uaddr); 2788 2915 2789 - if (KVM_REG_SIZE(reg->id) != sizeof(__u64)) 2790 - return -ENOENT; 2916 + err = set_invariant_sys_reg(reg->id, uaddr); 2917 + if (err != -ENOENT) 2918 + return err; 2791 2919 2792 - r = index_to_sys_reg_desc(vcpu, reg->id); 2793 - if (!r) 2794 - return set_invariant_sys_reg(reg->id, uaddr); 2795 - 2796 - /* Check for regs disabled by runtime config */ 2797 - if (sysreg_hidden(vcpu, r)) 2798 - return -ENOENT; 2799 - 2800 - if (r->set_user) 2801 - return (r->set_user)(vcpu, r, reg, uaddr); 2802 - 2803 - return reg_from_user(&__vcpu_sys_reg(vcpu, r->reg), uaddr, reg->id); 2920 + return kvm_sys_reg_set_user(vcpu, reg, 2921 + sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); 2804 2922 } 2805 2923 2806 2924 static unsigned int num_demux_regs(void)
+12 -6
arch/arm64/kvm/sys_regs.h
··· 75 75 76 76 /* Custom get/set_user functions, fallback to generic if NULL */ 77 77 int (*get_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 78 - const struct kvm_one_reg *reg, void __user *uaddr); 78 + u64 *val); 79 79 int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 80 - const struct kvm_one_reg *reg, void __user *uaddr); 80 + u64 val); 81 81 82 82 /* Return mask of REG_* runtime visibility overrides */ 83 83 unsigned int (*visibility)(const struct kvm_vcpu *vcpu, ··· 190 190 return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg); 191 191 } 192 192 193 - const struct sys_reg_desc *find_reg_by_id(u64 id, 194 - struct sys_reg_params *params, 195 - const struct sys_reg_desc table[], 196 - unsigned int num); 193 + const struct sys_reg_desc *get_reg_by_id(u64 id, 194 + const struct sys_reg_desc table[], 195 + unsigned int num); 196 + 197 + int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); 198 + int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); 199 + int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, 200 + const struct sys_reg_desc table[], unsigned int num); 201 + int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg, 202 + const struct sys_reg_desc table[], unsigned int num); 197 203 198 204 #define AA32(_x) .aarch32_map = AA32_##_x 199 205 #define Op0(_x) .Op0 = _x
+265 -201
arch/arm64/kvm/vgic-sys-reg-v3.c
··· 10 10 #include "vgic/vgic.h" 11 11 #include "sys_regs.h" 12 12 13 - static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 14 - const struct sys_reg_desc *r) 13 + static int set_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 14 + u64 val) 15 15 { 16 16 u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v; 17 + struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; 18 + struct vgic_vmcr vmcr; 19 + 20 + vgic_get_vmcr(vcpu, &vmcr); 21 + 22 + /* 23 + * Disallow restoring VM state if not supported by this 24 + * hardware. 25 + */ 26 + host_pri_bits = FIELD_GET(ICC_CTLR_EL1_PRI_BITS_MASK, val) + 1; 27 + if (host_pri_bits > vgic_v3_cpu->num_pri_bits) 28 + return -EINVAL; 29 + 30 + vgic_v3_cpu->num_pri_bits = host_pri_bits; 31 + 32 + host_id_bits = FIELD_GET(ICC_CTLR_EL1_ID_BITS_MASK, val); 33 + if (host_id_bits > vgic_v3_cpu->num_id_bits) 34 + return -EINVAL; 35 + 36 + vgic_v3_cpu->num_id_bits = host_id_bits; 37 + 38 + host_seis = FIELD_GET(ICH_VTR_SEIS_MASK, kvm_vgic_global_state.ich_vtr_el2); 39 + seis = FIELD_GET(ICC_CTLR_EL1_SEIS_MASK, val); 40 + if (host_seis != seis) 41 + return -EINVAL; 42 + 43 + host_a3v = FIELD_GET(ICH_VTR_A3V_MASK, kvm_vgic_global_state.ich_vtr_el2); 44 + a3v = FIELD_GET(ICC_CTLR_EL1_A3V_MASK, val); 45 + if (host_a3v != a3v) 46 + return -EINVAL; 47 + 48 + /* 49 + * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. 50 + * The vgic_set_vmcr() will convert to ICH_VMCR layout. 51 + */ 52 + vmcr.cbpr = FIELD_GET(ICC_CTLR_EL1_CBPR_MASK, val); 53 + vmcr.eoim = FIELD_GET(ICC_CTLR_EL1_EOImode_MASK, val); 54 + vgic_set_vmcr(vcpu, &vmcr); 55 + 56 + return 0; 57 + } 58 + 59 + static int get_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 60 + u64 *valp) 61 + { 17 62 struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; 18 63 struct vgic_vmcr vmcr; 19 64 u64 val; 20 65 21 66 vgic_get_vmcr(vcpu, &vmcr); 22 - if (p->is_write) { 23 - val = p->regval; 67 + val = 0; 68 + val |= FIELD_PREP(ICC_CTLR_EL1_PRI_BITS_MASK, vgic_v3_cpu->num_pri_bits - 1); 69 + val |= FIELD_PREP(ICC_CTLR_EL1_ID_BITS_MASK, vgic_v3_cpu->num_id_bits); 70 + val |= FIELD_PREP(ICC_CTLR_EL1_SEIS_MASK, 71 + FIELD_GET(ICH_VTR_SEIS_MASK, 72 + kvm_vgic_global_state.ich_vtr_el2)); 73 + val |= FIELD_PREP(ICC_CTLR_EL1_A3V_MASK, 74 + FIELD_GET(ICH_VTR_A3V_MASK, kvm_vgic_global_state.ich_vtr_el2)); 75 + /* 76 + * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. 77 + * Extract it directly using ICC_CTLR_EL1 reg definitions. 78 + */ 79 + val |= FIELD_PREP(ICC_CTLR_EL1_CBPR_MASK, vmcr.cbpr); 80 + val |= FIELD_PREP(ICC_CTLR_EL1_EOImode_MASK, vmcr.eoim); 24 81 25 - /* 26 - * Disallow restoring VM state if not supported by this 27 - * hardware. 28 - */ 29 - host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >> 30 - ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1; 31 - if (host_pri_bits > vgic_v3_cpu->num_pri_bits) 32 - return false; 82 + *valp = val; 33 83 34 - vgic_v3_cpu->num_pri_bits = host_pri_bits; 35 - 36 - host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >> 37 - ICC_CTLR_EL1_ID_BITS_SHIFT; 38 - if (host_id_bits > vgic_v3_cpu->num_id_bits) 39 - return false; 40 - 41 - vgic_v3_cpu->num_id_bits = host_id_bits; 42 - 43 - host_seis = ((kvm_vgic_global_state.ich_vtr_el2 & 44 - ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT); 45 - seis = (val & ICC_CTLR_EL1_SEIS_MASK) >> 46 - ICC_CTLR_EL1_SEIS_SHIFT; 47 - if (host_seis != seis) 48 - return false; 49 - 50 - host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 & 51 - ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT); 52 - a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT; 53 - if (host_a3v != a3v) 54 - return false; 55 - 56 - /* 57 - * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. 58 - * The vgic_set_vmcr() will convert to ICH_VMCR layout. 59 - */ 60 - vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT; 61 - vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT; 62 - vgic_set_vmcr(vcpu, &vmcr); 63 - } else { 64 - val = 0; 65 - val |= (vgic_v3_cpu->num_pri_bits - 1) << 66 - ICC_CTLR_EL1_PRI_BITS_SHIFT; 67 - val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT; 68 - val |= ((kvm_vgic_global_state.ich_vtr_el2 & 69 - ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) << 70 - ICC_CTLR_EL1_SEIS_SHIFT; 71 - val |= ((kvm_vgic_global_state.ich_vtr_el2 & 72 - ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) << 73 - ICC_CTLR_EL1_A3V_SHIFT; 74 - /* 75 - * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. 76 - * Extract it directly using ICC_CTLR_EL1 reg definitions. 77 - */ 78 - val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK; 79 - val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; 80 - 81 - p->regval = val; 82 - } 83 - 84 - return true; 84 + return 0; 85 85 } 86 86 87 - static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 88 - const struct sys_reg_desc *r) 87 + static int set_gic_pmr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 88 + u64 val) 89 89 { 90 90 struct vgic_vmcr vmcr; 91 91 92 92 vgic_get_vmcr(vcpu, &vmcr); 93 - if (p->is_write) { 94 - vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT; 95 - vgic_set_vmcr(vcpu, &vmcr); 96 - } else { 97 - p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK; 98 - } 93 + vmcr.pmr = FIELD_GET(ICC_PMR_EL1_MASK, val); 94 + vgic_set_vmcr(vcpu, &vmcr); 99 95 100 - return true; 96 + return 0; 101 97 } 102 98 103 - static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 104 - const struct sys_reg_desc *r) 99 + static int get_gic_pmr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 100 + u64 *val) 105 101 { 106 102 struct vgic_vmcr vmcr; 107 103 108 104 vgic_get_vmcr(vcpu, &vmcr); 109 - if (p->is_write) { 110 - vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >> 111 - ICC_BPR0_EL1_SHIFT; 112 - vgic_set_vmcr(vcpu, &vmcr); 113 - } else { 114 - p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) & 115 - ICC_BPR0_EL1_MASK; 116 - } 105 + *val = FIELD_PREP(ICC_PMR_EL1_MASK, vmcr.pmr); 117 106 118 - return true; 107 + return 0; 119 108 } 120 109 121 - static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 122 - const struct sys_reg_desc *r) 110 + static int set_gic_bpr0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 111 + u64 val) 123 112 { 124 113 struct vgic_vmcr vmcr; 125 114 126 - if (!p->is_write) 127 - p->regval = 0; 115 + vgic_get_vmcr(vcpu, &vmcr); 116 + vmcr.bpr = FIELD_GET(ICC_BPR0_EL1_MASK, val); 117 + vgic_set_vmcr(vcpu, &vmcr); 118 + 119 + return 0; 120 + } 121 + 122 + static int get_gic_bpr0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 123 + u64 *val) 124 + { 125 + struct vgic_vmcr vmcr; 126 + 127 + vgic_get_vmcr(vcpu, &vmcr); 128 + *val = FIELD_PREP(ICC_BPR0_EL1_MASK, vmcr.bpr); 129 + 130 + return 0; 131 + } 132 + 133 + static int set_gic_bpr1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 134 + u64 val) 135 + { 136 + struct vgic_vmcr vmcr; 128 137 129 138 vgic_get_vmcr(vcpu, &vmcr); 130 139 if (!vmcr.cbpr) { 131 - if (p->is_write) { 132 - vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >> 133 - ICC_BPR1_EL1_SHIFT; 134 - vgic_set_vmcr(vcpu, &vmcr); 135 - } else { 136 - p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) & 137 - ICC_BPR1_EL1_MASK; 138 - } 139 - } else { 140 - if (!p->is_write) 141 - p->regval = min((vmcr.bpr + 1), 7U); 140 + vmcr.abpr = FIELD_GET(ICC_BPR1_EL1_MASK, val); 141 + vgic_set_vmcr(vcpu, &vmcr); 142 142 } 143 143 144 - return true; 144 + return 0; 145 145 } 146 146 147 - static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 148 - const struct sys_reg_desc *r) 147 + static int get_gic_bpr1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 148 + u64 *val) 149 149 { 150 150 struct vgic_vmcr vmcr; 151 151 152 152 vgic_get_vmcr(vcpu, &vmcr); 153 - if (p->is_write) { 154 - vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >> 155 - ICC_IGRPEN0_EL1_SHIFT; 156 - vgic_set_vmcr(vcpu, &vmcr); 157 - } else { 158 - p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) & 159 - ICC_IGRPEN0_EL1_MASK; 160 - } 153 + if (!vmcr.cbpr) 154 + *val = FIELD_PREP(ICC_BPR1_EL1_MASK, vmcr.abpr); 155 + else 156 + *val = min((vmcr.bpr + 1), 7U); 161 157 162 - return true; 158 + 159 + return 0; 163 160 } 164 161 165 - static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 166 - const struct sys_reg_desc *r) 162 + static int set_gic_grpen0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 163 + u64 val) 167 164 { 168 165 struct vgic_vmcr vmcr; 169 166 170 167 vgic_get_vmcr(vcpu, &vmcr); 171 - if (p->is_write) { 172 - vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >> 173 - ICC_IGRPEN1_EL1_SHIFT; 174 - vgic_set_vmcr(vcpu, &vmcr); 175 - } else { 176 - p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) & 177 - ICC_IGRPEN1_EL1_MASK; 178 - } 168 + vmcr.grpen0 = FIELD_GET(ICC_IGRPEN0_EL1_MASK, val); 169 + vgic_set_vmcr(vcpu, &vmcr); 179 170 180 - return true; 171 + return 0; 181 172 } 182 173 183 - static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu, 184 - struct sys_reg_params *p, u8 apr, u8 idx) 174 + static int get_gic_grpen0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 175 + u64 *val) 176 + { 177 + struct vgic_vmcr vmcr; 178 + 179 + vgic_get_vmcr(vcpu, &vmcr); 180 + *val = FIELD_PREP(ICC_IGRPEN0_EL1_MASK, vmcr.grpen0); 181 + 182 + return 0; 183 + } 184 + 185 + static int set_gic_grpen1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 186 + u64 val) 187 + { 188 + struct vgic_vmcr vmcr; 189 + 190 + vgic_get_vmcr(vcpu, &vmcr); 191 + vmcr.grpen1 = FIELD_GET(ICC_IGRPEN1_EL1_MASK, val); 192 + vgic_set_vmcr(vcpu, &vmcr); 193 + 194 + return 0; 195 + } 196 + 197 + static int get_gic_grpen1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 198 + u64 *val) 199 + { 200 + struct vgic_vmcr vmcr; 201 + 202 + vgic_get_vmcr(vcpu, &vmcr); 203 + *val = FIELD_GET(ICC_IGRPEN1_EL1_MASK, vmcr.grpen1); 204 + 205 + return 0; 206 + } 207 + 208 + static void set_apr_reg(struct kvm_vcpu *vcpu, u64 val, u8 apr, u8 idx) 185 209 { 186 210 struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 187 - uint32_t *ap_reg; 188 211 189 212 if (apr) 190 - ap_reg = &vgicv3->vgic_ap1r[idx]; 213 + vgicv3->vgic_ap1r[idx] = val; 191 214 else 192 - ap_reg = &vgicv3->vgic_ap0r[idx]; 193 - 194 - if (p->is_write) 195 - *ap_reg = p->regval; 196 - else 197 - p->regval = *ap_reg; 215 + vgicv3->vgic_ap0r[idx] = val; 198 216 } 199 217 200 - static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 201 - const struct sys_reg_desc *r, u8 apr) 218 + static u64 get_apr_reg(struct kvm_vcpu *vcpu, u8 apr, u8 idx) 219 + { 220 + struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 221 + 222 + if (apr) 223 + return vgicv3->vgic_ap1r[idx]; 224 + else 225 + return vgicv3->vgic_ap0r[idx]; 226 + } 227 + 228 + static int set_gic_ap0r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 229 + u64 val) 230 + 202 231 { 203 232 u8 idx = r->Op2 & 3; 204 233 205 234 if (idx > vgic_v3_max_apr_idx(vcpu)) 206 - goto err; 235 + return -EINVAL; 207 236 208 - vgic_v3_access_apr_reg(vcpu, p, apr, idx); 209 - return true; 210 - err: 211 - if (!p->is_write) 212 - p->regval = 0; 213 - 214 - return false; 237 + set_apr_reg(vcpu, val, 0, idx); 238 + return 0; 215 239 } 216 240 217 - static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 218 - const struct sys_reg_desc *r) 241 + static int get_gic_ap0r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 242 + u64 *val) 243 + { 244 + u8 idx = r->Op2 & 3; 245 + 246 + if (idx > vgic_v3_max_apr_idx(vcpu)) 247 + return -EINVAL; 248 + 249 + *val = get_apr_reg(vcpu, 0, idx); 250 + 251 + return 0; 252 + } 253 + 254 + static int set_gic_ap1r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 255 + u64 val) 219 256 220 257 { 221 - return access_gic_aprn(vcpu, p, r, 0); 258 + u8 idx = r->Op2 & 3; 259 + 260 + if (idx > vgic_v3_max_apr_idx(vcpu)) 261 + return -EINVAL; 262 + 263 + set_apr_reg(vcpu, val, 1, idx); 264 + return 0; 222 265 } 223 266 224 - static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 225 - const struct sys_reg_desc *r) 267 + static int get_gic_ap1r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 268 + u64 *val) 226 269 { 227 - return access_gic_aprn(vcpu, p, r, 1); 270 + u8 idx = r->Op2 & 3; 271 + 272 + if (idx > vgic_v3_max_apr_idx(vcpu)) 273 + return -EINVAL; 274 + 275 + *val = get_apr_reg(vcpu, 1, idx); 276 + 277 + return 0; 228 278 } 229 279 230 - static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 231 - const struct sys_reg_desc *r) 280 + static int set_gic_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 281 + u64 val) 282 + { 283 + /* Validate SRE bit */ 284 + if (!(val & ICC_SRE_EL1_SRE)) 285 + return -EINVAL; 286 + 287 + return 0; 288 + } 289 + 290 + static int get_gic_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 291 + u64 *val) 232 292 { 233 293 struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 234 294 235 - /* Validate SRE bit */ 236 - if (p->is_write) { 237 - if (!(p->regval & ICC_SRE_EL1_SRE)) 238 - return false; 239 - } else { 240 - p->regval = vgicv3->vgic_sre; 241 - } 295 + *val = vgicv3->vgic_sre; 242 296 243 - return true; 297 + return 0; 244 298 } 299 + 245 300 static const struct sys_reg_desc gic_v3_icc_reg_descs[] = { 246 - { SYS_DESC(SYS_ICC_PMR_EL1), access_gic_pmr }, 247 - { SYS_DESC(SYS_ICC_BPR0_EL1), access_gic_bpr0 }, 248 - { SYS_DESC(SYS_ICC_AP0R0_EL1), access_gic_ap0r }, 249 - { SYS_DESC(SYS_ICC_AP0R1_EL1), access_gic_ap0r }, 250 - { SYS_DESC(SYS_ICC_AP0R2_EL1), access_gic_ap0r }, 251 - { SYS_DESC(SYS_ICC_AP0R3_EL1), access_gic_ap0r }, 252 - { SYS_DESC(SYS_ICC_AP1R0_EL1), access_gic_ap1r }, 253 - { SYS_DESC(SYS_ICC_AP1R1_EL1), access_gic_ap1r }, 254 - { SYS_DESC(SYS_ICC_AP1R2_EL1), access_gic_ap1r }, 255 - { SYS_DESC(SYS_ICC_AP1R3_EL1), access_gic_ap1r }, 256 - { SYS_DESC(SYS_ICC_BPR1_EL1), access_gic_bpr1 }, 257 - { SYS_DESC(SYS_ICC_CTLR_EL1), access_gic_ctlr }, 258 - { SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre }, 259 - { SYS_DESC(SYS_ICC_IGRPEN0_EL1), access_gic_grpen0 }, 260 - { SYS_DESC(SYS_ICC_IGRPEN1_EL1), access_gic_grpen1 }, 301 + { SYS_DESC(SYS_ICC_PMR_EL1), 302 + .set_user = set_gic_pmr, .get_user = get_gic_pmr, }, 303 + { SYS_DESC(SYS_ICC_BPR0_EL1), 304 + .set_user = set_gic_bpr0, .get_user = get_gic_bpr0, }, 305 + { SYS_DESC(SYS_ICC_AP0R0_EL1), 306 + .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 307 + { SYS_DESC(SYS_ICC_AP0R1_EL1), 308 + .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 309 + { SYS_DESC(SYS_ICC_AP0R2_EL1), 310 + .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 311 + { SYS_DESC(SYS_ICC_AP0R3_EL1), 312 + .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 313 + { SYS_DESC(SYS_ICC_AP1R0_EL1), 314 + .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 315 + { SYS_DESC(SYS_ICC_AP1R1_EL1), 316 + .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 317 + { SYS_DESC(SYS_ICC_AP1R2_EL1), 318 + .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 319 + { SYS_DESC(SYS_ICC_AP1R3_EL1), 320 + .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 321 + { SYS_DESC(SYS_ICC_BPR1_EL1), 322 + .set_user = set_gic_bpr1, .get_user = get_gic_bpr1, }, 323 + { SYS_DESC(SYS_ICC_CTLR_EL1), 324 + .set_user = set_gic_ctlr, .get_user = get_gic_ctlr, }, 325 + { SYS_DESC(SYS_ICC_SRE_EL1), 326 + .set_user = set_gic_sre, .get_user = get_gic_sre, }, 327 + { SYS_DESC(SYS_ICC_IGRPEN0_EL1), 328 + .set_user = set_gic_grpen0, .get_user = get_gic_grpen0, }, 329 + { SYS_DESC(SYS_ICC_IGRPEN1_EL1), 330 + .set_user = set_gic_grpen1, .get_user = get_gic_grpen1, }, 261 331 }; 262 332 263 - int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, 264 - u64 *reg) 333 + static u64 attr_to_id(u64 attr) 265 334 { 266 - struct sys_reg_params params; 267 - u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 335 + return ARM64_SYS_REG(FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP0_MASK, attr), 336 + FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP1_MASK, attr), 337 + FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_CRN_MASK, attr), 338 + FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_CRM_MASK, attr), 339 + FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP2_MASK, attr)); 340 + } 268 341 269 - params.regval = *reg; 270 - params.is_write = is_write; 271 - 272 - if (find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs, 273 - ARRAY_SIZE(gic_v3_icc_reg_descs))) 342 + int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) 343 + { 344 + if (get_reg_by_id(attr_to_id(attr->attr), gic_v3_icc_reg_descs, 345 + ARRAY_SIZE(gic_v3_icc_reg_descs))) 274 346 return 0; 275 347 276 348 return -ENXIO; 277 349 } 278 350 279 - int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id, 280 - u64 *reg) 351 + int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, 352 + struct kvm_device_attr *attr, 353 + bool is_write) 281 354 { 282 - struct sys_reg_params params; 283 - const struct sys_reg_desc *r; 284 - u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 355 + struct kvm_one_reg reg = { 356 + .id = attr_to_id(attr->attr), 357 + .addr = attr->addr, 358 + }; 285 359 286 360 if (is_write) 287 - params.regval = *reg; 288 - params.is_write = is_write; 289 - 290 - r = find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs, 291 - ARRAY_SIZE(gic_v3_icc_reg_descs)); 292 - if (!r) 293 - return -ENXIO; 294 - 295 - if (!r->access(vcpu, &params, r)) 296 - return -EINVAL; 297 - 298 - if (!is_write) 299 - *reg = params.regval; 300 - 301 - return 0; 361 + return kvm_sys_reg_set_user(vcpu, &reg, gic_v3_icc_reg_descs, 362 + ARRAY_SIZE(gic_v3_icc_reg_descs)); 363 + else 364 + return kvm_sys_reg_get_user(vcpu, &reg, gic_v3_icc_reg_descs, 365 + ARRAY_SIZE(gic_v3_icc_reg_descs)); 302 366 }
+143 -199
arch/arm64/kvm/vgic/vgic-kvm-device.c
··· 41 41 return 0; 42 42 } 43 43 44 + int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr) 45 + { 46 + struct vgic_dist *vgic = &kvm->arch.vgic; 47 + int r; 48 + 49 + mutex_lock(&kvm->lock); 50 + switch (FIELD_GET(KVM_ARM_DEVICE_TYPE_MASK, dev_addr->id)) { 51 + case KVM_VGIC_V2_ADDR_TYPE_DIST: 52 + r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); 53 + if (!r) 54 + r = vgic_check_iorange(kvm, vgic->vgic_dist_base, dev_addr->addr, 55 + SZ_4K, KVM_VGIC_V2_DIST_SIZE); 56 + if (!r) 57 + vgic->vgic_dist_base = dev_addr->addr; 58 + break; 59 + case KVM_VGIC_V2_ADDR_TYPE_CPU: 60 + r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); 61 + if (!r) 62 + r = vgic_check_iorange(kvm, vgic->vgic_cpu_base, dev_addr->addr, 63 + SZ_4K, KVM_VGIC_V2_CPU_SIZE); 64 + if (!r) 65 + vgic->vgic_cpu_base = dev_addr->addr; 66 + break; 67 + default: 68 + r = -ENODEV; 69 + } 70 + 71 + mutex_unlock(&kvm->lock); 72 + 73 + return r; 74 + } 75 + 44 76 /** 45 77 * kvm_vgic_addr - set or get vgic VM base addresses 46 78 * @kvm: pointer to the vm struct 47 - * @type: the VGIC addr type, one of KVM_VGIC_V[23]_ADDR_TYPE_XXX 48 - * @addr: pointer to address value 79 + * @attr: pointer to the attribute being retrieved/updated 49 80 * @write: if true set the address in the VM address space, if false read the 50 81 * address 51 82 * ··· 88 57 * overlapping regions in case of a virtual GICv3 here, since we don't know 89 58 * the number of VCPUs yet, so we defer this check to map_resources(). 90 59 */ 91 - int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write) 60 + static int kvm_vgic_addr(struct kvm *kvm, struct kvm_device_attr *attr, bool write) 92 61 { 93 - int r = 0; 62 + u64 __user *uaddr = (u64 __user *)attr->addr; 94 63 struct vgic_dist *vgic = &kvm->arch.vgic; 95 64 phys_addr_t *addr_ptr, alignment, size; 96 65 u64 undef_value = VGIC_ADDR_UNDEF; 66 + u64 addr; 67 + int r; 68 + 69 + /* Reading a redistributor region addr implies getting the index */ 70 + if (write || attr->attr == KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION) 71 + if (get_user(addr, uaddr)) 72 + return -EFAULT; 97 73 98 74 mutex_lock(&kvm->lock); 99 - switch (type) { 75 + switch (attr->attr) { 100 76 case KVM_VGIC_V2_ADDR_TYPE_DIST: 101 77 r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2); 102 78 addr_ptr = &vgic->vgic_dist_base; ··· 129 91 if (r) 130 92 break; 131 93 if (write) { 132 - r = vgic_v3_set_redist_base(kvm, 0, *addr, 0); 94 + r = vgic_v3_set_redist_base(kvm, 0, addr, 0); 133 95 goto out; 134 96 } 135 97 rdreg = list_first_entry_or_null(&vgic->rd_regions, ··· 149 111 if (r) 150 112 break; 151 113 152 - index = *addr & KVM_VGIC_V3_RDIST_INDEX_MASK; 114 + index = addr & KVM_VGIC_V3_RDIST_INDEX_MASK; 153 115 154 116 if (write) { 155 - gpa_t base = *addr & KVM_VGIC_V3_RDIST_BASE_MASK; 156 - u32 count = (*addr & KVM_VGIC_V3_RDIST_COUNT_MASK) 157 - >> KVM_VGIC_V3_RDIST_COUNT_SHIFT; 158 - u8 flags = (*addr & KVM_VGIC_V3_RDIST_FLAGS_MASK) 159 - >> KVM_VGIC_V3_RDIST_FLAGS_SHIFT; 117 + gpa_t base = addr & KVM_VGIC_V3_RDIST_BASE_MASK; 118 + u32 count = FIELD_GET(KVM_VGIC_V3_RDIST_COUNT_MASK, addr); 119 + u8 flags = FIELD_GET(KVM_VGIC_V3_RDIST_FLAGS_MASK, addr); 160 120 161 121 if (!count || flags) 162 122 r = -EINVAL; ··· 170 134 goto out; 171 135 } 172 136 173 - *addr = index; 174 - *addr |= rdreg->base; 175 - *addr |= (u64)rdreg->count << KVM_VGIC_V3_RDIST_COUNT_SHIFT; 137 + addr = index; 138 + addr |= rdreg->base; 139 + addr |= (u64)rdreg->count << KVM_VGIC_V3_RDIST_COUNT_SHIFT; 176 140 goto out; 177 141 } 178 142 default: ··· 183 147 goto out; 184 148 185 149 if (write) { 186 - r = vgic_check_iorange(kvm, *addr_ptr, *addr, alignment, size); 150 + r = vgic_check_iorange(kvm, *addr_ptr, addr, alignment, size); 187 151 if (!r) 188 - *addr_ptr = *addr; 152 + *addr_ptr = addr; 189 153 } else { 190 - *addr = *addr_ptr; 154 + addr = *addr_ptr; 191 155 } 192 156 193 157 out: 194 158 mutex_unlock(&kvm->lock); 159 + 160 + if (!r && !write) 161 + r = put_user(addr, uaddr); 162 + 195 163 return r; 196 164 } 197 165 ··· 205 165 int r; 206 166 207 167 switch (attr->group) { 208 - case KVM_DEV_ARM_VGIC_GRP_ADDR: { 209 - u64 __user *uaddr = (u64 __user *)(long)attr->addr; 210 - u64 addr; 211 - unsigned long type = (unsigned long)attr->attr; 212 - 213 - if (copy_from_user(&addr, uaddr, sizeof(addr))) 214 - return -EFAULT; 215 - 216 - r = kvm_vgic_addr(dev->kvm, type, &addr, true); 168 + case KVM_DEV_ARM_VGIC_GRP_ADDR: 169 + r = kvm_vgic_addr(dev->kvm, attr, true); 217 170 return (r == -ENODEV) ? -ENXIO : r; 218 - } 219 171 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: { 220 172 u32 __user *uaddr = (u32 __user *)(long)attr->addr; 221 173 u32 val; ··· 246 214 r = vgic_init(dev->kvm); 247 215 mutex_unlock(&dev->kvm->lock); 248 216 return r; 217 + case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES: 218 + /* 219 + * OK, this one isn't common at all, but we 220 + * want to handle all control group attributes 221 + * in a single place. 222 + */ 223 + if (vgic_check_type(dev->kvm, KVM_DEV_TYPE_ARM_VGIC_V3)) 224 + return -ENXIO; 225 + mutex_lock(&dev->kvm->lock); 226 + 227 + if (!lock_all_vcpus(dev->kvm)) { 228 + mutex_unlock(&dev->kvm->lock); 229 + return -EBUSY; 230 + } 231 + r = vgic_v3_save_pending_tables(dev->kvm); 232 + unlock_all_vcpus(dev->kvm); 233 + mutex_unlock(&dev->kvm->lock); 234 + return r; 249 235 } 250 236 break; 251 237 } ··· 278 228 int r = -ENXIO; 279 229 280 230 switch (attr->group) { 281 - case KVM_DEV_ARM_VGIC_GRP_ADDR: { 282 - u64 __user *uaddr = (u64 __user *)(long)attr->addr; 283 - u64 addr; 284 - unsigned long type = (unsigned long)attr->attr; 285 - 286 - if (copy_from_user(&addr, uaddr, sizeof(addr))) 287 - return -EFAULT; 288 - 289 - r = kvm_vgic_addr(dev->kvm, type, &addr, false); 290 - if (r) 291 - return (r == -ENODEV) ? -ENXIO : r; 292 - 293 - if (copy_to_user(uaddr, &addr, sizeof(addr))) 294 - return -EFAULT; 295 - break; 296 - } 231 + case KVM_DEV_ARM_VGIC_GRP_ADDR: 232 + r = kvm_vgic_addr(dev->kvm, attr, false); 233 + return (r == -ENODEV) ? -ENXIO : r; 297 234 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: { 298 235 u32 __user *uaddr = (u32 __user *)(long)attr->addr; 299 236 ··· 385 348 * 386 349 * @dev: kvm device handle 387 350 * @attr: kvm device attribute 388 - * @reg: address the value is read or written 389 351 * @is_write: true if userspace is writing a register 390 352 */ 391 353 static int vgic_v2_attr_regs_access(struct kvm_device *dev, 392 354 struct kvm_device_attr *attr, 393 - u32 *reg, bool is_write) 355 + bool is_write) 394 356 { 357 + u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr; 395 358 struct vgic_reg_attr reg_attr; 396 359 gpa_t addr; 397 360 struct kvm_vcpu *vcpu; 398 361 int ret; 362 + u32 val; 399 363 400 364 ret = vgic_v2_parse_attr(dev, attr, &reg_attr); 401 365 if (ret) ··· 404 366 405 367 vcpu = reg_attr.vcpu; 406 368 addr = reg_attr.addr; 369 + 370 + if (is_write) 371 + if (get_user(val, uaddr)) 372 + return -EFAULT; 407 373 408 374 mutex_lock(&dev->kvm->lock); 409 375 ··· 422 380 423 381 switch (attr->group) { 424 382 case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: 425 - ret = vgic_v2_cpuif_uaccess(vcpu, is_write, addr, reg); 383 + ret = vgic_v2_cpuif_uaccess(vcpu, is_write, addr, &val); 426 384 break; 427 385 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 428 - ret = vgic_v2_dist_uaccess(vcpu, is_write, addr, reg); 386 + ret = vgic_v2_dist_uaccess(vcpu, is_write, addr, &val); 429 387 break; 430 388 default: 431 389 ret = -EINVAL; ··· 435 393 unlock_all_vcpus(dev->kvm); 436 394 out: 437 395 mutex_unlock(&dev->kvm->lock); 396 + 397 + if (!ret && !is_write) 398 + ret = put_user(val, uaddr); 399 + 438 400 return ret; 439 401 } 440 402 441 403 static int vgic_v2_set_attr(struct kvm_device *dev, 442 404 struct kvm_device_attr *attr) 443 405 { 444 - int ret; 445 - 446 - ret = vgic_set_common_attr(dev, attr); 447 - if (ret != -ENXIO) 448 - return ret; 449 - 450 406 switch (attr->group) { 451 407 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 452 - case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: { 453 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 454 - u32 reg; 455 - 456 - if (get_user(reg, uaddr)) 457 - return -EFAULT; 458 - 459 - return vgic_v2_attr_regs_access(dev, attr, &reg, true); 408 + case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: 409 + return vgic_v2_attr_regs_access(dev, attr, true); 410 + default: 411 + return vgic_set_common_attr(dev, attr); 460 412 } 461 - } 462 - 463 - return -ENXIO; 464 413 } 465 414 466 415 static int vgic_v2_get_attr(struct kvm_device *dev, 467 416 struct kvm_device_attr *attr) 468 417 { 469 - int ret; 470 - 471 - ret = vgic_get_common_attr(dev, attr); 472 - if (ret != -ENXIO) 473 - return ret; 474 - 475 418 switch (attr->group) { 476 419 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 477 - case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: { 478 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 479 - u32 reg = 0; 480 - 481 - ret = vgic_v2_attr_regs_access(dev, attr, &reg, false); 482 - if (ret) 483 - return ret; 484 - return put_user(reg, uaddr); 420 + case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: 421 + return vgic_v2_attr_regs_access(dev, attr, false); 422 + default: 423 + return vgic_get_common_attr(dev, attr); 485 424 } 486 - } 487 - 488 - return -ENXIO; 489 425 } 490 426 491 427 static int vgic_v2_has_attr(struct kvm_device *dev, ··· 532 512 * 533 513 * @dev: kvm device handle 534 514 * @attr: kvm device attribute 535 - * @reg: address the value is read or written 536 515 * @is_write: true if userspace is writing a register 537 516 */ 538 517 static int vgic_v3_attr_regs_access(struct kvm_device *dev, 539 518 struct kvm_device_attr *attr, 540 - u64 *reg, bool is_write) 519 + bool is_write) 541 520 { 542 521 struct vgic_reg_attr reg_attr; 543 522 gpa_t addr; 544 523 struct kvm_vcpu *vcpu; 524 + bool uaccess; 525 + u32 val; 545 526 int ret; 546 - u32 tmp32; 547 527 548 528 ret = vgic_v3_parse_attr(dev, attr, &reg_attr); 549 529 if (ret) ··· 551 531 552 532 vcpu = reg_attr.vcpu; 553 533 addr = reg_attr.addr; 534 + 535 + switch (attr->group) { 536 + case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: 537 + /* Sysregs uaccess is performed by the sysreg handling code */ 538 + uaccess = false; 539 + break; 540 + default: 541 + uaccess = true; 542 + } 543 + 544 + if (uaccess && is_write) { 545 + u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr; 546 + if (get_user(val, uaddr)) 547 + return -EFAULT; 548 + } 554 549 555 550 mutex_lock(&dev->kvm->lock); 556 551 ··· 581 546 582 547 switch (attr->group) { 583 548 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 584 - if (is_write) 585 - tmp32 = *reg; 586 - 587 - ret = vgic_v3_dist_uaccess(vcpu, is_write, addr, &tmp32); 588 - if (!is_write) 589 - *reg = tmp32; 549 + ret = vgic_v3_dist_uaccess(vcpu, is_write, addr, &val); 590 550 break; 591 551 case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: 592 - if (is_write) 593 - tmp32 = *reg; 594 - 595 - ret = vgic_v3_redist_uaccess(vcpu, is_write, addr, &tmp32); 596 - if (!is_write) 597 - *reg = tmp32; 552 + ret = vgic_v3_redist_uaccess(vcpu, is_write, addr, &val); 598 553 break; 599 - case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: { 600 - u64 regid; 601 - 602 - regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK); 603 - ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write, 604 - regid, reg); 554 + case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: 555 + ret = vgic_v3_cpu_sysregs_uaccess(vcpu, attr, is_write); 605 556 break; 606 - } 607 557 case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: { 608 558 unsigned int info, intid; 609 559 ··· 598 578 intid = attr->attr & 599 579 KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK; 600 580 ret = vgic_v3_line_level_info_uaccess(vcpu, is_write, 601 - intid, reg); 581 + intid, &val); 602 582 } else { 603 583 ret = -EINVAL; 604 584 } ··· 612 592 unlock_all_vcpus(dev->kvm); 613 593 out: 614 594 mutex_unlock(&dev->kvm->lock); 595 + 596 + if (!ret && uaccess && !is_write) { 597 + u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr; 598 + ret = put_user(val, uaddr); 599 + } 600 + 615 601 return ret; 616 602 } 617 603 618 604 static int vgic_v3_set_attr(struct kvm_device *dev, 619 605 struct kvm_device_attr *attr) 620 606 { 621 - int ret; 622 - 623 - ret = vgic_set_common_attr(dev, attr); 624 - if (ret != -ENXIO) 625 - return ret; 626 - 627 607 switch (attr->group) { 628 608 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 629 - case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: { 630 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 631 - u32 tmp32; 632 - u64 reg; 633 - 634 - if (get_user(tmp32, uaddr)) 635 - return -EFAULT; 636 - 637 - reg = tmp32; 638 - return vgic_v3_attr_regs_access(dev, attr, &reg, true); 609 + case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: 610 + case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: 611 + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: 612 + return vgic_v3_attr_regs_access(dev, attr, true); 613 + default: 614 + return vgic_set_common_attr(dev, attr); 639 615 } 640 - case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: { 641 - u64 __user *uaddr = (u64 __user *)(long)attr->addr; 642 - u64 reg; 643 - 644 - if (get_user(reg, uaddr)) 645 - return -EFAULT; 646 - 647 - return vgic_v3_attr_regs_access(dev, attr, &reg, true); 648 - } 649 - case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: { 650 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 651 - u64 reg; 652 - u32 tmp32; 653 - 654 - if (get_user(tmp32, uaddr)) 655 - return -EFAULT; 656 - 657 - reg = tmp32; 658 - return vgic_v3_attr_regs_access(dev, attr, &reg, true); 659 - } 660 - case KVM_DEV_ARM_VGIC_GRP_CTRL: { 661 - int ret; 662 - 663 - switch (attr->attr) { 664 - case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES: 665 - mutex_lock(&dev->kvm->lock); 666 - 667 - if (!lock_all_vcpus(dev->kvm)) { 668 - mutex_unlock(&dev->kvm->lock); 669 - return -EBUSY; 670 - } 671 - ret = vgic_v3_save_pending_tables(dev->kvm); 672 - unlock_all_vcpus(dev->kvm); 673 - mutex_unlock(&dev->kvm->lock); 674 - return ret; 675 - } 676 - break; 677 - } 678 - } 679 - return -ENXIO; 680 616 } 681 617 682 618 static int vgic_v3_get_attr(struct kvm_device *dev, 683 619 struct kvm_device_attr *attr) 684 620 { 685 - int ret; 686 - 687 - ret = vgic_get_common_attr(dev, attr); 688 - if (ret != -ENXIO) 689 - return ret; 690 - 691 621 switch (attr->group) { 692 622 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 693 - case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: { 694 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 695 - u64 reg; 696 - u32 tmp32; 697 - 698 - ret = vgic_v3_attr_regs_access(dev, attr, &reg, false); 699 - if (ret) 700 - return ret; 701 - tmp32 = reg; 702 - return put_user(tmp32, uaddr); 623 + case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS: 624 + case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: 625 + case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: 626 + return vgic_v3_attr_regs_access(dev, attr, false); 627 + default: 628 + return vgic_get_common_attr(dev, attr); 703 629 } 704 - case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: { 705 - u64 __user *uaddr = (u64 __user *)(long)attr->addr; 706 - u64 reg; 707 - 708 - ret = vgic_v3_attr_regs_access(dev, attr, &reg, false); 709 - if (ret) 710 - return ret; 711 - return put_user(reg, uaddr); 712 - } 713 - case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: { 714 - u32 __user *uaddr = (u32 __user *)(long)attr->addr; 715 - u64 reg; 716 - u32 tmp32; 717 - 718 - ret = vgic_v3_attr_regs_access(dev, attr, &reg, false); 719 - if (ret) 720 - return ret; 721 - tmp32 = reg; 722 - return put_user(tmp32, uaddr); 723 - } 724 - } 725 - return -ENXIO; 726 630 } 727 631 728 632 static int vgic_v3_has_attr(struct kvm_device *dev,
+3 -7
arch/arm64/kvm/vgic/vgic-mmio-v3.c
··· 986 986 iodev.base_addr = 0; 987 987 break; 988 988 } 989 - case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: { 990 - u64 reg, id; 991 - 992 - id = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK); 993 - return vgic_v3_has_cpu_sysregs_attr(vcpu, 0, id, &reg); 994 - } 989 + case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS: 990 + return vgic_v3_has_cpu_sysregs_attr(vcpu, attr); 995 991 default: 996 992 return -ENXIO; 997 993 } ··· 1154 1158 } 1155 1159 1156 1160 int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write, 1157 - u32 intid, u64 *val) 1161 + u32 intid, u32 *val) 1158 1162 { 1159 1163 if (intid % 32) 1160 1164 return -EINVAL;
+3 -3
arch/arm64/kvm/vgic/vgic-mmio.c
··· 775 775 } 776 776 } 777 777 778 - u64 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid) 778 + u32 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid) 779 779 { 780 780 int i; 781 - u64 val = 0; 781 + u32 val = 0; 782 782 int nr_irqs = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS; 783 783 784 784 for (i = 0; i < 32; i++) { ··· 798 798 } 799 799 800 800 void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid, 801 - const u64 val) 801 + const u32 val) 802 802 { 803 803 int i; 804 804 int nr_irqs = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+2 -2
arch/arm64/kvm/vgic/vgic-mmio.h
··· 207 207 int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev, 208 208 bool is_write, int offset, u32 *val); 209 209 210 - u64 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid); 210 + u32 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid); 211 211 212 212 void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid, 213 - const u64 val); 213 + const u32 val); 214 214 215 215 unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev); 216 216
+4 -5
arch/arm64/kvm/vgic/vgic.h
··· 245 245 int offset, u32 *val); 246 246 int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write, 247 247 int offset, u32 *val); 248 - int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, 249 - u64 id, u64 *val); 250 - int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, 251 - u64 *reg); 248 + int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, 249 + struct kvm_device_attr *attr, bool is_write); 250 + int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); 252 251 int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write, 253 - u32 intid, u64 *val); 252 + u32 intid, u32 *val); 254 253 int kvm_register_vgic_device(unsigned long type); 255 254 void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 256 255 void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr);
+1 -1
include/kvm/arm_vgic.h
··· 364 364 extern struct static_key_false vgic_v2_cpuif_trap; 365 365 extern struct static_key_false vgic_v3_cpuif_trap; 366 366 367 - int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write); 367 + int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr); 368 368 void kvm_vgic_early_init(struct kvm *kvm); 369 369 int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); 370 370 int kvm_vgic_create(struct kvm *kvm, u32 type);
+12 -5
tools/testing/selftests/kvm/aarch64/vgic_init.c
··· 663 663 664 664 if (!__kvm_test_create_device(v.vm, other)) { 665 665 ret = __kvm_test_create_device(v.vm, other); 666 - TEST_ASSERT(ret && errno == EINVAL, 666 + TEST_ASSERT(ret && (errno == EINVAL || errno == EEXIST), 667 667 "create GIC device while other version exists"); 668 668 } 669 669 ··· 691 691 { 692 692 int ret; 693 693 int pa_bits; 694 + int cnt_impl = 0; 694 695 695 696 pa_bits = vm_guest_mode_params[VM_MODE_DEFAULT].pa_bits; 696 697 max_phys_size = 1ULL << pa_bits; ··· 700 699 if (!ret) { 701 700 pr_info("Running GIC_v3 tests.\n"); 702 701 run_tests(KVM_DEV_TYPE_ARM_VGIC_V3); 703 - return 0; 702 + cnt_impl++; 704 703 } 705 704 706 705 ret = test_kvm_device(KVM_DEV_TYPE_ARM_VGIC_V2); 707 - __TEST_REQUIRE(!ret, "No GICv2 nor GICv3 support"); 706 + if (!ret) { 707 + pr_info("Running GIC_v2 tests.\n"); 708 + run_tests(KVM_DEV_TYPE_ARM_VGIC_V2); 709 + cnt_impl++; 710 + } 708 711 709 - pr_info("Running GIC_v2 tests.\n"); 710 - run_tests(KVM_DEV_TYPE_ARM_VGIC_V2); 712 + if (!cnt_impl) { 713 + print_skip("No GICv2 nor GICv3 support"); 714 + exit(KSFT_SKIP); 715 + } 711 716 return 0; 712 717 }