From aa63a74d4535a1d97b60e46655a1361c42565b89 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 6 Apr 2022 15:01:50 -0700 Subject: topology/sysfs: Hide PPIN on systems that do not support it. Systems that do not support a Protected Processor Identification Number currently report: # cat /sys/devices/system/cpu/cpu0/topology/ppin 0x0 which is confusing/wrong. Add a ".is_visible" function to suppress inclusion of the ppin file. Fixes: ab28e944197f ("topology/sysfs: Add PPIN in sysfs under cpu topology") Signed-off-by: Tony Luck Link: https://lore.kernel.org/r/20220406220150.63855-1-tony.luck@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/topology.c b/drivers/base/topology.c index e9d1efcda89b..706dbf8bf249 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -152,9 +152,21 @@ static struct attribute *default_attrs[] = { NULL }; +static umode_t topology_is_visible(struct kobject *kobj, + struct attribute *attr, int unused) +{ + struct device *dev = kobj_to_dev(kobj); + + if (attr == &dev_attr_ppin.attr && !topology_ppin(dev->id)) + return 0; + + return attr->mode; +} + static const struct attribute_group topology_attr_group = { .attrs = default_attrs, .bin_attrs = bin_attrs, + .is_visible = topology_is_visible, .name = "topology" }; -- cgit v1.2.3 From db1e59483dfd8d4e956575302520bb8f7e20c79b Mon Sep 17 00:00:00 2001 From: Darren Hart Date: Mon, 11 Apr 2022 13:53:34 -0700 Subject: topology: make core_mask include at least cluster_siblings Ampere Altra defines CPU clusters in the ACPI PPTT. They share a Snoop Control Unit, but have no shared CPU-side last level cache. cpu_coregroup_mask() will return a cpumask with weight 1, while cpu_clustergroup_mask() will return a cpumask with weight 2. As a result, build_sched_domain() will BUG() once per CPU with: BUG: arch topology borken the CLS domain not a subset of the MC domain The MC level cpumask is then extended to that of the CLS child, and is later removed entirely as redundant. This sched domain topology is an improvement over previous topologies, or those built without SCHED_CLUSTER, particularly for certain latency sensitive workloads. With the current scheduler model and heuristics, this is a desirable default topology for Ampere Altra and Altra Max system. Rather than create a custom sched domains topology structure and introduce new logic in arch/arm64 to detect these systems, update the core_mask so coregroup is never a subset of clustergroup, extending it to cluster_siblings if necessary. Only do this if CONFIG_SCHED_CLUSTER is enabled to avoid also changing the topology (MC) when CONFIG_SCHED_CLUSTER is disabled. This has the added benefit over a custom topology of working for both symmetric and asymmetric topologies. It does not address systems where the CLUSTER topology is above a populated MC topology, but these are not considered today and can be addressed separately if and when they appear. The final sched domain topology for a 2 socket Ampere Altra system is unchanged with or without CONFIG_SCHED_CLUSTER, and the BUG is avoided: For CPU0: CONFIG_SCHED_CLUSTER=y CLS [0-1] DIE [0-79] NUMA [0-159] CONFIG_SCHED_CLUSTER is not set DIE [0-79] NUMA [0-159] Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Catalin Marinas Cc: Will Deacon Cc: Peter Zijlstra Cc: Vincent Guittot Cc: D. Scott Phillips Cc: Ilkka Koskinen Cc: # 5.16.x Suggested-by: Barry Song Reviewed-by: Barry Song Reviewed-by: Dietmar Eggemann Acked-by: Sudeep Holla Signed-off-by: Darren Hart Link: https://lore.kernel.org/r/c8fe9fce7c86ed56b4c455b8c902982dc2303868.1649696956.git.darren@os.amperecomputing.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 1d6636ebaac5..5497c5ab7318 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -667,6 +667,15 @@ const struct cpumask *cpu_coregroup_mask(int cpu) core_mask = &cpu_topology[cpu].llc_sibling; } + /* + * For systems with no shared cpu-side LLC but with clusters defined, + * extend core_mask to cluster_siblings. The sched domain builder will + * then remove MC as redundant with CLS if SCHED_CLUSTER is enabled. + */ + if (IS_ENABLED(CONFIG_SCHED_CLUSTER) && + cpumask_subset(core_mask, &cpu_topology[cpu].cluster_sibling)) + core_mask = &cpu_topology[cpu].cluster_sibling; + return core_mask; } -- cgit v1.2.3 From 1dc9f1a66e1718479e1c4f95514e1750602a3cb9 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Sun, 10 Apr 2022 19:36:19 -0700 Subject: arch_topology: Do not set llc_sibling if llc_id is invalid When ACPI is not enabled, cpuid_topo->llc_id = cpu_topo->llc_id = -1, which will set llc_sibling 0xff(...), this is misleading. Don't set llc_sibling(default 0) if we don't know the cache topology. Reviewed-by: Sudeep Holla Signed-off-by: Wang Qing Fixes: 37c3ec2d810f ("arm64: topology: divorce MC scheduling domain from core_siblings") Cc: stable Link: https://lore.kernel.org/r/1649644580-54626-1-git-send-email-wangqing@vivo.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base') diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 5497c5ab7318..f73b836047cf 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -693,7 +693,7 @@ void update_siblings_masks(unsigned int cpuid) for_each_online_cpu(cpu) { cpu_topo = &cpu_topology[cpu]; - if (cpuid_topo->llc_id == cpu_topo->llc_id) { + if (cpu_topo->llc_id != -1 && cpuid_topo->llc_id == cpu_topo->llc_id) { cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling); cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling); } -- cgit v1.2.3 From c95ce3a23dcda678f6f7811dd39b6d14eeb6f192 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Apr 2022 08:26:53 +0200 Subject: topology: Fix up build warning in topology_is_visible() Commit aa63a74d4535 ("topology/sysfs: Hide PPIN on systems that do not support it.") caused a build warning on some configurations: drivers/base/topology.c: In function 'topology_is_visible': drivers/base/topology.c:158:24: warning: unused variable 'dev' [-Wunused-variable] 158 | struct device *dev = kobj_to_dev(kobj); Fix this up by getting rid of the variable entirely. Fixes: aa63a74d4535 ("topology/sysfs: Hide PPIN on systems that do not support it.") Cc: Tony Luck Reported-by: Stephen Rothwell Link: https://lore.kernel.org/r/20220422062653.3899972-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/base') diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 706dbf8bf249..ac6ad9ab67f9 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -155,9 +155,7 @@ static struct attribute *default_attrs[] = { static umode_t topology_is_visible(struct kobject *kobj, struct attribute *attr, int unused) { - struct device *dev = kobj_to_dev(kobj); - - if (attr == &dev_attr_ppin.attr && !topology_ppin(dev->id)) + if (attr == &dev_attr_ppin.attr && !topology_ppin(kobj_to_dev(kobj)->id)) return 0; return attr->mode; -- cgit v1.2.3 From 581dd69830341d299b0c097fc366097ab497d679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= Date: Mon, 2 May 2022 10:49:52 +1000 Subject: firmware_loader: use kernel credentials when reading firmware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device drivers may decide to not load firmware when probed to avoid slowing down the boot process should the firmware filesystem not be available yet. In this case, the firmware loading request may be done when a device file associated with the driver is first accessed. The credentials of the userspace process accessing the device file may be used to validate access to the firmware files requested by the driver. Ensure that the kernel assumes the responsibility of reading the firmware. This was observed on Android for a graphic driver loading their firmware when the device file (e.g. /dev/mali0) was first opened by userspace (i.e. surfaceflinger). The security context of surfaceflinger was used to validate the access to the firmware file (e.g. /vendor/firmware/mali.bin). Previously, Android configurations were not setting up the firmware_class.path command line argument and were relying on the userspace fallback mechanism. In this case, the security context of the userspace daemon (i.e. ueventd) was consistently used to read firmware files. More Android devices are now found to set firmware_class.path which gives the kernel the opportunity to read the firmware directly (via kernel_read_file_from_path_initns). In this scenario, the current process credentials were used, even if unrelated to the loading of the firmware file. Signed-off-by: ThiƩbaud Weksteen Cc: # 5.10 Reviewed-by: Paul Moore Acked-by: Luis Chamberlain Link: https://lore.kernel.org/r/20220502004952.3970800-1-tweek@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/main.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/base') diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 94d1789a233e..406a907a4cae 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -735,6 +735,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name, size_t offset, u32 opt_flags) { struct firmware *fw = NULL; + struct cred *kern_cred = NULL; + const struct cred *old_cred; bool nondirect = false; int ret; @@ -751,6 +753,18 @@ _request_firmware(const struct firmware **firmware_p, const char *name, if (ret <= 0) /* error or already assigned */ goto out; + /* + * We are about to try to access the firmware file. Because we may have been + * called by a driver when serving an unrelated request from userland, we use + * the kernel credentials to read the file. + */ + kern_cred = prepare_kernel_cred(NULL); + if (!kern_cred) { + ret = -ENOMEM; + goto out; + } + old_cred = override_creds(kern_cred); + ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); /* Only full reads can support decompression, platform, and sysfs. */ @@ -776,6 +790,9 @@ _request_firmware(const struct firmware **firmware_p, const char *name, } else ret = assign_fw(fw, device); + revert_creds(old_cred); + put_cred(kern_cred); + out: if (ret < 0) { fw_abort_batch_reqs(fw); -- cgit v1.2.3