diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-01 15:18:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-01 15:18:27 -0700 |
commit | 533b220f7be4e461a5222a223d169b42856741ef (patch) | |
tree | 3684fae5a676b31a4a75e275a0ee5519f0d3c6d9 /drivers/firmware | |
parent | 3ee3723b40d55f473b8c82c60ed0e67f1f9ec6b9 (diff) | |
parent | 082af5ec5080b028f7d0846a6c27cbb87f288205 (diff) |
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Will Deacon:
"A sizeable pile of arm64 updates for 5.8.
Summary below, but the big two features are support for Branch Target
Identification and Clang's Shadow Call stack. The latter is currently
arm64-only, but the high-level parts are all in core code so it could
easily be adopted by other architectures pending toolchain support
Branch Target Identification (BTI):
- Support for ARMv8.5-BTI in both user- and kernel-space. This allows
branch targets to limit the types of branch from which they can be
called and additionally prevents branching to arbitrary code,
although kernel support requires a very recent toolchain.
- Function annotation via SYM_FUNC_START() so that assembly functions
are wrapped with the relevant "landing pad" instructions.
- BPF and vDSO updates to use the new instructions.
- Addition of a new HWCAP and exposure of BTI capability to userspace
via ID register emulation, along with ELF loader support for the
BTI feature in .note.gnu.property.
- Non-critical fixes to CFI unwind annotations in the sigreturn
trampoline.
Shadow Call Stack (SCS):
- Support for Clang's Shadow Call Stack feature, which reserves
platform register x18 to point at a separate stack for each task
that holds only return addresses. This protects function return
control flow from buffer overruns on the main stack.
- Save/restore of x18 across problematic boundaries (user-mode,
hypervisor, EFI, suspend, etc).
- Core support for SCS, should other architectures want to use it
too.
- SCS overflow checking on context-switch as part of the existing
stack limit check if CONFIG_SCHED_STACK_END_CHECK=y.
CPU feature detection:
- Removed numerous "SANITY CHECK" errors when running on a system
with mismatched AArch32 support at EL1. This is primarily a concern
for KVM, which disabled support for 32-bit guests on such a system.
- Addition of new ID registers and fields as the architecture has
been extended.
Perf and PMU drivers:
- Minor fixes and cleanups to system PMU drivers.
Hardware errata:
- Unify KVM workarounds for VHE and nVHE configurations.
- Sort vendor errata entries in Kconfig.
Secure Monitor Call Calling Convention (SMCCC):
- Update to the latest specification from Arm (v1.2).
- Allow PSCI code to query the SMCCC version.
Software Delegated Exception Interface (SDEI):
- Unexport a bunch of unused symbols.
- Minor fixes to handling of firmware data.
Pointer authentication:
- Add support for dumping the kernel PAC mask in vmcoreinfo so that
the stack can be unwound by tools such as kdump.
- Simplification of key initialisation during CPU bringup.
BPF backend:
- Improve immediate generation for logical and add/sub instructions.
vDSO:
- Minor fixes to the linker flags for consistency with other
architectures and support for LLVM's unwinder.
- Clean up logic to initialise and map the vDSO into userspace.
ACPI:
- Work around for an ambiguity in the IORT specification relating to
the "num_ids" field.
- Support _DMA method for all named components rather than only PCIe
root complexes.
- Minor other IORT-related fixes.
Miscellaneous:
- Initialise debug traps early for KGDB and fix KDB cacheflushing
deadlock.
- Minor tweaks to early boot state (documentation update, set
TEXT_OFFSET to 0x0, increase alignment of PE/COFF sections).
- Refactoring and cleanup"
* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (148 commits)
KVM: arm64: Move __load_guest_stage2 to kvm_mmu.h
KVM: arm64: Check advertised Stage-2 page size capability
arm64/cpufeature: Add get_arm64_ftr_reg_nowarn()
ACPI/IORT: Remove the unused __get_pci_rid()
arm64/cpuinfo: Add ID_MMFR4_EL1 into the cpuinfo_arm64 context
arm64/cpufeature: Add remaining feature bits in ID_AA64PFR1 register
arm64/cpufeature: Add remaining feature bits in ID_AA64PFR0 register
arm64/cpufeature: Add remaining feature bits in ID_AA64ISAR0 register
arm64/cpufeature: Add remaining feature bits in ID_MMFR4 register
arm64/cpufeature: Add remaining feature bits in ID_PFR0 register
arm64/cpufeature: Introduce ID_MMFR5 CPU register
arm64/cpufeature: Introduce ID_DFR1 CPU register
arm64/cpufeature: Introduce ID_PFR2 CPU register
arm64/cpufeature: Make doublelock a signed feature in ID_AA64DFR0
arm64/cpufeature: Drop TraceFilt feature exposure from ID_DFR0 register
arm64/cpufeature: Add explicit ftr_id_isar0[] for ID_ISAR0 register
arm64: mm: Add asid_gen_match() helper
firmware: smccc: Fix missing prototype warning for arm_smccc_version_init
arm64: vdso: Fix CFI directives in sigreturn trampoline
arm64: vdso: Don't prefix sigreturn trampoline with a BTI C instruction
...
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/Kconfig | 6 | ||||
-rw-r--r-- | drivers/firmware/Makefile | 3 | ||||
-rw-r--r-- | drivers/firmware/arm_sdei.c | 49 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/Makefile | 3 | ||||
-rw-r--r-- | drivers/firmware/psci/psci.c | 21 | ||||
-rw-r--r-- | drivers/firmware/smccc/Kconfig | 16 | ||||
-rw-r--r-- | drivers/firmware/smccc/Makefile | 3 | ||||
-rw-r--r-- | drivers/firmware/smccc/smccc.c | 31 |
8 files changed, 83 insertions, 49 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 8007d4aa76dc..4843e94713a4 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -295,15 +295,13 @@ config TURRIS_MOX_RWTM other manufacturing data and also utilize the Entropy Bit Generator for hardware random number generation. -config HAVE_ARM_SMCCC - bool - -source "drivers/firmware/psci/Kconfig" source "drivers/firmware/broadcom/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" source "drivers/firmware/imx/Kconfig" source "drivers/firmware/meson/Kconfig" +source "drivers/firmware/psci/Kconfig" +source "drivers/firmware/smccc/Kconfig" source "drivers/firmware/tegra/Kconfig" source "drivers/firmware/xilinx/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index e9fb838af4df..99510be9f5ed 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -23,12 +23,13 @@ obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o obj-$(CONFIG_ARM_SCMI_PROTOCOL) += arm_scmi/ -obj-y += psci/ obj-y += broadcom/ obj-y += meson/ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ obj-$(CONFIG_EFI) += efi/ obj-$(CONFIG_UEFI_CPER) += efi/ obj-y += imx/ +obj-y += psci/ +obj-y += smccc/ obj-y += tegra/ obj-y += xilinx/ diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 334c8be0c11f..e7e36aab2386 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -429,7 +429,6 @@ int sdei_event_enable(u32 event_num) return err; } -EXPORT_SYMBOL(sdei_event_enable); static int sdei_api_event_disable(u32 event_num) { @@ -471,7 +470,6 @@ int sdei_event_disable(u32 event_num) return err; } -EXPORT_SYMBOL(sdei_event_disable); static int sdei_api_event_unregister(u32 event_num) { @@ -533,7 +531,6 @@ int sdei_event_unregister(u32 event_num) return err; } -EXPORT_SYMBOL(sdei_event_unregister); /* * unregister events, but don't destroy them as they are re-registered by @@ -643,7 +640,6 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg) return err; } -EXPORT_SYMBOL(sdei_event_register); static int sdei_reregister_event_llocked(struct sdei_event *event) { @@ -1079,26 +1075,9 @@ static struct platform_driver sdei_driver = { .probe = sdei_probe, }; -static bool __init sdei_present_dt(void) -{ - struct device_node *np, *fw_np; - - fw_np = of_find_node_by_name(NULL, "firmware"); - if (!fw_np) - return false; - - np = of_find_matching_node(fw_np, sdei_of_match); - if (!np) - return false; - of_node_put(np); - - return true; -} - static bool __init sdei_present_acpi(void) { acpi_status status; - struct platform_device *pdev; struct acpi_table_header *sdei_table_header; if (acpi_disabled) @@ -1113,20 +1092,26 @@ static bool __init sdei_present_acpi(void) if (ACPI_FAILURE(status)) return false; - pdev = platform_device_register_simple(sdei_driver.driver.name, 0, NULL, - 0); - if (IS_ERR(pdev)) - return false; + acpi_put_table(sdei_table_header); return true; } static int __init sdei_init(void) { - if (sdei_present_dt() || sdei_present_acpi()) - platform_driver_register(&sdei_driver); + int ret = platform_driver_register(&sdei_driver); - return 0; + if (!ret && sdei_present_acpi()) { + struct platform_device *pdev; + + pdev = platform_device_register_simple(sdei_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(pdev)) + pr_info("Failed to register ACPI:SDEI platform device %ld\n", + PTR_ERR(pdev)); + } + + return ret; } /* @@ -1143,6 +1128,14 @@ int sdei_event_handler(struct pt_regs *regs, mm_segment_t orig_addr_limit; u32 event_num = arg->event_num; + /* + * Save restore 'fs'. + * The architecture's entry code save/restores 'fs' when taking an + * exception from the kernel. This ensures addr_limit isn't inherited + * if you interrupted something that allowed the uaccess routines to + * access kernel memory. + * Do the same here because this doesn't come via the same entry code. + */ orig_addr_limit = get_fs(); set_fs(USER_DS); diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 034d71663b1e..cce4a7436052 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -33,6 +33,9 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ $(call cc-option,-fno-addrsig) \ -D__DISABLE_EXPORTS +# remove SCS flags from all objects in this directory +KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) + GCOV_PROFILE := n KASAN_SANITIZE := n UBSAN_SANITIZE := n diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 2937d44b5df4..92013ecc2d9e 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -46,25 +46,14 @@ * require cooperation with a Trusted OS driver. */ static int resident_cpu = -1; +struct psci_operations psci_ops; +static enum arm_smccc_conduit psci_conduit = SMCCC_CONDUIT_NONE; bool psci_tos_resident_on(int cpu) { return cpu == resident_cpu; } -struct psci_operations psci_ops = { - .conduit = SMCCC_CONDUIT_NONE, - .smccc_version = SMCCC_VERSION_1_0, -}; - -enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) -{ - if (psci_ops.smccc_version < SMCCC_VERSION_1_1) - return SMCCC_CONDUIT_NONE; - - return psci_ops.conduit; -} - typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); static psci_fn *invoke_psci_fn; @@ -242,7 +231,7 @@ static void set_conduit(enum arm_smccc_conduit conduit) WARN(1, "Unexpected PSCI conduit %d\n", conduit); } - psci_ops.conduit = conduit; + psci_conduit = conduit; } static int get_set_conduit_method(struct device_node *np) @@ -411,8 +400,8 @@ static void __init psci_init_smccc(void) if (feature != PSCI_RET_NOT_SUPPORTED) { u32 ret; ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0); - if (ret == ARM_SMCCC_VERSION_1_1) { - psci_ops.smccc_version = SMCCC_VERSION_1_1; + if (ret >= ARM_SMCCC_VERSION_1_1) { + arm_smccc_version_init(ret, psci_conduit); ver = ret; } } diff --git a/drivers/firmware/smccc/Kconfig b/drivers/firmware/smccc/Kconfig new file mode 100644 index 000000000000..27b675d76235 --- /dev/null +++ b/drivers/firmware/smccc/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +config HAVE_ARM_SMCCC + bool + help + Include support for the Secure Monitor Call (SMC) and Hypervisor + Call (HVC) instructions on Armv7 and above architectures. + +config HAVE_ARM_SMCCC_DISCOVERY + bool + depends on ARM_PSCI_FW + default y + help + SMCCC v1.0 lacked discoverability and hence PSCI v1.0 was updated + to add SMCCC discovery mechanism though the PSCI firmware + implementation of PSCI_FEATURES(SMCCC_VERSION) which returns + success on firmware compliant to SMCCC v1.1 and above. diff --git a/drivers/firmware/smccc/Makefile b/drivers/firmware/smccc/Makefile new file mode 100644 index 000000000000..6f369fe3f0b9 --- /dev/null +++ b/drivers/firmware/smccc/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +# +obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smccc.o diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c new file mode 100644 index 000000000000..4e80921ee212 --- /dev/null +++ b/drivers/firmware/smccc/smccc.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Arm Limited + */ + +#define pr_fmt(fmt) "smccc: " fmt + +#include <linux/init.h> +#include <linux/arm-smccc.h> + +static u32 smccc_version = ARM_SMCCC_VERSION_1_0; +static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE; + +void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) +{ + smccc_version = version; + smccc_conduit = conduit; +} + +enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) +{ + if (smccc_version < ARM_SMCCC_VERSION_1_1) + return SMCCC_CONDUIT_NONE; + + return smccc_conduit; +} + +u32 arm_smccc_get_version(void) +{ + return smccc_version; +} |