[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8ca16cca-101d-1d1b-b3da-c9727665fec8@zytor.com>
Date: Mon, 14 Jan 2019 14:54:12 -0800
From: "H. Peter Anvin" <hpa@...or.com>
To: Jiri Kosina <jikos@...nel.org>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
Josh Poimboeuf <jpoimboe@...hat.com>,
Nadav Amit <namit@...are.com>,
Andy Lutomirski <luto@...nel.org>,
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
I think this sequence ought to work (keep in mind we are already under a
mutex, so the global data is safe even if we are preempted):
set up page table entries
invlpg
set up bp patching global data
cpu = get_cpu()
bp_old_value = atomic_read(bp_write_addr)
do {
atomic_write(&bp_poke_state, 1)
atomic_write(bp_write_addr, 0xcc)
mask <- online_cpu_mask - self
send IPIs
wait for mask = 0
} while (cmpxchg(&bp_poke_state, 1, 2) != 1);
patch sites, remove breakpoints after patching each one
atomic_write(&bp_poke_state, 3);
mask <- online_cpu_mask - self
send IPIs
wait for mask = 0
atomic_write(&bp_poke_state, 0);
tear down patching global data
tear down page table entries
The #BP handler would then look like:
state = cmpxchg(&bp_poke_state, 1, 4);
switch (state) {
case 1:
case 4:
invlpg
cmpxchg(bp_write_addr, 0xcc, bp_old_value)
break;
case 2:
invlpg
complete patch sequence
remove breakpoint
break;
case 3:
/* If we are here, the #BP will go away on its own */
break;
case 0:
/* No patching in progress!!! */
return 0;
}
clear bit in mask
return 1;
The IPI handler:
clear bit in mask
sync_core /* Needed if multiple IPI events are chained */
Powered by blists - more mailing lists