Re: hv_hypercall_pg page permissios
From: Christoph Hellwig <hch@lst.de>
Date: 2020-06-16 09:33:48
Also in:
lkml
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:
quoted hunk ↗ jump to hunk
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.