From: kettenis Date: Thu, 10 Aug 2023 19:29:32 +0000 (+0000) Subject: The Lenovo X13s has broken firmware that makes it impossible to use PAC. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=83e0a8ee3ac8e296e818d14426c6708a905425f2;p=openbsd The Lenovo X13s has broken firmware that makes it impossible to use PAC. But other machines that use the same SoC work just fine. So instead of disabling this feature on all CPUs that implement the architectured algorithm, add an SMBIOS-based check that just disables the feature on these machines. This means we need to attach smbios0 before cpu0, which in turn means attaching efi0 earlier. tested by patrick@ --- diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index 8213130c3a6..d2d4381d19c 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.97 2023/07/16 16:13:46 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.98 2023/08/10 19:29:32 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -919,6 +919,16 @@ cpu_attach(struct device *parent, struct device *dev, void *aux) cpu_id_aa64pfr0 &= ~ID_AA64PFR0_EL2_MASK; cpu_id_aa64pfr0 &= ~ID_AA64PFR0_EL3_MASK; + /* + * Lenovo X13s ships with broken EL2 firmware that + * hangs the machine if we enable PAuth. + */ + if (hw_vendor && strcmp(hw_vendor, "LENOVO") == 0 && + hw_prod && strncmp(hw_prod, "21BX", 4) == 0) { + cpu_id_aa64isar1 &= ~ID_AA64ISAR1_APA_MASK; + cpu_id_aa64isar1 &= ~ID_AA64ISAR1_GPA_MASK; + } + cpu_identify(ci); if (OF_getproplen(ci->ci_node, "clocks") > 0) { @@ -945,7 +955,6 @@ cpu_init(void) { uint64_t id_aa64mmfr1, sctlr; uint64_t id_aa64pfr0; - uint64_t id_aa64isar1; uint64_t tcr; WRITE_SPECIALREG(ttbr0_el1, pmap_kernel()->pm_pt0pa); @@ -971,8 +980,8 @@ cpu_init(void) __asm volatile (".arch armv8.4-a; msr dit, #1"); /* Enable PAuth. */ - id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1); - if (ID_AA64ISAR1_API(id_aa64isar1) >= ID_AA64ISAR1_API_BASE) { + if (ID_AA64ISAR1_APA(cpu_id_aa64isar1) >= ID_AA64ISAR1_APA_BASE || + ID_AA64ISAR1_API(cpu_id_aa64isar1) >= ID_AA64ISAR1_API_BASE) { sctlr = READ_SPECIALREG(sctlr_el1); sctlr |= SCTLR_EnIA | SCTLR_EnDA; sctlr |= SCTLR_EnIB | SCTLR_EnDB; diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c index 6903db003b5..7bb689d5040 100644 --- a/sys/arch/arm64/arm64/pmap.c +++ b/sys/arch/arm64/arm64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.98 2023/06/11 21:42:01 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.99 2023/08/10 19:29:32 kettenis Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn * @@ -2231,7 +2231,8 @@ pmap_show_mapping(uint64_t va) void pmap_setpauthkeys(struct pmap *pm) { - if (ID_AA64ISAR1_API(cpu_id_aa64isar1) >= ID_AA64ISAR1_API_BASE) { + if (ID_AA64ISAR1_APA(cpu_id_aa64isar1) >= ID_AA64ISAR1_APA_BASE || + ID_AA64ISAR1_API(cpu_id_aa64isar1) >= ID_AA64ISAR1_API_BASE) { __asm volatile (".arch armv8.3-a; msr apiakeylo_el1, %0" :: "r"(pm->pm_apiakey[0])); __asm volatile (".arch armv8.3-a; msr apiakeyhi_el1, %0" @@ -2250,7 +2251,8 @@ pmap_setpauthkeys(struct pmap *pm) :: "r"(pm->pm_apdbkey[1])); } - if (ID_AA64ISAR1_GPI(cpu_id_aa64isar1) >= ID_AA64ISAR1_GPI_IMPL) { + if (ID_AA64ISAR1_GPA(cpu_id_aa64isar1) >= ID_AA64ISAR1_GPA_IMPL || + ID_AA64ISAR1_GPI(cpu_id_aa64isar1) >= ID_AA64ISAR1_GPI_IMPL) { __asm volatile (".arch armv8.3-a; msr apgakeylo_el1, %0" :: "r"(pm->pm_apgakey[0])); __asm volatile (".arch armv8.3-a; msr apgakeyhi_el1, %0" diff --git a/sys/arch/arm64/dev/mainbus.c b/sys/arch/arm64/dev/mainbus.c index 192e45c2f95..495a4ca286a 100644 --- a/sys/arch/arm64/dev/mainbus.c +++ b/sys/arch/arm64/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.27 2023/07/19 21:52:55 kettenis Exp $ */ +/* $OpenBSD: mainbus.c,v 1.28 2023/08/10 19:29:32 kettenis Exp $ */ /* * Copyright (c) 2016 Patrick Wildt * Copyright (c) 2017 Mark Kettenis @@ -133,6 +133,7 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) } mainbus_attach_psci(self); + mainbus_attach_efi(self); /* Attach primary CPU first. */ mainbus_attach_cpus(self, mainbus_match_primary); @@ -140,7 +141,6 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) /* Attach secondary CPUs. */ mainbus_attach_cpus(self, mainbus_match_secondary); - mainbus_attach_efi(self); mainbus_attach_firmware(self); mainbus_attach_resvmem(self);