From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
To support device tree boot for arm64 mpam, the __init macro might be used by the dts driver. This remove the necessary __init macro for the related functions.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Reviewed-by: Wang ShaoBo bobo.shaobowang@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/resctrl.h | 2 +- arch/arm64/kernel/mpam/mpam_device.c | 14 +++++++------- arch/arm64/kernel/mpam/mpam_internal.h | 2 +- arch/arm64/kernel/mpam/mpam_resctrl.c | 2 +- fs/resctrlfs.c | 2 +- include/linux/arm_mpam.h | 14 +++++++------- 6 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/include/asm/resctrl.h b/arch/arm64/include/asm/resctrl.h index ff4ce56430d1f..3fceaa482e5a3 100644 --- a/arch/arm64/include/asm/resctrl.h +++ b/arch/arm64/include/asm/resctrl.h @@ -424,7 +424,7 @@ int resctrl_update_groups_config(struct rdtgroup *rdtgrp);
#define RESCTRL_MAX_CLOSID 32
-int __init resctrl_group_init(void); +int resctrl_group_init(void);
void post_resctrl_mount(void);
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index c0615f6947a1f..4139b4476a836 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -534,7 +534,7 @@ static void mpam_disable_irqs(void) * Scheduled by mpam_discovery_complete() once all devices have been created. * Also scheduled when new devices are probed when new CPUs come online. */ -static void __init mpam_enable(struct work_struct *work) +static void mpam_enable(struct work_struct *work) { int err; unsigned long flags; @@ -761,7 +761,7 @@ static struct mpam_class * __init mpam_class_get(u8 level_idx, * class/component structures may be allocated. * Returns the new device, or an ERR_PTR(). */ -struct mpam_device * __init +struct mpam_device * __mpam_device_create(u8 level_idx, enum mpam_class_types type, int component_id, const struct cpumask *fw_affinity, phys_addr_t hwpage_address) @@ -810,7 +810,7 @@ __mpam_device_create(u8 level_idx, enum mpam_class_types type, return dev; }
-void __init mpam_device_set_error_irq(struct mpam_device *dev, u32 irq, +void mpam_device_set_error_irq(struct mpam_device *dev, u32 irq, u32 flags) { unsigned long irq_save_flags; @@ -821,7 +821,7 @@ void __init mpam_device_set_error_irq(struct mpam_device *dev, u32 irq, spin_unlock_irqrestore(&dev->lock, irq_save_flags); }
-void __init mpam_device_set_overflow_irq(struct mpam_device *dev, u32 irq, +void mpam_device_set_overflow_irq(struct mpam_device *dev, u32 irq, u32 flags) { unsigned long irq_save_flags; @@ -864,7 +864,7 @@ static inline u16 mpam_cpu_max_pmg(void) /* * prepare for initializing devices. */ -int __init mpam_discovery_start(void) +int mpam_discovery_start(void) { if (!mpam_cpus_have_feature()) return -EOPNOTSUPP; @@ -1104,7 +1104,7 @@ static int mpam_cpu_offline(unsigned int cpu) return 0; }
-int __init mpam_discovery_complete(void) +int mpam_discovery_complete(void) { int ret = 0;
@@ -1121,7 +1121,7 @@ int __init mpam_discovery_complete(void) return ret; }
-void __init mpam_discovery_failed(void) +void mpam_discovery_failed(void) { struct mpam_class *class, *tmp;
diff --git a/arch/arm64/kernel/mpam/mpam_internal.h b/arch/arm64/kernel/mpam/mpam_internal.h index cfaef82428aa5..7b84ea54975aa 100644 --- a/arch/arm64/kernel/mpam/mpam_internal.h +++ b/arch/arm64/kernel/mpam/mpam_internal.h @@ -329,7 +329,7 @@ int mpam_resctrl_setup(void); struct raw_resctrl_resource * mpam_get_raw_resctrl_resource(u32 level);
-int __init mpam_resctrl_init(void); +int mpam_resctrl_init(void);
int mpam_resctrl_set_default_cpu(unsigned int cpu); void mpam_resctrl_clear_default_cpu(unsigned int cpu); diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 51cdefebaeba8..1ad4cd49762a3 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -2209,7 +2209,7 @@ static int __init mpam_setup(char *str) } __setup("mpam", mpam_setup);
-int __init mpam_resctrl_init(void) +int mpam_resctrl_init(void) { mpam_init_padding();
diff --git a/fs/resctrlfs.c b/fs/resctrlfs.c index 11741c87eb0af..ea9df7d77b95a 100644 --- a/fs/resctrlfs.c +++ b/fs/resctrlfs.c @@ -1029,7 +1029,7 @@ static int __init resctrl_group_setup_root(void) * * Return: 0 on success or -errno */ -int __init resctrl_group_init(void) +int resctrl_group_init(void) { int ret = 0;
diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h index 44d0690ae8c4b..a242d4fdff8b3 100644 --- a/include/linux/arm_mpam.h +++ b/include/linux/arm_mpam.h @@ -16,7 +16,7 @@ enum mpam_class_types { MPAM_CLASS_UNKNOWN, /* Everything else, e.g. TLBs etc */ };
-struct mpam_device * __init +struct mpam_device * __mpam_device_create(u8 level_idx, enum mpam_class_types type, int component_id, const struct cpumask *fw_affinity, phys_addr_t hwpage_address); @@ -54,9 +54,9 @@ mpam_device_create_memory(int nid, phys_addr_t hwpage_address) return __mpam_device_create(~0, MPAM_CLASS_MEMORY, nid, &dev_affinity, hwpage_address); } -int __init mpam_discovery_start(void); -int __init mpam_discovery_complete(void); -void __init mpam_discovery_failed(void); +int mpam_discovery_start(void); +int mpam_discovery_complete(void); +void mpam_discovery_failed(void);
enum mpam_enable_type { MPAM_ENABLE_DENIED = 0, @@ -71,12 +71,12 @@ extern enum mpam_enable_type mpam_enabled; #define mpam_irq_flags_to_acpi(x) ((x & MPAM_IRQ_MODE_LEVEL) ? \ ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE)
-void __init mpam_device_set_error_irq(struct mpam_device *dev, u32 irq, +void mpam_device_set_error_irq(struct mpam_device *dev, u32 irq, u32 flags); -void __init mpam_device_set_overflow_irq(struct mpam_device *dev, u32 irq, +void mpam_device_set_overflow_irq(struct mpam_device *dev, u32 irq, u32 flags);
-static inline int __init mpam_register_device_irq(struct mpam_device *dev, +static inline int mpam_register_device_irq(struct mpam_device *dev, u32 overflow_interrupt, u32 overflow_flags, u32 error_interrupt, u32 error_flags) {
From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
For now, only ACPI boot is supported for the arm64 mpam init. This introduce device tree support, treat the mpam device as a platform device, add a platform driver and use of interface to parse the dts node. Add a common init function to call the device tree or ACPI init procedure, according to whether ACPI is disabled and the boot arguments.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Reviewed-by: Wang ShaoBo bobo.shaobowang@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/kernel/mpam/mpam_device.c | 169 ++++++++++++++++++++++++++ arch/arm64/kernel/mpam/mpam_resctrl.c | 2 + drivers/acpi/arm64/mpam.c | 6 - include/linux/arm_mpam.h | 3 + 4 files changed, 174 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 4139b4476a836..4910e99348798 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -32,6 +32,8 @@ #include <linux/cpu.h> #include <linux/cacheinfo.h> #include <linux/arm_mpam.h> +#include <linux/of.h> +#include <linux/of_platform.h>
#include "mpam_resource.h" #include "mpam_device.h" @@ -1708,3 +1710,170 @@ void mpam_component_get_config(struct mpam_component *comp, { mpam_component_get_config_local(comp, args, result); } + +#define ARM_MPAM_PDEV_NAME "arm-mpam" + +static const struct of_device_id arm_mpam_of_device_ids[] = { + {.compatible = "arm,mpam"}, +}; + +static int of_mpam_parse_irq(struct platform_device *pdev, + struct mpam_device *dev) +{ + struct device_node *node = pdev->dev.of_node; + u32 overflow_interrupt, overflow_flags; + u32 error_interrupt, error_interrupt_flags; + + of_property_read_u32(node, "overflow-interrupt", &overflow_interrupt); + of_property_read_u32(node, "overflow-flags", &overflow_flags); + of_property_read_u32(node, "error-interrupt", &error_interrupt); + of_property_read_u32(node, "error-interrupt-flags", + &error_interrupt_flags); + + return mpam_register_device_irq(dev, + overflow_interrupt, overflow_flags, + error_interrupt, error_interrupt_flags); +} + +static int of_mpam_parse_cache(struct platform_device *pdev) +{ + struct mpam_device *dev; + struct device_node *node = pdev->dev.of_node; + int cache_level, cache_id; + struct resource *res; + + if (of_property_read_u32(node, "cache-level", &cache_level)) { + dev_err(&pdev->dev, "missing cache level property\n"); + return -EINVAL; + } + + if (of_property_read_u32(node, "cache-id", &cache_id)) { + dev_err(&pdev->dev, "missing cache id property\n"); + return -EINVAL; + } + + /* Base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing io resource property\n"); + return -EINVAL; + } + + dev = mpam_device_create_cache(cache_level, cache_id, NULL, res->start); + if (IS_ERR(dev)) { + dev_err(&pdev->dev, "Failed to create cache node\n"); + return -EINVAL; + } + + return of_mpam_parse_irq(pdev, dev); +} + +static int of_mpam_parse_memory(struct platform_device *pdev) +{ + struct mpam_device *dev; + struct device_node *node = pdev->dev.of_node; + int numa_id; + struct resource *res; + + if (of_property_read_u32(node, "numa-node-id", &numa_id)) { + dev_err(&pdev->dev, "missing numa node id property\n"); + return -EINVAL; + } + + /* Base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing io resource property\n"); + return -EINVAL; + } + + dev = mpam_device_create_memory(numa_id, res->start); + if (IS_ERR(dev)) { + dev_err(&pdev->dev, "Failed to create memory node\n"); + return -EINVAL; + } + + return of_mpam_parse_irq(pdev, dev); +} + +static int of_mpam_parse(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + enum mpam_class_types type; + + if (!node || !of_match_node(arm_mpam_of_device_ids, pdev->dev.of_node)) + return -EINVAL; + + if (of_property_read_u32(dev->of_node, "type", &type)) { + dev_err(dev, "missing type property\n"); + return -EINVAL; + } + + switch (type) { + case MPAM_CLASS_CACHE: + return of_mpam_parse_cache(pdev); + case MPAM_CLASS_MEMORY: + return of_mpam_parse_memory(pdev); + default: + pr_warn_once("Unknown node type %u.\n", type); + return -EINVAL; + /* fall through */ + case MPAM_CLASS_SMMU: + /* not yet supported */ + /* fall through */ + case MPAM_CLASS_UNKNOWN: + break; + } + + return 0; +} + +static int arm_mpam_device_probe(struct platform_device *pdev) +{ + int ret; + + if (!cpus_have_const_cap(ARM64_HAS_MPAM)) + return 0; + + if (!acpi_disabled || mpam_enabled != MPAM_ENABLE_OF) + return 0; + + ret = mpam_discovery_start(); + if (ret) + return ret; + + ret = of_mpam_parse(pdev); + + if (ret) { + mpam_discovery_failed(); + } else { + ret = mpam_discovery_complete(); + if (!ret) + pr_info("Successfully init mpam by DT.\n"); + } + + return ret; +} + +static struct platform_driver arm_mpam_driver = { + .driver = { + .name = ARM_MPAM_PDEV_NAME, + .of_match_table = arm_mpam_of_device_ids, + }, + .probe = arm_mpam_device_probe, +}; + +static int __init arm_mpam_driver_init(void) +{ + if (acpi_disabled) + return platform_driver_register(&arm_mpam_driver); + else + return acpi_mpam_parse(); +} + +/* + * We want to run after cacheinfo_sysfs_init() has caused the cacheinfo + * structures to be populated. That runs as a device_initcall. + */ +device_initcall(arm_mpam_driver_init); diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 1ad4cd49762a3..fe2dcf92100f8 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -2204,6 +2204,8 @@ static int __init mpam_setup(char *str) { if (!strcmp(str, "=acpi")) mpam_enabled = MPAM_ENABLE_ACPI; + else if (!strcmp(str, "=of")) + mpam_enabled = MPAM_ENABLE_OF;
return 1; } diff --git a/drivers/acpi/arm64/mpam.c b/drivers/acpi/arm64/mpam.c index 51419473f63be..6f4572193eb22 100644 --- a/drivers/acpi/arm64/mpam.c +++ b/drivers/acpi/arm64/mpam.c @@ -240,9 +240,3 @@ int __init acpi_mpam_parse(void)
return ret; } - -/* - * We want to run after cacheinfo_sysfs_init() has caused the cacheinfo - * structures to be populated. That runs as a device_initcall. - */ -device_initcall_sync(acpi_mpam_parse); diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h index a242d4fdff8b3..eed95ba06a5d3 100644 --- a/include/linux/arm_mpam.h +++ b/include/linux/arm_mpam.h @@ -61,6 +61,7 @@ void mpam_discovery_failed(void); enum mpam_enable_type { MPAM_ENABLE_DENIED = 0, MPAM_ENABLE_ACPI, + MPAM_ENABLE_OF, };
extern enum mpam_enable_type mpam_enabled; @@ -115,4 +116,6 @@ static inline int mpam_register_device_irq(struct mpam_device *dev, return ret; }
+int __init acpi_mpam_parse(void); + #endif
From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
Add devicetree bindings document for arm64/mpam, this add basic description for the main properties of mpam devicetree definition.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Reviewed-by: Wang ShaoBo bobo.shaobowang@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../devicetree/bindings/arm/arm,mpam.txt | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/arm,mpam.txt
diff --git a/Documentation/devicetree/bindings/arm/arm,mpam.txt b/Documentation/devicetree/bindings/arm/arm,mpam.txt new file mode 100644 index 0000000000000..65c1e6809685e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/arm,mpam.txt @@ -0,0 +1,54 @@ +Memory System Resource Partitioning and Monitoring (MPAM), for Armv8-A +---------------------------------------------------------- + +The MPAM is used to limit memory bandwidth and cache usage for ARM platform. +The required properties for driver is: + compatible = "arm,mpam"; /* MPAM for Arm */ + reg = <>; /* mpam device base register */ + +The property type must be included, it is used to indicate type of mpam +device for the node. There are several type of mpam device: + MPAM_CLASS_SMMU = 0, + MPAM_CLASS_CACHE, /* Well known caches, e.g. L2 */ + MPAM_CLASS_MEMORY, /* Main memory */ + MPAM_CLASS_UNKNOWN, /* Everything else, e.g. TLBs etc */ + +The type of memory is set as: + type = <2>; +The type of cache is set as: + type = <1>; + +MPAM support interrupt for error and overflow, the error-interrupt and +overflow-interrupt are defined in "Memory System Resource Partitioning +and Monitoring (MPAM), for Armv8-A", MPAM interrupts(section 8.8). + overflow-interrupt = <0>; + overflow-flags = <0>; + error-interrupt = <0>; + error-interrupt-flags = <0>; + +Example: + +mpam_memory0 { + compatible = "arm,mpam"; + reg = <0x0 0x10000000 0x0 0x10000>; + type = <2>; /* memory type */ + numa-node-id = <0>; + overflow-interrupt = <0>; + overflow-flags = <0>; + error-interrupt = <0>; + error-interrupt-flags = <0>; + not-ready-max = <0>; +}; + +mpam_cache0 { + compatible = "arm,mpam"; + reg = <0x0 0x20000000 0x0 0x10000>; + type = <1>; /* cache type */ + cache-id = <0>; + cache-level = <3>; + overflow-interrupt = <0>; + overflow-flags = <0>; + error-interrupt = <0>; + error-interrupt-flags = <0>; + not-ready-max = <0>; +};