On Tue, Jun 16, 2020 at 11:29:33AM +0200, Vitaly Kuznetsov wrote: > it seems we need something like PAGE_KERNEL_READONLY_EXEC but we don't > seem to have one on x86. Hypercall page is special in a way that the > guest doesn't need to write there at all. vmalloc_exec() seems to have > only one other user on x86: module_alloc() and it has other needs. module_alloc actually is a weak function and overriden on x86 (and many other architectures) , so it isn't used either (did I mention that I hate weak functions?) > On > ARM, alloc_insn_page() does the following: > > arch/arm64/kernel/probes/kprobes.c: page = vmalloc_exec(PAGE_SIZE); > arch/arm64/kernel/probes/kprobes.c- if (page) { > arch/arm64/kernel/probes/kprobes.c- set_memory_ro((unsigned long)page, 1); > arch/arm64/kernel/probes/kprobes.c- set_vm_flush_reset_perms(page); > arch/arm64/kernel/probes/kprobes.c- } > > What if we do the same? (almost untested): > > diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c > index e2137070386a..31aadfea589b 100644 > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -23,6 +23,7 @@ > #include <linux/kernel.h> > #include <linux/cpuhotplug.h> > #include <linux/syscore_ops.h> > +#include <linux/set_memory.h> > #include <clocksource/hyperv_timer.h> > > void *hv_hypercall_pg; > @@ -383,6 +384,8 @@ void __init hyperv_init(void) > wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); > goto remove_cpuhp_state; > } > + set_memory_ro((unsigned long)hv_hypercall_pg, 1); > + set_vm_flush_reset_perms(hv_hypercall_pg); This should work and might be the best for 5.8, but I think we need to sort this whole mess out for real.