Messages in this thread | | | Subject | Re: [PATCH v3 0/6] Static calls | From | "H. Peter Anvin" <> | Date | Mon, 14 Jan 2019 14:54:12 -0800 |
| |
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 */
| |