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 ...
Šī revīzija ir iekļauta:
@@ -394,7 +394,7 @@ static int __init gtdt_sbsa_gwdt_init(void)
|
||||
*/
|
||||
ret = acpi_gtdt_init(table, &timer_count);
|
||||
if (ret || !timer_count)
|
||||
return ret;
|
||||
goto out_put_gtdt;
|
||||
|
||||
for_each_platform_timer(platform_timer) {
|
||||
if (is_non_secure_watchdog(platform_timer)) {
|
||||
@@ -408,6 +408,8 @@ static int __init gtdt_sbsa_gwdt_init(void)
|
||||
if (gwdt_count)
|
||||
pr_info("found %d SBSA generic Watchdog(s).\n", gwdt_count);
|
||||
|
||||
out_put_gtdt:
|
||||
acpi_put_table(table);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -299,61 +299,8 @@ out:
|
||||
return status;
|
||||
}
|
||||
|
||||
struct iort_workaround_oem_info {
|
||||
char oem_id[ACPI_OEM_ID_SIZE + 1];
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
|
||||
u32 oem_revision;
|
||||
};
|
||||
|
||||
static bool apply_id_count_workaround;
|
||||
|
||||
static struct iort_workaround_oem_info wa_info[] __initdata = {
|
||||
{
|
||||
.oem_id = "HISI ",
|
||||
.oem_table_id = "HIP07 ",
|
||||
.oem_revision = 0,
|
||||
}, {
|
||||
.oem_id = "HISI ",
|
||||
.oem_table_id = "HIP08 ",
|
||||
.oem_revision = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static void __init
|
||||
iort_check_id_count_workaround(struct acpi_table_header *tbl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wa_info); i++) {
|
||||
if (!memcmp(wa_info[i].oem_id, tbl->oem_id, ACPI_OEM_ID_SIZE) &&
|
||||
!memcmp(wa_info[i].oem_table_id, tbl->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
|
||||
wa_info[i].oem_revision == tbl->oem_revision) {
|
||||
apply_id_count_workaround = true;
|
||||
pr_warn(FW_BUG "ID count for ID mapping entry is wrong, applying workaround\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 iort_get_map_max(struct acpi_iort_id_mapping *map)
|
||||
{
|
||||
u32 map_max = map->input_base + map->id_count;
|
||||
|
||||
/*
|
||||
* The IORT specification revision D (Section 3, table 4, page 9) says
|
||||
* Number of IDs = The number of IDs in the range minus one, but the
|
||||
* IORT code ignored the "minus one", and some firmware did that too,
|
||||
* so apply a workaround here to keep compatible with both the spec
|
||||
* compliant and non-spec compliant firmwares.
|
||||
*/
|
||||
if (apply_id_count_workaround)
|
||||
map_max--;
|
||||
|
||||
return map_max;
|
||||
}
|
||||
|
||||
static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
|
||||
u32 *rid_out)
|
||||
u32 *rid_out, bool check_overlap)
|
||||
{
|
||||
/* Single mapping does not care for input id */
|
||||
if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
|
||||
@@ -368,10 +315,37 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (rid_in < map->input_base || rid_in > iort_get_map_max(map))
|
||||
if (rid_in < map->input_base ||
|
||||
(rid_in > map->input_base + map->id_count))
|
||||
return -ENXIO;
|
||||
|
||||
if (check_overlap) {
|
||||
/*
|
||||
* We already found a mapping for this input ID at the end of
|
||||
* another region. If it coincides with the start of this
|
||||
* region, we assume the prior match was due to the off-by-1
|
||||
* issue mentioned below, and allow it to be superseded.
|
||||
* Otherwise, things are *really* broken, and we just disregard
|
||||
* duplicate matches entirely to retain compatibility.
|
||||
*/
|
||||
pr_err(FW_BUG "[map %p] conflicting mapping for input ID 0x%x\n",
|
||||
map, rid_in);
|
||||
if (rid_in != map->input_base)
|
||||
return -ENXIO;
|
||||
|
||||
pr_err(FW_BUG "applying workaround.\n");
|
||||
}
|
||||
|
||||
*rid_out = map->output_base + (rid_in - map->input_base);
|
||||
|
||||
/*
|
||||
* Due to confusion regarding the meaning of the id_count field (which
|
||||
* carries the number of IDs *minus 1*), we may have to disregard this
|
||||
* match if it is at the end of the range, and overlaps with the start
|
||||
* of another one.
|
||||
*/
|
||||
if (map->id_count > 0 && rid_in == map->input_base + map->id_count)
|
||||
return -EAGAIN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -414,6 +388,7 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
|
||||
static int iort_get_id_mapping_index(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu_v3 *smmu;
|
||||
struct acpi_iort_pmcg *pmcg;
|
||||
|
||||
switch (node->type) {
|
||||
case ACPI_IORT_NODE_SMMU_V3:
|
||||
@@ -441,6 +416,10 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node)
|
||||
|
||||
return smmu->id_mapping_index;
|
||||
case ACPI_IORT_NODE_PMCG:
|
||||
pmcg = (struct acpi_iort_pmcg *)node->node_data;
|
||||
if (pmcg->overflow_gsiv || node->mapping_count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -456,7 +435,8 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
|
||||
/* Parse the ID mapping tree to find specified node type */
|
||||
while (node) {
|
||||
struct acpi_iort_id_mapping *map;
|
||||
int i, index;
|
||||
int i, index, rc = 0;
|
||||
u32 out_ref = 0, map_id = id;
|
||||
|
||||
if (IORT_TYPE_MASK(node->type) & type_mask) {
|
||||
if (id_out)
|
||||
@@ -490,15 +470,18 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
|
||||
if (i == index)
|
||||
continue;
|
||||
|
||||
if (!iort_id_map(map, node->type, id, &id))
|
||||
rc = iort_id_map(map, node->type, map_id, &id, out_ref);
|
||||
if (!rc)
|
||||
break;
|
||||
if (rc == -EAGAIN)
|
||||
out_ref = map->output_reference;
|
||||
}
|
||||
|
||||
if (i == node->mapping_count)
|
||||
if (i == node->mapping_count && !out_ref)
|
||||
goto fail_map;
|
||||
|
||||
node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
|
||||
map->output_reference);
|
||||
rc ? out_ref : map->output_reference);
|
||||
}
|
||||
|
||||
fail_map:
|
||||
@@ -789,15 +772,6 @@ void acpi_configure_pmsi_domain(struct device *dev)
|
||||
dev_set_msi_domain(dev, msi_domain);
|
||||
}
|
||||
|
||||
static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
|
||||
void *data)
|
||||
{
|
||||
u32 *rid = data;
|
||||
|
||||
*rid = alias;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
|
||||
{
|
||||
@@ -1148,13 +1122,10 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||
else
|
||||
size = 1ULL << 32;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
|
||||
if (ret == -ENODEV)
|
||||
ret = rc_dma_get_range(dev, &size);
|
||||
} else {
|
||||
ret = nc_dma_get_range(dev, &size);
|
||||
}
|
||||
ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
|
||||
if (ret == -ENODEV)
|
||||
ret = dev_is_pci(dev) ? rc_dma_get_range(dev, &size)
|
||||
: nc_dma_get_range(dev, &size);
|
||||
|
||||
if (!ret) {
|
||||
/*
|
||||
@@ -1692,6 +1663,10 @@ void __init acpi_iort_init(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
/* iort_table will be used at runtime after the iort init,
|
||||
* so we don't need to call acpi_put_table() to release
|
||||
* the IORT table mapping.
|
||||
*/
|
||||
status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status != AE_NOT_FOUND) {
|
||||
@@ -1703,6 +1678,5 @@ void __init acpi_iort_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
iort_check_id_count_workaround(iort_table);
|
||||
iort_init_platform_devices();
|
||||
}
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user