- 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) -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAl/DeEcACgkQEsHwGGHe VUrAlg/+KO2GMYiz5mNslI3tg0tUf0tDEw7bsfsibGL9XkkRRre0zn2pTN3GoutG ZeM9d+epFNfv1msyTYXjhhMeO5XLGnuBzyeCv4wQkIH0zdNJSencPlr6tKnaMrAo Alk/BxmvBmOOWHayBOhgNBVYWXBoACkIzIUFi0d3lRbgiGDhOqowYbYkLWIu/tvm pI8anovuAfkluhh+tD96TyBrSa+GfWWiOYItNbJbmKAbGjGbJU5IEVmlXeMEziGO 7zmGNwl4Di2V3lU5oDJNcYvF2Ngok/L81QqOMKeVu7EYDHLBjHxp0rxwuE8QqlX8 bk40EEHyI1Aiwx/7WxB/ChnDOfpIpXljWEvropZeNOCY1LqDMnMnAJFrygQAmYeo t9GxbhBYvtXSxTkkfTWzowt20Vmm2+r5j09kpq3tfMrZXwk7VrSF8TjQ/3iM/5iM eV/wPaigqX0xZwdzF1o3fuXeM+RXHhMrnX+cKlFemUX9uFZi0/ZXk3TlJwCG/jKL QWbpTBuxcDwXR3K1RNPjBJG1OA1cupZQ9ePK8h95H1844rEwglreypCOf3LwDJzU 9XEZo94V/J+gxNzg5iakidtdBMSst+SYY+vd/SUlLHXzkwcykOzwPgvZwVA7U2HM 74Eh7eQhIht3Lin35i9h1Ez/bxE/Ss6Fi9wnObp8ij5ImOaS5eU= =JrT9 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
7255a39d24
|
@ -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)
|
||||||
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)
|
||||||
* 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 @@ unlock:
|
||||||
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)
|
||||||
(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,
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
&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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
/*
|
/*
|
||||||
* 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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue