Commit cb86616c authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/ubsan-el2 into kvmarm-master/next



* kvm-arm64/ubsan-el2:
  : .
  : Add UBSAN support to the EL2 portion of KVM, reusing most of the
  : existing logic provided by CONFIG_IBSAN_TRAP.
  :
  : Patches courtesy of Mostafa Saleh.
  : .
  KVM: arm64: Handle UBSAN faults
  KVM: arm64: Introduce CONFIG_UBSAN_KVM_EL2
  ubsan: Remove regs from report_ubsan_failure()
  arm64: Introduce esr_is_ubsan_brk()

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents a90e0017 44669275
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -440,6 +440,11 @@ static inline bool esr_is_cfi_brk(unsigned long esr)
	       (esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE;
}

static inline bool esr_is_ubsan_brk(unsigned long esr)
{
	return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM;
}

static inline bool esr_fsc_is_translation_fault(unsigned long esr)
{
	esr = esr & ESR_ELx_FSC;
+2 −2
Original line number Diff line number Diff line
@@ -1118,7 +1118,7 @@ static struct break_hook kasan_break_hook = {
#ifdef CONFIG_UBSAN_TRAP
static int ubsan_handler(struct pt_regs *regs, unsigned long esr)
{
	die(report_ubsan_failure(regs, esr & UBSAN_BRK_MASK), regs, esr);
	die(report_ubsan_failure(esr & UBSAN_BRK_MASK), regs, esr);
	return DBG_HOOK_HANDLED;
}

@@ -1145,7 +1145,7 @@ int __init early_brk64(unsigned long addr, unsigned long esr,
		return kasan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
#ifdef CONFIG_UBSAN_TRAP
	if ((esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
	if (esr_is_ubsan_brk(esr))
		return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
	return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
+6 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@

#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <linux/ubsan.h>

#include <asm/esr.h>
#include <asm/exception.h>
@@ -474,6 +475,11 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
			print_nvhe_hyp_panic("BUG", panic_addr);
	} else if (IS_ENABLED(CONFIG_CFI_CLANG) && esr_is_cfi_brk(esr)) {
		kvm_nvhe_report_cfi_failure(panic_addr);
	} else if (IS_ENABLED(CONFIG_UBSAN_KVM_EL2) &&
		   ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
		   esr_is_ubsan_brk(esr)) {
		print_nvhe_hyp_panic(report_ubsan_failure(esr & UBSAN_BRK_MASK),
				     panic_addr);
	} else {
		print_nvhe_hyp_panic("panic", panic_addr);
	}
+6 −0
Original line number Diff line number Diff line
@@ -99,3 +99,9 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS), $(KBUILD_CFLAG
# causes a build failure. Remove profile optimization flags.
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%, $(KBUILD_CFLAGS))
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables

ifeq ($(CONFIG_UBSAN_KVM_EL2),y)
UBSAN_SANITIZE := y
# Always use brk and not hooks
ccflags-y += $(CFLAGS_UBSAN_TRAP)
endif
+1 −1
Original line number Diff line number Diff line
@@ -351,7 +351,7 @@ static noinstr bool handle_bug(struct pt_regs *regs)
	case BUG_UD1_UBSAN:
		if (IS_ENABLED(CONFIG_UBSAN_TRAP)) {
			pr_crit("%s at %pS\n",
				report_ubsan_failure(regs, ud_imm),
				report_ubsan_failure(ud_imm),
				(void *)regs->ip);
		}
		break;
Loading