summaryrefslogtreecommitdiff
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 18:32:24 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-18 18:32:24 -0700
commit94845e2929701018100389b3554dc54d1eee0c70 (patch)
tree2d5e3dce3c03ee956f47b89edf25e42280a83515 /arch/x86/kernel
parentccb9331e132a0554f6efb18140eae78bc32b0ee4 (diff)
parent854db793d4073087fa799d886ed84a342e3f484a (diff)
Merge tag 'x86_cache_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 resource control updates from Borislav Petkov: - How refreshing: no new features but a whole pile of fixes to more or less serious issues reported by Sashiko along with miscellaneous cleanups all over the place. All except one by Reinette Chatre, the one by Tony Luck. * tag 'x86_cache_for_v7.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: fs/resctrl: Inform user space when status buffer overflowed fs/resctrl: Communicate resource group deleted error via last_cmd_status fs/resctrl: Add last_cmd_status support for writes to max_threshold_occupancy fs/resctrl: Change last_cmd_status custom during input parsing fs/resctrl: Use accurate and symmetric exit flows fs/resctrl: Pass error reading event through to user space fs/resctrl: Use accurate type for rdt_resource::rid fs/resctrl: Change pattern used to track number of entries in enum resctrl_conf_type x86/resctrl: Protect against bad shift fs/resctrl: Use correct format specifier for printing error pointers fs/resctrl: Fix UAF from worker threads when domains are removed x86/resctrl: Ensure domain fully initialized before placed on RCU list fs/resctrl: Prevent deadlock and use-after-free in info file handlers fs/resctrl: Prevent use-after-free in rdtgroup_kn_put() fs/resctrl: Fix deadlock on errors during mount fs/resctrl: Move functions to avoid forward references in subsequent fixes x86,fs/resctrl: Document safe RCU list traversal
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/cpu/resctrl/core.c24
-rw-r--r--arch/x86/kernel/cpu/resctrl/ctrlmondata.c4
-rw-r--r--arch/x86/kernel/cpu/resctrl/intel_aet.c5
-rw-r--r--arch/x86/kernel/cpu/resctrl/monitor.c2
-rw-r--r--arch/x86/kernel/cpu/resctrl/rdtgroup.c4
5 files changed, 19 insertions, 20 deletions
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index f452e8ce4cef..55214d6fdc49 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -247,7 +247,11 @@ static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
cpuid_count(0x80000020, subleaf, &eax, &ebx, &ecx, &edx);
hw_res->num_closid = edx + 1;
- r->membw.max_bw = 1 << eax;
+ if (BITS_PER_TYPE(r->membw.max_bw) <= eax) {
+ pr_warn("Unable to support hardware's maximum bandwidth\n");
+ return false;
+ }
+ r->membw.max_bw = BIT(eax);
/* AMD does not use delay */
r->membw.delay_linear = false;
@@ -515,14 +519,12 @@ static void domain_add_cpu_ctrl(int cpu, struct rdt_resource *r)
return;
}
- list_add_tail_rcu(&d->hdr.list, add_pos);
-
err = resctrl_online_ctrl_domain(r, d);
if (err) {
- list_del_rcu(&d->hdr.list);
- synchronize_rcu();
ctrl_domain_free(hw_dom);
+ return;
}
+ list_add_tail_rcu(&d->hdr.list, add_pos);
}
static void l3_mon_domain_setup(int cpu, int id, struct rdt_resource *r, struct list_head *add_pos)
@@ -556,14 +558,12 @@ static void l3_mon_domain_setup(int cpu, int id, struct rdt_resource *r, struct
return;
}
- list_add_tail_rcu(&d->hdr.list, add_pos);
-
err = resctrl_online_mon_domain(r, &d->hdr);
if (err) {
- list_del_rcu(&d->hdr.list);
- synchronize_rcu();
l3_mon_domain_free(hw_dom);
+ return;
}
+ list_add_tail_rcu(&d->hdr.list, add_pos);
}
static void domain_add_cpu_mon(int cpu, struct rdt_resource *r)
@@ -642,9 +642,9 @@ static void domain_remove_cpu_ctrl(int cpu, struct rdt_resource *r)
d = container_of(hdr, struct rdt_ctrl_domain, hdr);
hw_dom = resctrl_to_arch_ctrl_dom(d);
- resctrl_offline_ctrl_domain(r, d);
list_del_rcu(&hdr->list);
synchronize_rcu();
+ resctrl_offline_ctrl_domain(r, d);
/*
* rdt_ctrl_domain "d" is going to be freed below, so clear
@@ -689,9 +689,9 @@ static void domain_remove_cpu_mon(int cpu, struct rdt_resource *r)
d = container_of(hdr, struct rdt_l3_mon_domain, hdr);
hw_dom = resctrl_to_arch_mon_dom(d);
- resctrl_offline_mon_domain(r, hdr);
list_del_rcu(&hdr->list);
synchronize_rcu();
+ resctrl_offline_mon_domain(r, hdr);
l3_mon_domain_free(hw_dom);
break;
}
@@ -702,9 +702,9 @@ static void domain_remove_cpu_mon(int cpu, struct rdt_resource *r)
return;
pkgd = container_of(hdr, struct rdt_perf_pkg_mon_domain, hdr);
- resctrl_offline_mon_domain(r, hdr);
list_del_rcu(&hdr->list);
synchronize_rcu();
+ resctrl_offline_mon_domain(r, hdr);
kfree(pkgd);
break;
}
diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index b20e705606b8..e74f1ed54b86 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -53,7 +53,7 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
/* Walking r->domains, ensure it can't race with cpuhp */
lockdep_assert_cpus_held();
- list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+ list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
hw_dom = resctrl_to_arch_ctrl_dom(d);
msr_param.res = NULL;
for (t = 0; t < CDP_NUM_TYPES; t++) {
@@ -115,7 +115,7 @@ static void _resctrl_sdciae_enable(struct rdt_resource *r, bool enable)
lockdep_assert_cpus_held();
/* Update MSR_IA32_L3_QOS_EXT_CFG MSR on all the CPUs in all domains */
- list_for_each_entry(d, &r->ctrl_domains, hdr.list)
+ list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held())
on_each_cpu_mask(&d->hdr.cpu_mask, resctrl_sdciae_set_one_amd, &enable, 1);
}
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 89b8b619d5d5..c22c3cf5167d 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -398,12 +398,11 @@ void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
d->hdr.type = RESCTRL_MON_DOMAIN;
d->hdr.rid = RDT_RESOURCE_PERF_PKG;
cpumask_set_cpu(cpu, &d->hdr.cpu_mask);
- list_add_tail_rcu(&d->hdr.list, add_pos);
err = resctrl_online_mon_domain(r, &d->hdr);
if (err) {
- list_del_rcu(&d->hdr.list);
- synchronize_rcu();
kfree(d);
+ return;
}
+ list_add_tail_rcu(&d->hdr.list, add_pos);
}
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index d096ba7d1b88..3838e0a13d36 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -513,7 +513,7 @@ static void _resctrl_abmc_enable(struct rdt_resource *r, bool enable)
lockdep_assert_cpus_held();
- list_for_each_entry(d, &r->mon_domains, hdr.list) {
+ list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
on_each_cpu_mask(&d->hdr.cpu_mask, resctrl_abmc_set_one_amd,
&enable, 1);
resctrl_arch_reset_rmid_all(r, d);
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 885026468440..5ffa39fa86fa 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -151,7 +151,7 @@ static int set_cache_qos_cfg(int level, bool enable)
return -ENOMEM;
r_l = &rdt_resources_all[level].r_resctrl;
- list_for_each_entry(d, &r_l->ctrl_domains, hdr.list) {
+ list_for_each_entry_rcu(d, &r_l->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
if (r_l->cache.arch_has_per_cpu_cfg)
/* Pick all the CPUs in the domain instance */
for_each_cpu(cpu, &d->hdr.cpu_mask)
@@ -249,7 +249,7 @@ void resctrl_arch_reset_all_ctrls(struct rdt_resource *r)
* CBMs in all ctrl_domains to the maximum mask value. Pick one CPU
* from each domain to update the MSRs below.
*/
- list_for_each_entry(d, &r->ctrl_domains, hdr.list) {
+ list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
hw_dom = resctrl_to_arch_ctrl_dom(d);
for (i = 0; i < hw_res->num_closid; i++)