Commit 7255a39d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_urgent_for_v5.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:
 "A couple of urgent fixes which accumulated this last week:

   - Two resctrl fixes to prevent refcount leaks when manipulating the
     resctrl fs (Xiaochen Shen)

   - Correct prctl(PR_GET_SPECULATION_CTRL) reporting (Anand K Mistry)

   - A fix to not lose already seen MCE severity which determines
     whether the machine can recover (Gabriele Paoloni)"

* tag 'x86_urgent_for_v5.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mce: Do not overwrite no_way_out if mce_end() fails
  x86/speculation: Fix prctl() when spectre_v2_user={seccomp,prctl},ibpb
  x86/resctrl: Add necessary kernfs_put() calls to prevent refcount leak
  x86/resctrl: Remove superfluous kernfs_get() calls to prevent refcount leak
parents aae5ab85 25bc65d8
...@@ -739,11 +739,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -739,11 +739,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
if (boot_cpu_has(X86_FEATURE_IBPB)) { if (boot_cpu_has(X86_FEATURE_IBPB)) {
setup_force_cpu_cap(X86_FEATURE_USE_IBPB); setup_force_cpu_cap(X86_FEATURE_USE_IBPB);
spectre_v2_user_ibpb = mode;
switch (cmd) { switch (cmd) {
case SPECTRE_V2_USER_CMD_FORCE: case SPECTRE_V2_USER_CMD_FORCE:
case SPECTRE_V2_USER_CMD_PRCTL_IBPB: case SPECTRE_V2_USER_CMD_PRCTL_IBPB:
case SPECTRE_V2_USER_CMD_SECCOMP_IBPB: case SPECTRE_V2_USER_CMD_SECCOMP_IBPB:
static_branch_enable(&switch_mm_always_ibpb); static_branch_enable(&switch_mm_always_ibpb);
spectre_v2_user_ibpb = SPECTRE_V2_USER_STRICT;
break; break;
case SPECTRE_V2_USER_CMD_PRCTL: case SPECTRE_V2_USER_CMD_PRCTL:
case SPECTRE_V2_USER_CMD_AUTO: case SPECTRE_V2_USER_CMD_AUTO:
...@@ -757,8 +759,6 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -757,8 +759,6 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n", pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n",
static_key_enabled(&switch_mm_always_ibpb) ? static_key_enabled(&switch_mm_always_ibpb) ?
"always-on" : "conditional"); "always-on" : "conditional");
spectre_v2_user_ibpb = mode;
} }
/* /*
......
...@@ -1384,8 +1384,10 @@ noinstr void do_machine_check(struct pt_regs *regs) ...@@ -1384,8 +1384,10 @@ noinstr void do_machine_check(struct pt_regs *regs)
* When there's any problem use only local no_way_out state. * When there's any problem use only local no_way_out state.
*/ */
if (!lmce) { if (!lmce) {
if (mce_end(order) < 0) if (mce_end(order) < 0) {
no_way_out = worst >= MCE_PANIC_SEVERITY; if (!no_way_out)
no_way_out = worst >= MCE_PANIC_SEVERITY;
}
} else { } else {
/* /*
* If there was a fatal machine check we should have * If there was a fatal machine check we should have
......
...@@ -507,6 +507,24 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, ...@@ -507,6 +507,24 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of,
return ret ?: nbytes; return ret ?: nbytes;
} }
/**
* rdtgroup_remove - the helper to remove resource group safely
* @rdtgrp: resource group to remove
*
* On resource group creation via a mkdir, an extra kernfs_node reference is
* taken to ensure that the rdtgroup structure remains accessible for the
* rdtgroup_kn_unlock() calls where it is removed.
*
* Drop the extra reference here, then free the rdtgroup structure.
*
* Return: void
*/
static void rdtgroup_remove(struct rdtgroup *rdtgrp)
{
kernfs_put(rdtgrp->kn);
kfree(rdtgrp);
}
struct task_move_callback { struct task_move_callback {
struct callback_head work; struct callback_head work;
struct rdtgroup *rdtgrp; struct rdtgroup *rdtgrp;
...@@ -529,7 +547,7 @@ static void move_myself(struct callback_head *head) ...@@ -529,7 +547,7 @@ static void move_myself(struct callback_head *head)
(rdtgrp->flags & RDT_DELETED)) { (rdtgrp->flags & RDT_DELETED)) {
current->closid = 0; current->closid = 0;
current->rmid = 0; current->rmid = 0;
kfree(rdtgrp); rdtgroup_remove(rdtgrp);
} }
if (unlikely(current->flags & PF_EXITING)) if (unlikely(current->flags & PF_EXITING))
...@@ -1769,7 +1787,6 @@ static int rdtgroup_mkdir_info_resdir(struct rdt_resource *r, char *name, ...@@ -1769,7 +1787,6 @@ static int rdtgroup_mkdir_info_resdir(struct rdt_resource *r, char *name,
if (IS_ERR(kn_subdir)) if (IS_ERR(kn_subdir))
return PTR_ERR(kn_subdir); return PTR_ERR(kn_subdir);
kernfs_get(kn_subdir);
ret = rdtgroup_kn_set_ugid(kn_subdir); ret = rdtgroup_kn_set_ugid(kn_subdir);
if (ret) if (ret)
return ret; return ret;
...@@ -1792,7 +1809,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) ...@@ -1792,7 +1809,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL);
if (IS_ERR(kn_info)) if (IS_ERR(kn_info))
return PTR_ERR(kn_info); return PTR_ERR(kn_info);
kernfs_get(kn_info);
ret = rdtgroup_add_files(kn_info, RF_TOP_INFO); ret = rdtgroup_add_files(kn_info, RF_TOP_INFO);
if (ret) if (ret)
...@@ -1813,12 +1829,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) ...@@ -1813,12 +1829,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
goto out_destroy; goto out_destroy;
} }
/*
* This extra ref will be put in kernfs_remove() and guarantees
* that @rdtgrp->kn is always accessible.
*/
kernfs_get(kn_info);
ret = rdtgroup_kn_set_ugid(kn_info); ret = rdtgroup_kn_set_ugid(kn_info);
if (ret) if (ret)
goto out_destroy; goto out_destroy;
...@@ -1847,12 +1857,6 @@ mongroup_create_dir(struct kernfs_node *parent_kn, struct rdtgroup *prgrp, ...@@ -1847,12 +1857,6 @@ mongroup_create_dir(struct kernfs_node *parent_kn, struct rdtgroup *prgrp,
if (dest_kn) if (dest_kn)
*dest_kn = kn; *dest_kn = kn;
/*
* This extra ref will be put in kernfs_remove() and guarantees
* that @rdtgrp->kn is always accessible.
*/
kernfs_get(kn);
ret = rdtgroup_kn_set_ugid(kn); ret = rdtgroup_kn_set_ugid(kn);
if (ret) if (ret)
goto out_destroy; goto out_destroy;
...@@ -2079,8 +2083,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn) ...@@ -2079,8 +2083,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED)
rdtgroup_pseudo_lock_remove(rdtgrp); rdtgroup_pseudo_lock_remove(rdtgrp);
kernfs_unbreak_active_protection(kn); kernfs_unbreak_active_protection(kn);
kernfs_put(rdtgrp->kn); rdtgroup_remove(rdtgrp);
kfree(rdtgrp);
} else { } else {
kernfs_unbreak_active_protection(kn); kernfs_unbreak_active_protection(kn);
} }
...@@ -2139,13 +2142,11 @@ static int rdt_get_tree(struct fs_context *fc) ...@@ -2139,13 +2142,11 @@ static int rdt_get_tree(struct fs_context *fc)
&kn_mongrp); &kn_mongrp);
if (ret < 0) if (ret < 0)
goto out_info; goto out_info;
kernfs_get(kn_mongrp);
ret = mkdir_mondata_all(rdtgroup_default.kn, ret = mkdir_mondata_all(rdtgroup_default.kn,
&rdtgroup_default, &kn_mondata); &rdtgroup_default, &kn_mondata);
if (ret < 0) if (ret < 0)
goto out_mongrp; goto out_mongrp;
kernfs_get(kn_mondata);
rdtgroup_default.mon.mon_data_kn = kn_mondata; rdtgroup_default.mon.mon_data_kn = kn_mondata;
} }
...@@ -2357,7 +2358,7 @@ static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp) ...@@ -2357,7 +2358,7 @@ static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp)
if (atomic_read(&sentry->waitcount) != 0) if (atomic_read(&sentry->waitcount) != 0)
sentry->flags = RDT_DELETED; sentry->flags = RDT_DELETED;
else else
kfree(sentry); rdtgroup_remove(sentry);
} }
} }
...@@ -2399,7 +2400,7 @@ static void rmdir_all_sub(void) ...@@ -2399,7 +2400,7 @@ static void rmdir_all_sub(void)
if (atomic_read(&rdtgrp->waitcount) != 0) if (atomic_read(&rdtgrp->waitcount) != 0)
rdtgrp->flags = RDT_DELETED; rdtgrp->flags = RDT_DELETED;
else else
kfree(rdtgrp); rdtgroup_remove(rdtgrp);
} }
/* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */ /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */
update_closid_rmid(cpu_online_mask, &rdtgroup_default); update_closid_rmid(cpu_online_mask, &rdtgroup_default);
...@@ -2499,11 +2500,6 @@ static int mkdir_mondata_subdir(struct kernfs_node *parent_kn, ...@@ -2499,11 +2500,6 @@ static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
if (IS_ERR(kn)) if (IS_ERR(kn))
return PTR_ERR(kn); return PTR_ERR(kn);
/*
* This extra ref will be put in kernfs_remove() and guarantees
* that kn is always accessible.
*/
kernfs_get(kn);
ret = rdtgroup_kn_set_ugid(kn); ret = rdtgroup_kn_set_ugid(kn);
if (ret) if (ret)
goto out_destroy; goto out_destroy;
...@@ -2838,8 +2834,8 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, ...@@ -2838,8 +2834,8 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
/* /*
* kernfs_remove() will drop the reference count on "kn" which * kernfs_remove() will drop the reference count on "kn" which
* will free it. But we still need it to stick around for the * will free it. But we still need it to stick around for the
* rdtgroup_kn_unlock(kn} call below. Take one extra reference * rdtgroup_kn_unlock(kn) call. Take one extra reference here,
* here, which will be dropped inside rdtgroup_kn_unlock(). * which will be dropped by kernfs_put() in rdtgroup_remove().
*/ */
kernfs_get(kn); kernfs_get(kn);
...@@ -2880,6 +2876,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, ...@@ -2880,6 +2876,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
out_idfree: out_idfree:
free_rmid(rdtgrp->mon.rmid); free_rmid(rdtgrp->mon.rmid);
out_destroy: out_destroy:
kernfs_put(rdtgrp->kn);
kernfs_remove(rdtgrp->kn); kernfs_remove(rdtgrp->kn);
out_free_rgrp: out_free_rgrp:
kfree(rdtgrp); kfree(rdtgrp);
...@@ -2892,7 +2889,7 @@ static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp) ...@@ -2892,7 +2889,7 @@ static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp)
{ {
kernfs_remove(rgrp->kn); kernfs_remove(rgrp->kn);
free_rmid(rgrp->mon.rmid); free_rmid(rgrp->mon.rmid);
kfree(rgrp); rdtgroup_remove(rgrp);
} }
/* /*
...@@ -3049,11 +3046,6 @@ static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp, ...@@ -3049,11 +3046,6 @@ static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp,
WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list));
list_del(&rdtgrp->mon.crdtgrp_list); list_del(&rdtgrp->mon.crdtgrp_list);
/*
* one extra hold on this, will drop when we kfree(rdtgrp)
* in rdtgroup_kn_unlock()
*/
kernfs_get(kn);
kernfs_remove(rdtgrp->kn); kernfs_remove(rdtgrp->kn);
return 0; return 0;
...@@ -3065,11 +3057,6 @@ static int rdtgroup_ctrl_remove(struct kernfs_node *kn, ...@@ -3065,11 +3057,6 @@ static int rdtgroup_ctrl_remove(struct kernfs_node *kn,
rdtgrp->flags = RDT_DELETED; rdtgrp->flags = RDT_DELETED;
list_del(&rdtgrp->rdtgroup_list); list_del(&rdtgrp->rdtgroup_list);
/*
* one extra hold on this, will drop when we kfree(rdtgrp)
* in rdtgroup_kn_unlock()
*/
kernfs_get(kn);
kernfs_remove(rdtgrp->kn); kernfs_remove(rdtgrp->kn);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment