[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <bd8e2753-e460-7641-5b52-e4cb9ab1fc10@zytor.com>
Date: Mon, 14 Jan 2019 21:37:44 -0800
From: "H. Peter Anvin" <hpa@...or.com>
To: Andy Lutomirski <luto@...nel.org>
Cc: Jiri Kosina <jikos@...nel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Josh Poimboeuf <jpoimboe@...hat.com>,
Nadav Amit <namit@...are.com>,
Peter Zijlstra <peterz@...radead.org>,
the arch/x86 maintainers <x86@...nel.org>,
Linux List Kernel Mailing <linux-kernel@...r.kernel.org>,
Ard Biesheuvel <ard.biesheuvel@...aro.org>,
Steven Rostedt <rostedt@...dmis.org>,
Ingo Molnar <mingo@...nel.org>,
Thomas Gleixner <tglx@...utronix.de>,
Masami Hiramatsu <mhiramat@...nel.org>,
Jason Baron <jbaron@...mai.com>,
David Laight <David.Laight@...lab.com>,
Borislav Petkov <bp@...en8.de>,
Julia Cartwright <julia@...com>, Jessica Yu <jeyu@...nel.org>,
Rasmus Villemoes <linux@...musvillemoes.dk>,
Edward Cree <ecree@...arflare.com>,
Daniel Bristot de Oliveira <bristot@...hat.com>
Subject: Re: [PATCH v3 0/6] Static calls
On 1/14/19 9:01 PM, H. Peter Anvin wrote:
>
> This could be as simple as spinning for a limited time waiting for
> states 0 or 3 if we are not the patching CPU. It is also not necessary
> to wait for the mask to become zero for the first sync if we find
> ourselves suddenly in state 4.
>
So this would look something like this for the #BP handler; I think this
is safe. This uses the TLB miss on the write page intentionally to slow
down the loop a bit to reduce the risk of livelock. Note that
"bp_write_addr" here refers to the write address for the breakpoint that
was taken.
state = atomic_read(&bp_poke_state);
if (state == 0)
return 0; /* No patching in progress */
recheck:
clear bit in mask
switch (state) {
case 1:
case 4:
if (smp_processor_id() != bp_patching_cpu) {
int retries = NNN;
while (retries--) {
invlpg
if (*bp_write_addr != 0xcc)
goto recheck;
state = atomic_read(&bp_poke_state);
if (state != 1 && state != 4)
goto recheck;
}
}
state = cmpxchg(&bp_poke_state, 1, 4);
if (state != 1 && state != 4)
goto recheck;
atomic_write(bp_write_addr, bp_old_value);
break;
case 2:
if (smp_processor_id() != bp_patching_cpu) {
invlpg
state = atomic_read(&bp_poke_state);
if (state != 2)
goto recheck;
}
complete patch sequence
remove breakpoint
break;
case 3:
case 0:
/*
* If we are here, the #BP will go away on its
* own, or we will re-take it if it was a "real"
* breakpoint.
*/
break;
}
return 1;
Powered by blists - more mailing lists