From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
Fix modpost Section mismatch error in __mpam_device_create() and others. These warnings will occur in high version gcc, for example 10.1.0.
[...] WARNING: vmlinux.o(.text+0x2ed88): Section mismatch in reference from the function __mpam_device_create() to the function .init.text:mpam_device_alloc() The function __mpam_device_create() references the function __init mpam_device_alloc(). This is often because __mpam_device_create lacks a __init annotation or the annotation of mpam_device_alloc is wrong.
WARNING: vmlinux.o(.text.unlikely+0xa5c): Section mismatch in reference from the function mpam_resctrl_init() to the function .init.text:mpam_init_padding() The function mpam_resctrl_init() references the function __init mpam_init_padding(). This is often because mpam_resctrl_init lacks a __init annotation or the annotation of mpam_init_padding is wrong.
WARNING: vmlinux.o(.text.unlikely+0x5a9c): Section mismatch in reference from the function resctrl_group_init() to the function .init.text:resctrl_group_setup_root() The function resctrl_group_init() references the function __init resctrl_group_setup_root(). This is often because resctrl_group_init lacks a __init annotation or the annotation of resctrl_group_setup_root is wrong. [...]
Fixes: c5e27c395a70 ("arm64/mpam: remove __init macro to support driver probe") Signed-off-by: Xingang Wang wangxingang5@huawei.com Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- arch/arm64/kernel/mpam/mpam_device.c | 8 ++++---- arch/arm64/kernel/mpam/mpam_resctrl.c | 2 +- fs/resctrlfs.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 4e882e81cf41..5d34751f8c3e 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -621,7 +621,7 @@ static void mpam_failed(struct work_struct *work) mutex_unlock(&mpam_cpuhp_lock); }
-static struct mpam_device * __init +static struct mpam_device * mpam_device_alloc(struct mpam_component *comp) { struct mpam_device *dev; @@ -656,7 +656,7 @@ static void mpam_devices_destroy(struct mpam_component *comp) } }
-static struct mpam_component * __init mpam_component_alloc(int id) +static struct mpam_component *mpam_component_alloc(int id) { struct mpam_component *comp;
@@ -694,7 +694,7 @@ struct mpam_component *mpam_component_get(struct mpam_class *class, int id, return comp; }
-static struct mpam_class * __init mpam_class_alloc(u8 level_idx, +static struct mpam_class *mpam_class_alloc(u8 level_idx, enum mpam_class_types type) { struct mpam_class *class; @@ -733,7 +733,7 @@ static void mpam_class_destroy(struct mpam_class *class) } }
-static struct mpam_class * __init mpam_class_get(u8 level_idx, +static struct mpam_class *mpam_class_get(u8 level_idx, enum mpam_class_types type, bool alloc) { diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index fe2dcf92100f..183c83d4274f 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -1135,7 +1135,7 @@ void closid_free(int closid) * Choose a width for the resource name and resource data based on the * resource that has widest name and cbm. */ -static __init void mpam_init_padding(void) +static void mpam_init_padding(void) { int cl; struct mpam_resctrl_res *res; diff --git a/fs/resctrlfs.c b/fs/resctrlfs.c index ea9df7d77b95..0e6753012140 100644 --- a/fs/resctrlfs.c +++ b/fs/resctrlfs.c @@ -989,7 +989,7 @@ static void resctrl_group_default_init(struct resctrl_group *r) r->type = RDTCTRL_GROUP; }
-static int __init resctrl_group_setup_root(void) +static int resctrl_group_setup_root(void) { int ret;
From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
The process of MPAM device tree initialization is like this: arm_mpam_device_probe() // driver probe mpam_discovery_start() // start discover mpam devices [...] // find and add mpam devices mpam_discovery_complete() // trigger mpam_enable
When there are multiple mpam device nodes, the driver probe procedure will execute more than once. However, the mpam_discovery_start() and mpam_discovery_complete() should only run once. Besides, the start should run first, and the complete should run after all devices added.
So we reorganize the device tree structure, so that there will be only one mpam device parent nodes, and the probe procedure will only run once. We add the child node to represent the mpam devices, and traverse and add all mpam devices in the middle procedure of driver probe.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- arch/arm64/kernel/mpam/mpam_device.c | 59 +++++++++++++++------------- 1 file changed, 32 insertions(+), 27 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 5d34751f8c3e..6455c69f132f 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -34,6 +34,7 @@ #include <linux/arm_mpam.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/of_address.h>
#include "mpam_resource.h" #include "mpam_device.h" @@ -1718,10 +1719,9 @@ static const struct of_device_id arm_mpam_of_device_ids[] = { { } };
-static int of_mpam_parse_irq(struct platform_device *pdev, +static int of_mpam_parse_irq(struct device_node *node, struct mpam_device *dev) { - struct device_node *node = pdev->dev.of_node; u32 overflow_interrupt, overflow_flags; u32 error_interrupt, error_interrupt_flags;
@@ -1736,12 +1736,12 @@ static int of_mpam_parse_irq(struct platform_device *pdev, error_interrupt, error_interrupt_flags); }
-static int of_mpam_parse_cache(struct platform_device *pdev) +static int of_mpam_parse_cache(struct platform_device *pdev, + struct device_node *node) { struct mpam_device *dev; - struct device_node *node = pdev->dev.of_node; int cache_level, cache_id; - struct resource *res; + u64 reg_value[2];
if (of_property_read_u32(node, "cache-level", &cache_level)) { dev_err(&pdev->dev, "missing cache level property\n"); @@ -1754,27 +1754,27 @@ static int of_mpam_parse_cache(struct platform_device *pdev) }
/* Base address */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { + if (of_property_read_u64_array(node, "reg", reg_value, 2)) { dev_err(&pdev->dev, "missing io resource property\n"); return -EINVAL; }
- dev = mpam_device_create_cache(cache_level, cache_id, NULL, res->start); + dev = mpam_device_create_cache(cache_level, cache_id, NULL, + reg_value[0]); if (IS_ERR(dev)) { dev_err(&pdev->dev, "Failed to create cache node\n"); return -EINVAL; }
- return of_mpam_parse_irq(pdev, dev); + return of_mpam_parse_irq(node, dev); }
-static int of_mpam_parse_memory(struct platform_device *pdev) +static int of_mpam_parse_memory(struct platform_device *pdev, + struct device_node *node) { struct mpam_device *dev; - struct device_node *node = pdev->dev.of_node; int numa_id; - struct resource *res; + u64 reg_value[2];
if (of_property_read_u32(node, "numa-node-id", &numa_id)) { dev_err(&pdev->dev, "missing numa node id property\n"); @@ -1782,40 +1782,35 @@ static int of_mpam_parse_memory(struct platform_device *pdev) }
/* Base address */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { + if (of_property_read_u64_array(node, "reg", reg_value, 2)) { dev_err(&pdev->dev, "missing io resource property\n"); return -EINVAL; }
- dev = mpam_device_create_memory(numa_id, res->start); + dev = mpam_device_create_memory(numa_id, reg_value[0]); if (IS_ERR(dev)) { dev_err(&pdev->dev, "Failed to create memory node\n"); return -EINVAL; }
- return of_mpam_parse_irq(pdev, dev); + return of_mpam_parse_irq(node, dev); }
-static int of_mpam_parse(struct platform_device *pdev) +static int of_mpam_add_child(struct platform_device *pdev, + struct device_node *node) { - 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"); + if (of_property_read_u32(node, "type", &type)) { + dev_err(&pdev->dev, "missing type property\n"); return -EINVAL; }
switch (type) { case MPAM_CLASS_CACHE: - return of_mpam_parse_cache(pdev); + return of_mpam_parse_cache(pdev, node); case MPAM_CLASS_MEMORY: - return of_mpam_parse_memory(pdev); + return of_mpam_parse_memory(pdev, node); default: pr_warn_once("Unknown node type %u.\n", type); return -EINVAL; @@ -1833,6 +1828,9 @@ static int of_mpam_parse(struct platform_device *pdev) static int arm_mpam_device_probe(struct platform_device *pdev) { int ret; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct device_node *child = NULL;
if (!cpus_have_const_cap(ARM64_HAS_MPAM)) return 0; @@ -1840,11 +1838,18 @@ static int arm_mpam_device_probe(struct platform_device *pdev) if (!acpi_disabled || mpam_enabled != MPAM_ENABLE_OF) return 0;
+ if (!node || !of_match_node(arm_mpam_of_device_ids, pdev->dev.of_node)) + return -EINVAL; + ret = mpam_discovery_start(); if (ret) return ret;
- ret = of_mpam_parse(pdev); + for_each_available_child_of_node(node, child) { + ret = of_mpam_add_child(pdev, child); + if (ret) + break; + }
if (ret) { mpam_discovery_failed();
From: Xingang Wang wangxingang5@huawei.com
arm64/mpam: refactor device tree structure to support multiple devices
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
---------------------------------------------------
To support multiple mpam device nodes, all nodes should be organized as child of the same parent nodes. This makes sure that the mpam discovery start and complete procedure in the right execution order. Add modification in the devicetree documentation to record this.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- .../devicetree/bindings/arm/arm,mpam.txt | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/arm,mpam.txt b/Documentation/devicetree/bindings/arm/arm,mpam.txt index 65c1e6809685..e9ba09bb3159 100644 --- a/Documentation/devicetree/bindings/arm/arm,mpam.txt +++ b/Documentation/devicetree/bindings/arm/arm,mpam.txt @@ -28,27 +28,30 @@ and Monitoring (MPAM), for Armv8-A", MPAM interrupts(section 8.8).
Example:
-mpam_memory0 { +mpam { 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>; + mpam_memory0 { + 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 { + 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>; + }; + };
From: Wang ShaoBo bobo.shaobowang@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4SE03 CVE: NA
---------------------------------------------------
This makes step entry aligned with step_size*step_cnt but not step_size, and check for alignment before traversing rmid_transform.
When modifying rmid with a value not aligned with step_size*step_cnt, for_each_rmid_transform_point_step_from might miss next step point if it has been occupied in case step_cnt or step_size not equals to 1, which will cause the actual allocated rmid to be inconsistent with the expected one.
Fixes: b47b9a817da1 ("arm64/mpam: rmid: refine allocation and release process") Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Laibin Qiu qiulaibin@huawei.com --- arch/arm64/kernel/mpam/mpam_resctrl.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 183c83d4274f..60d3d8706a38 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -839,7 +839,8 @@ static inline unsigned long **__rmid_remap_bmp(u32 col) #define __step_xy_initialize(step, x, y, from) \ (x = from, step = 1, y = 0) #define __step_align(from) \ - (!(from % rmid_remap_matrix.step_size)) + (!(from % (rmid_remap_matrix.step_size * \ + rmid_remap_matrix.step_cnt))) #define __step_overflow(step) \ (__xy_overflow(x, y) || \ (step > rmid_remap_matrix.step_cnt)) @@ -913,7 +914,7 @@ static int is_rmid_remap_bmp_full(unsigned long *bmp) bitmap_full(bmp, rmid_remap_matrix.rows)); }
-static int rmid_remap_bmp_find_first_avail_partid(int partid) +static int rmid_remap_bmp_find_step_entry(int partid) { int x, y; unsigned long **bmp; @@ -922,17 +923,18 @@ static int rmid_remap_bmp_find_first_avail_partid(int partid) rmid_remap_matrix.cols) return 0;
+ /* step entry should be non-occupied and aligned */ bmp = __rmid_remap_bmp(partid); - if (bmp && !is_rmid_remap_bmp_occ(*bmp)) - return partid; + if (bmp) + return (is_rmid_remap_bmp_occ(*bmp) || + !__step_align(partid)) ? -ENOSPC : partid;
for_each_rmid_transform_point_from(bmp, x, y, 0) { /* * do not waste partid resource, start - * from step_size aligned position. + * from step aligned position. */ - if (!is_rmid_remap_bmp_occ(*bmp) && - (x % rmid_remap_matrix.step_size) == 0) + if (__step_align(x) && !is_rmid_remap_bmp_occ(*bmp)) return x; }
@@ -1026,8 +1028,8 @@ static int __rmid_alloc(int partid, int pmg) if (pmg >= 0) checkpmg = true;
- /* traverse from first non-occupied and step_size aligned entry */ - ret = rmid_remap_bmp_find_first_avail_partid(partid); + /* traverse from first non-occupied and step-aligned entry */ + ret = rmid_remap_bmp_find_step_entry(partid); if (ret < 0) goto out; partid = ret;