Commit 1270dad3 authored by Oliver Upton's avatar Oliver Upton
Browse files

Merge branch kvm-arm64/el2-kcfi into kvmarm/next



* kvm-arm64/el2-kcfi:
  : kCFI support in the EL2 hypervisor, courtesy of Pierre-Clément Tosi
  :
  : Enable the usage fo CONFIG_CFI_CLANG (kCFI) for hardening indirect
  : branches in the EL2 hypervisor. Unlike kernel support for the feature,
  : CFI failures at EL2 are always fatal.
  KVM: arm64: nVHE: Support CONFIG_CFI_CLANG at EL2
  KVM: arm64: Introduce print_nvhe_hyp_panic helper
  arm64: Introduce esr_brk_comment, esr_is_cfi_brk
  KVM: arm64: VHE: Mark __hyp_call_panic __noreturn
  KVM: arm64: nVHE: gen-hyprel: Skip R_AARCH64_ABS32
  KVM: arm64: nVHE: Simplify invalid_host_el2_vect
  KVM: arm64: Fix __pkvm_init_switch_pgd call ABI
  KVM: arm64: Fix clobbered ELR in sync abort/SError

Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parents 377d0e5d eca4ba5b
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -380,6 +380,11 @@
#ifndef __ASSEMBLY__
#include <asm/types.h>

static inline unsigned long esr_brk_comment(unsigned long esr)
{
	return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
}

static inline bool esr_is_data_abort(unsigned long esr)
{
	const unsigned long ec = ESR_ELx_EC(esr);
@@ -387,6 +392,12 @@ static inline bool esr_is_data_abort(unsigned long esr)
	return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR;
}

static inline bool esr_is_cfi_brk(unsigned long esr)
{
	return ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
	       (esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE;
}

static inline bool esr_fsc_is_translation_fault(unsigned long esr)
{
	/* Translation fault, level -1 */
+2 −2
Original line number Diff line number Diff line
@@ -124,8 +124,8 @@ void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
#endif

#ifdef __KVM_NVHE_HYPERVISOR__
void __pkvm_init_switch_pgd(phys_addr_t phys, unsigned long size,
			    phys_addr_t pgd, void *sp, void *cont_fn);
void __pkvm_init_switch_pgd(phys_addr_t pgd, unsigned long sp,
		void (*fn)(void));
int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
		unsigned long *per_cpu_base, u32 hyp_va_bits);
void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
+1 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ int main(void)
  DEFINE(VCPU_FAULT_DISR,	offsetof(struct kvm_vcpu, arch.fault.disr_el1));
  DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
  DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_cpu_context, regs));
  DEFINE(CPU_ELR_EL2,		offsetof(struct kvm_cpu_context, sys_regs[ELR_EL2]));
  DEFINE(CPU_RGSR_EL1,		offsetof(struct kvm_cpu_context, sys_regs[RGSR_EL1]));
  DEFINE(CPU_GCR_EL1,		offsetof(struct kvm_cpu_context, sys_regs[GCR_EL1]));
  DEFINE(CPU_APIAKEYLO_EL1,	offsetof(struct kvm_cpu_context, sys_regs[APIAKEYLO_EL1]));
+1 −3
Original line number Diff line number Diff line
@@ -312,9 +312,7 @@ static int call_break_hook(struct pt_regs *regs, unsigned long esr)
	 * entirely not preemptible, and we can use rcu list safely here.
	 */
	list_for_each_entry_rcu(hook, list, node) {
		unsigned long comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;

		if ((comment & ~hook->mask) == hook->imm)
		if ((esr_brk_comment(esr) & ~hook->mask) == hook->imm)
			fn = hook->fn;
	}

+3 −5
Original line number Diff line number Diff line
@@ -1105,8 +1105,6 @@ static struct break_hook ubsan_break_hook = {
};
#endif

#define esr_comment(esr) ((esr) & ESR_ELx_BRK64_ISS_COMMENT_MASK)

/*
 * Initial handler for AArch64 BRK exceptions
 * This handler only used until debug_traps_init().
@@ -1115,15 +1113,15 @@ int __init early_brk64(unsigned long addr, unsigned long esr,
		struct pt_regs *regs)
{
#ifdef CONFIG_CFI_CLANG
	if ((esr_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE)
	if (esr_is_cfi_brk(esr))
		return cfi_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
#ifdef CONFIG_KASAN_SW_TAGS
	if ((esr_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM)
	if ((esr_brk_comment(esr) & ~KASAN_BRK_MASK) == KASAN_BRK_IMM)
		return kasan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
#ifdef CONFIG_UBSAN_TRAP
	if ((esr_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
	if ((esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
		return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
	return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
Loading