From 4821a718efdc4a85c15e6e07ff78b44da32d97c2 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort Date: Tue, 24 Sep 2024 15:06:24 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Automate pKVM module event registration Previously, modules had to register themselves the .event_ids ELF section. This is now on done on their behalf before jumping into the module init function. Bug: 357781595 Bug: 268495982 Change-Id: Iebe839dc096d3020921e2c97a75a5284c518dee7 Signed-off-by: Vincent Donnefort --- arch/arm64/include/asm/kvm_pkvm_module.h | 1 - arch/arm64/kvm/hyp/include/nvhe/trace/trace.h | 4 ++-- arch/arm64/kvm/hyp/nvhe/events.c | 6 +++--- arch/arm64/kvm/hyp/nvhe/module.lds.S | 2 -- arch/arm64/kvm/hyp/nvhe/modules.c | 7 ++++++- drivers/misc/pkvm-smc/pkvm/pkvm-smc.c | 4 ---- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pkvm_module.h b/arch/arm64/include/asm/kvm_pkvm_module.h index 325bbfabfd22..abe984438180 100644 --- a/arch/arm64/include/asm/kvm_pkvm_module.h +++ b/arch/arm64/include/asm/kvm_pkvm_module.h @@ -210,7 +210,6 @@ struct pkvm_module_ops { phys_addr_t (*hyp_pa)(void *x); void* (*hyp_va)(phys_addr_t phys); unsigned long (*kern_hyp_va)(unsigned long x); - int (*register_hyp_event_ids)(unsigned long start, unsigned long end); void* (*tracing_reserve_entry)(unsigned long length); void (*tracing_commit_entry)(void); void (*tracing_mod_hyp_printk)(u8 fmt_id, u64 a, u64 b, u64 c, u64 d); diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace/trace.h b/arch/arm64/kvm/hyp/include/nvhe/trace/trace.h index a4385ab121bb..27127cf76725 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace/trace.h @@ -7,7 +7,7 @@ #ifdef CONFIG_TRACING void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); -int register_hyp_event_ids(unsigned long start, unsigned long end); +int register_hyp_event_ids(void *event_ids, size_t nr_events); #define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ HYP_EVENT_FORMAT(__name, __struct); \ @@ -80,7 +80,7 @@ do { \ #else static inline void *tracing_reserve_entry(unsigned long length) { return NULL; } static inline void tracing_commit_entry(void) { } -static inline int register_hyp_event_ids(unsigned long start, unsigned long end) +static inline int register_hyp_event_ids(void *event_ids, size_t nr_events) { return -ENODEV; } diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/events.c index b23516136bf7..5494859b8ddc 100644 --- a/arch/arm64/kvm/hyp/nvhe/events.c +++ b/arch/arm64/kvm/hyp/nvhe/events.c @@ -72,7 +72,7 @@ static bool try_set_mod_event(unsigned short id, bool enable) return false; } -int register_hyp_event_ids(unsigned long start, unsigned long end) +int register_hyp_event_ids(void *event_ids, size_t nr_events) { int mod, ret = -ENOMEM; @@ -80,8 +80,8 @@ int register_hyp_event_ids(unsigned long start, unsigned long end) mod = atomic_read(&num_event_id_mod); if (mod < MAX_EVENT_ID_MOD) { - event_id_mod[mod].start = (struct hyp_event_id *)start; - event_id_mod[mod].end = (struct hyp_event_id *)end; + event_id_mod[mod].start = (struct hyp_event_id *)event_ids; + event_id_mod[mod].end = (struct hyp_event_id *)event_ids + nr_events; /* * Order access between num_event_id_mod and event_id_mod. * Paired with try_set_mod_event() diff --git a/arch/arm64/kvm/hyp/nvhe/module.lds.S b/arch/arm64/kvm/hyp/nvhe/module.lds.S index e6f412c7ae1b..26e13e8568fe 100644 --- a/arch/arm64/kvm/hyp/nvhe/module.lds.S +++ b/arch/arm64/kvm/hyp/nvhe/module.lds.S @@ -21,9 +21,7 @@ SECTIONS { .hyp.event_ids : { HYP_SECTION_SYMBOL_NAME(.event_ids) = .; - __hyp_event_ids_start = .; *(HYP_SECTION_NAME(.event_ids)) - __hyp_event_ids_end = .; *(HYP_SECTION_NAME(.printk_fmt_offset)) } diff --git a/arch/arm64/kvm/hyp/nvhe/modules.c b/arch/arm64/kvm/hyp/nvhe/modules.c index 09bff67706e8..da625f1f8c06 100644 --- a/arch/arm64/kvm/hyp/nvhe/modules.c +++ b/arch/arm64/kvm/hyp/nvhe/modules.c @@ -244,7 +244,6 @@ const struct pkvm_module_ops module_ops = { .hyp_pa = hyp_virt_to_phys, .hyp_va = hyp_phys_to_virt, .kern_hyp_va = __kern_hyp_va, - .register_hyp_event_ids = register_hyp_event_ids, .tracing_reserve_entry = tracing_reserve_entry, .tracing_commit_entry = tracing_commit_entry, .tracing_mod_hyp_printk = tracing_mod_hyp_printk, @@ -277,6 +276,12 @@ int __pkvm_init_module(void *host_mod) { int (*do_module_init)(const struct pkvm_module_ops *ops); struct pkvm_el2_module *mod = kern_hyp_va(host_mod); + void *event_ids; + + event_ids = pkvm_module_hyp_va(mod, mod->event_ids.start); + + if (mod->nr_hyp_events) + register_hyp_event_ids(event_ids, mod->nr_hyp_events); do_module_init = pkvm_module_hyp_va(mod, (void *)mod->init); diff --git a/drivers/misc/pkvm-smc/pkvm/pkvm-smc.c b/drivers/misc/pkvm-smc/pkvm/pkvm-smc.c index d2cc51808690..5681aef227aa 100644 --- a/drivers/misc/pkvm-smc/pkvm/pkvm-smc.c +++ b/drivers/misc/pkvm-smc/pkvm/pkvm-smc.c @@ -134,10 +134,6 @@ bool filter_smc(struct user_pt_regs *regs) int pkvm_smc_filter_hyp_init(const struct pkvm_module_ops *ops) { -#ifdef CONFIG_TRACING - ops->register_hyp_event_ids((unsigned long)__hyp_event_ids_start, - (unsigned long)__hyp_event_ids_end); -#endif pkvm_ops = ops; return ops->register_host_smc_handler(filter_smc); }