Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81da72aa authored by Valentin Schneider's avatar Valentin Schneider Committed by Greg Kroah-Hartman
Browse files

x86/resctrl: Apply READ_ONCE/WRITE_ONCE to task_struct.{rmid,closid}



commit 6d3b47ddffed70006cf4ba360eef61e9ce097d8f upstream.

A CPU's current task can have its {closid, rmid} fields read locally
while they are being concurrently written to from another CPU.
This can happen anytime __resctrl_sched_in() races with either
__rdtgroup_move_task() or rdt_move_group_tasks().

Prevent load / store tearing for those accesses by giving them the
READ_ONCE() / WRITE_ONCE() treatment.

Signed-off-by: default avatarValentin Schneider <valentin.schneider@arm.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/9921fda88ad81afb9885b517fbe864a2bc7c35a9.1608243147.git.reinette.chatre@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bde541a5
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -56,19 +56,22 @@ static void __resctrl_sched_in(void)
	struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
	u32 closid = state->default_closid;
	u32 rmid = state->default_rmid;
	u32 tmp;

	/*
	 * If this task has a closid/rmid assigned, use it.
	 * Else use the closid/rmid assigned to this cpu.
	 */
	if (static_branch_likely(&rdt_alloc_enable_key)) {
		if (current->closid)
			closid = current->closid;
		tmp = READ_ONCE(current->closid);
		if (tmp)
			closid = tmp;
	}

	if (static_branch_likely(&rdt_mon_enable_key)) {
		if (current->rmid)
			rmid = current->rmid;
		tmp = READ_ONCE(current->rmid);
		if (tmp)
			rmid = tmp;
	}

	if (closid != state->cur_closid || rmid != state->cur_rmid) {
+5 −5
Original line number Diff line number Diff line
@@ -563,11 +563,11 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
	 */

	if (rdtgrp->type == RDTCTRL_GROUP) {
		tsk->closid = rdtgrp->closid;
		tsk->rmid = rdtgrp->mon.rmid;
		WRITE_ONCE(tsk->closid, rdtgrp->closid);
		WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
	} else if (rdtgrp->type == RDTMON_GROUP) {
		if (rdtgrp->mon.parent->closid == tsk->closid) {
			tsk->rmid = rdtgrp->mon.rmid;
			WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
		} else {
			rdt_last_cmd_puts("Can't move task to different control group\n");
			return -EINVAL;
@@ -2177,8 +2177,8 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
	for_each_process_thread(p, t) {
		if (!from || is_closid_match(t, from) ||
		    is_rmid_match(t, from)) {
			t->closid = to->closid;
			t->rmid = to->mon.rmid;
			WRITE_ONCE(t->closid, to->closid);
			WRITE_ONCE(t->rmid, to->mon.rmid);

			/*
			 * Order the closid/rmid stores above before the loads