未验证 提交 a21ea4e1 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!1069 support ACPI for MPAM 2.0

Merge Pull Request from: @ci-robot 
 
PR sync from:  Yu Liao <liaoyu15@huawei.com>
 https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/thread/CQNKMRKUYC4EDBYHOMD6CXZQPZEJBMFY/ 
This patch series support ACPI for MPAM 2.0.

v5: fix unused variable warning.

v4: add PPTT null check to prevent NULL pointer deference.


Erik Kaneda (1):
  ACPICA: ACPI 6.4: PPTT: add new version of subtable type 1

Hesham Almatary (1):
  ACPICA: Add support for Arm's MPAM ACPI table version 2

Yu Liao (2):
  ACPI / PPTT: Find PPTT processor node by cache id
  ACPI/MPAM: Adapt to Arm's MPAM ACPI table version 2


-- 
2.25.1
 
 
Link:https://gitee.com/openeuler/kernel/pulls/1069 

Reviewed-by: Wang ShaoBo <bobo.shaobowang@huawei.com> 
Signed-off-by: Jialin Zhang <zhangjialin11@huawei.com> 
......@@ -1865,7 +1865,7 @@ static int __init arm_mpam_driver_init(void)
if (acpi_disabled)
return platform_driver_register(&arm_mpam_driver);
else
return acpi_mpam_parse();
return acpi_mpam_parse_version();
}
/*
......
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-$(CONFIG_ACPI_MPAM) += mpam.o
obj-$(CONFIG_ACPI_MPAM) += mpam.o mpam_v2.o
......@@ -32,6 +32,8 @@
#include <linux/nodemask.h>
#include <linux/arm_mpam.h>
extern int __init acpi_mpam_parse_table_v2(struct acpi_table_header *table,
struct acpi_table_header *pptt);
/**
* acpi_mpam_label_cache_component_id() - Recursivly find @min_physid
* for all leaf CPUs below @cpu_node, use numa node id of @min_cpu_node
......@@ -40,7 +42,7 @@
* @cpu_node: The point in the toplogy to start the walk
* @component_id: The id labels the structure mpam_node cache
*/
static int
int
acpi_mpam_label_cache_component_id(struct acpi_table_header *table_hdr,
struct acpi_pptt_processor *cpu_node,
u32 *component_id)
......@@ -187,10 +189,10 @@ static int __init acpi_mpam_parse_table(struct acpi_table_header *table,
pr_warn_once("Unknown node type %u offset %ld.",
node_hdr->type,
(table_offset-(char *)table));
/* fall through */
fallthrough;
case ACPI_MPAM_TYPE_SMMU:
/* not yet supported */
/* fall through */
fallthrough;
case ACPI_MPAM_TYPE_UNKNOWN:
break;
}
......@@ -213,7 +215,7 @@ static int __init acpi_mpam_parse_table(struct acpi_table_header *table,
return ret;
}
int __init acpi_mpam_parse(void)
int __init acpi_mpam_parse_version(void)
{
struct acpi_table_header *mpam, *pptt;
acpi_status status;
......@@ -234,7 +236,18 @@ int __init acpi_mpam_parse(void)
if (ACPI_FAILURE(status))
pptt = NULL;
ret = acpi_mpam_parse_table(mpam, pptt);
/*
* The BIOS of Kunpeng 920 supports MPAM ACPI 1.0, but the ACPI
* revision is wrongly written as 1, so distinguished by
* oem_table_id here.
*/
if (mpam->revision == 0 || strncmp(mpam->oem_table_id, "HIP08", 5) == 0)
ret = acpi_mpam_parse_table(mpam, pptt);
else if (mpam->revision == 1)
ret = acpi_mpam_parse_table_v2(mpam, pptt);
else
pr_err("unsupported MPAM ACPI version: %u\n", mpam->revision);
acpi_put_table(pptt);
acpi_put_table(mpam);
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Common code for ARM v8 MPAM ACPI 2.0
*
* Copyright (C) 2019-2022 Huawei Technologies Co., Ltd
*
* Author: Yu Liao <liaoyu15@huawei.com>
*
* Code was partially borrowed from http://www.linux-arm.org/git?p=
* linux-jm.git;a=commit;h=10fe7d6363ae96b25f584d4a91f9d0f2fd5faf3b.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
/* Parse the MPAM ACPI table feeding the discovered nodes into the driver */
#define pr_fmt(fmt) "ACPI MPAM: " fmt
#include <linux/acpi.h>
#include <acpi/processor.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cacheinfo.h>
#include <linux/string.h>
#include <linux/nodemask.h>
#include <linux/arm_mpam.h>
extern int
acpi_mpam_label_cache_component_id(struct acpi_table_header *table_hdr,
struct acpi_pptt_processor *cpu_node,
u32 *component_id);
static int __init acpi_mpam_parse_cache_v2(struct acpi_mpam_msc_node *msc,
struct acpi_table_header *pptt)
{
int ret = 0;
int level;
u32 component_id;
struct mpam_device *dev;
struct cacheinfo *ci;
struct acpi_pptt_processor *pptt_cpu_node;
struct acpi_mpam_resource_node *resources;
resources = (struct acpi_mpam_resource_node *)(msc + 1);
pptt_cpu_node = find_acpi_processor_node_from_cache_id(resources->locator.cache_locator.cache_reference);
if (!pptt_cpu_node) {
pr_err("Failed to find processor cpu node\n");
return -EINVAL;
}
ret = acpi_mpam_label_cache_component_id(pptt, pptt_cpu_node,
&component_id);
if (ret) {
pr_err("Failed to label cache component id\n");
return -EINVAL;
}
cpus_read_lock();
ci = cacheinfo_shared_cpu_map_search(pptt_cpu_node);
if (!ci) {
pr_err_once("No CPU has cache with PPTT reference %#llx",
resources->locator.cache_locator.cache_reference);
pr_err_once("All CPUs must be online to probe mpam.\n");
cpus_read_unlock();
return -ENODEV;
}
level = ci->level;
ci = NULL;
cpus_read_unlock();
/*
* Possible we can get cpu-affinity in next MPAM ACPI version,
* now we have to set it to NULL and use default possible_aff-
* inity.
*/
dev = mpam_device_create_cache(level, component_id, NULL,
msc->base_address);
if (IS_ERR(dev)) {
pr_err("Failed to create cache node\n");
return -EINVAL;
}
return mpam_register_device_irq(dev,
msc->overflow_interrupt, msc->overflow_interrupt_flags,
msc->error_interrupt, msc->error_interrupt_flags);
}
static int __init acpi_mpam_parse_memory_v2(struct acpi_mpam_msc_node *msc)
{
u32 component_id;
struct mpam_device *dev;
struct acpi_mpam_resource_node *resources;
resources = (struct acpi_mpam_resource_node *)(msc + 1);
component_id = acpi_map_pxm_to_node(resources->locator.memory_locator.proximity_domain);
if (component_id == NUMA_NO_NODE)
component_id = 0;
dev = mpam_device_create_memory(component_id, msc->base_address);
if (IS_ERR(dev)) {
pr_err("Failed to create memory node\n");
return -EINVAL;
}
return mpam_register_device_irq(dev,
msc->overflow_interrupt, msc->overflow_interrupt_flags,
msc->error_interrupt, msc->error_interrupt_flags);
}
int __init acpi_mpam_parse_table_v2(struct acpi_table_header *table,
struct acpi_table_header *pptt)
{
char *table_offset = (char *)(table + 1);
char *table_end = (char *)table + table->length;
struct acpi_mpam_msc_node *node_hdr;
struct acpi_mpam_resource_node *resources;
int ret = 0;
ret = mpam_discovery_start();
if (ret)
return ret;
node_hdr = (struct acpi_mpam_msc_node *)table_offset;
resources = (struct acpi_mpam_resource_node *)(node_hdr + 1);
while (table_offset < table_end) {
switch (resources->locator_type) {
case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE:
ret = acpi_mpam_parse_cache_v2(node_hdr, pptt);
break;
case ACPI_MPAM_LOCATION_TYPE_MEMORY:
ret = acpi_mpam_parse_memory_v2(node_hdr);
break;
default:
pr_warn_once("Unknown node type %u offset %ld.",
(resources->locator_type),
(table_offset-(char *)table));
fallthrough;
case ACPI_MPAM_LOCATION_TYPE_SMMU:
/* not yet supported */
fallthrough;
case ACPI_MPAM_TYPE_UNKNOWN:
break;
}
if (ret)
break;
table_offset += node_hdr->length;
node_hdr = (struct acpi_mpam_msc_node *)table_offset;
resources = (struct acpi_mpam_resource_node *)(node_hdr + 1);
}
if (ret) {
pr_err("discovery failed: %d\n", ret);
mpam_discovery_failed();
} else {
ret = mpam_discovery_complete();
if (!ret)
pr_info("Successfully init mpam by ACPI.\n");
}
return ret;
}
......@@ -958,3 +958,58 @@ int __init acpi_pptt_init(void)
return 0;
}
struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id)
{
u32 acpi_cpu_id;
acpi_status status;
int level, cpu, num_levels;
struct acpi_pptt_cache *cache;
struct acpi_table_header *table;
struct acpi_pptt_cache_v1 *cache_v1;
struct acpi_pptt_processor *cpu_node;
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
if (ACPI_FAILURE(status)) {
acpi_pptt_warn_missing();
return NULL;
}
if (table->revision < 3) {
acpi_put_table(table);
return NULL;
}
/*
* If we found the cache first, we'd still need to walk from each CPU
* to find the level...
*/
for_each_possible_cpu(cpu) {
acpi_cpu_id = get_acpi_id_for_cpu(cpu);
cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
if (!cpu_node)
break;
num_levels = acpi_count_levels(table, cpu_node);
for (level = 0; level <= num_levels; level++) {
cache = acpi_find_cache_node(table, acpi_cpu_id,
ACPI_PPTT_CACHE_TYPE_UNIFIED,
level, &cpu_node);
if (!cache)
continue;
cache_v1 = ACPI_ADD_PTR(struct acpi_pptt_cache_v1,
cache,
sizeof(struct acpi_pptt_cache));
if (cache->flags & ACPI_PPTT_CACHE_ID_VALID &&
cache_v1->cache_id == cache_id) {
acpi_put_table(table);
return cpu_node;
}
}
}
acpi_put_table(table);
return NULL;
}
......@@ -1106,6 +1106,117 @@ struct acpi_mpam_node_memory {
u8 reserved1[3];
};
/*******************************************************************************
*
* MPAM - Memory System Resource Partitioning and Monitoring
*
* Conforms to "ACPI for Memory System Resource Partitioning and Monitoring 2.0"
* Document number: ARM DEN 0065, December, 2022.
*
******************************************************************************/
/* MPAM RIS locator types. Table 11, Location types */
enum acpi_mpam_locator_type {
ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE = 0,
ACPI_MPAM_LOCATION_TYPE_MEMORY = 1,
ACPI_MPAM_LOCATION_TYPE_SMMU = 2,
ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE = 3,
ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE = 4,
ACPI_MPAM_LOCATION_TYPE_INTERCONNECT = 5,
ACPI_MPAM_LOCATION_TYPE_UNKNOWN = 0xFF
};
/* MPAM Functional dependency descriptor. Table 10 */
struct acpi_mpam_func_deps {
u32 producer;
u32 reserved;
};
/* MPAM Processor cache locator descriptor. Table 13 */
struct acpi_mpam_resource_cache_locator {
u64 cache_reference;
u32 reserved;
};
/* MPAM Memory locator descriptor. Table 14 */
struct acpi_mpam_resource_memory_locator {
u64 proximity_domain;
u32 reserved;
};
/* MPAM SMMU locator descriptor. Table 15 */
struct acpi_mpam_resource_smmu_locator {
u64 smmu_interface;
u32 reserved;
};
/* MPAM Memory-side cache locator descriptor. Table 16 */
struct acpi_mpam_resource_memcache_locator {
u8 reserved[7];
u8 level;
u32 reference;
};
/* MPAM ACPI device locator descriptor. Table 17 */
struct acpi_mpam_resource_acpi_locator {
u64 acpi_hw_id;
u32 acpi_unique_id;
};
/* MPAM Interconnect locator descriptor. Table 18 */
struct acpi_mpam_resource_interconnect_locator {
u64 inter_connect_desc_tbl_off;
u32 reserved;
};
/* MPAM Locator structure. Table 12 */
struct acpi_mpam_resource_generic_locator {
u64 descriptor1;
u32 descriptor2;
};
union acpi_mpam_resource_locator {
struct acpi_mpam_resource_cache_locator cache_locator;
struct acpi_mpam_resource_memory_locator memory_locator;
struct acpi_mpam_resource_smmu_locator smmu_locator;
struct acpi_mpam_resource_memcache_locator mem_cache_locator;
struct acpi_mpam_resource_acpi_locator acpi_locator;
struct acpi_mpam_resource_interconnect_locator interconnect_ifc_locator;
struct acpi_mpam_resource_generic_locator generic_locator;
};
/* Memory System Component Resource Node Structure Table 9 */
struct acpi_mpam_resource_node {
u32 identifier;
u8 ris_index;
u16 reserved1;
u8 locator_type;
union acpi_mpam_resource_locator locator;
u32 num_functional_deps;
};
/* Memory System Component (MSC) Node Structure. Table 4 */
struct acpi_mpam_msc_node {
u16 length;
u8 interface_type;
u8 reserved;
u32 identifier;
u64 base_address;
u32 mmio_size;
u32 overflow_interrupt;
u32 overflow_interrupt_flags;
u32 reserved1;
u32 overflow_interrupt_affinity;
u32 error_interrupt;
u32 error_interrupt_flags;
u32 reserved2;
u32 error_interrupt_affinity;
u32 max_nrdy_usec;
u64 hardware_id_linked_device;
u32 instance_id_linked_device;
u32 num_resouce_nodes;
};
/*******************************************************************************
*
* MSDM - Microsoft Data Management table
......@@ -1695,6 +1806,12 @@ struct acpi_pptt_cache {
u16 line_size;
};
/* 1: Cache Type Structure for PPTT version 3 */
struct acpi_pptt_cache_v1 {
u32 cache_id;
};
/* Flags */
#define ACPI_PPTT_SIZE_PROPERTY_VALID (1) /* Physical property valid */
......@@ -1704,6 +1821,7 @@ struct acpi_pptt_cache {
#define ACPI_PPTT_CACHE_TYPE_VALID (1<<4) /* Cache type valid */
#define ACPI_PPTT_WRITE_POLICY_VALID (1<<5) /* Write policy valid */
#define ACPI_PPTT_LINE_SIZE_VALID (1<<6) /* Line size valid */
#define ACPI_PPTT_CACHE_ID_VALID (1<<7) /* Cache ID valid */
/* Masks for Attributes */
......
......@@ -1367,6 +1367,7 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu);
int find_acpi_cpu_topology_package(unsigned int cpu);
int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id);
#else
static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
{
......@@ -1392,6 +1393,10 @@ static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
{
return -EINVAL;
}
static inline struct acpi_pptt_processor *find_acpi_processor_node_from_cache_id(u32 cache_id)
{
return NULL;
}
#endif
#ifdef CONFIG_ACPI
......
......@@ -116,6 +116,6 @@ static inline int mpam_register_device_irq(struct mpam_device *dev,
return ret;
}
int __init acpi_mpam_parse(void);
int __init acpi_mpam_parse_version(void);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册