From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 37018C61DA4 for ; Fri, 3 Feb 2023 17:28:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=5GbZM6YPghudNSj4TS0MOkf32XFWwRiOVD9BiO+dX9Y=; b=OfNl/66I8cYSPB 5gFyRuepKdNI9Zd8ItMwdWj1Vw1LV331fsgTOYZxOZ5NTSTcJZpLRRoJ9cbIkENwz3aZIeuLMaeZB borIz4YcaoedStnmDv/yA40ZpJrdBGSvYSdvXiCi22Agh09BgoGQw3JKwGO07rFuYQw+TpfrR3gkk 552ZjMtxwjyXkU9nZyezgM0bb+X09i8So4/0hyRv9U3WW3uoBwb46SyH2e83Y4xXY8y7Lr7eakUdI aCpLglhRXM/rqDs7v8o0P+HaT/DJVsaqXiFRlCs/4nBF6UpgixxqONITN8pqzb0/e+CVuX1Q1oZPQ It3HcNJYHOxRPNyZXyew==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pNzqJ-0034ZY-EY; Fri, 03 Feb 2023 17:27:19 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pNzqE-0034YQ-EE for linux-arm-kernel@lists.infradead.org; Fri, 03 Feb 2023 17:27:17 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 73365C14; Fri, 3 Feb 2023 09:27:53 -0800 (PST) Received: from FVFF77S0Q05N (unknown [10.57.90.37]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A1DD33F71E; Fri, 3 Feb 2023 09:27:10 -0800 (PST) Date: Fri, 3 Feb 2023 17:27:00 +0000 From: Mark Rutland To: Ruan Jinjie Cc: linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v2 9/9] arm64: armv8_deprecated: rework deprected instruction handling Message-ID: References: <20221019144123.612388-1-mark.rutland@arm.com> <20221019144123.612388-10-mark.rutland@arm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230203_092714_609608_FF1EC6A1 X-CRM114-Status: GOOD ( 48.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Fri, Feb 03, 2023 at 06:08:08PM +0800, Ruan Jinjie wrote: > > > On 2022/10/19 22:41, Mark Rutland wrote: > > Support for deprecated instructions can be enabled or disabled at > > runtime. To handle this, the code in armv8_deprecated.c registers and > > unregisters undef_hooks, and makes cross CPU calls to configure HW > > support. This is rather complicated, and the synchronization required to > > make this safe ends up serializing the handling of instructions which > > have been trapped. > > > > This patch simplifies the deprecated instruction handling by removing > > the dynamic registration and unregistration, and changing the trap > > handling code to determine whether a handler should be invoked. This > > removes the need for dynamic list management, and simplifies the locking > > requirements, making it possible to handle trapped instructions entirely > > in parallel. > > > > Where changing the emulation state requires a cross-call, this is > > serialized by locally disabling interrupts, ensuring that the CPU is not > > left in an inconsistent state. > > > > To simplify sysctl management, each insn_emulation is given a separate > > sysctl table, permitting these to be registered separately. The core > > sysctl code will iterate over all of these when walking sysfs. > > > > I've tested this with userspace programs which use each of the > > deprecated instructions, and I've concurrently modified the support > > level for each of the features back-and-forth between HW and emulated to > > check that there are no spurious SIGILLs sent to userspace when the > > support level is changed. > > Hi, Mark, I want to merge this patch to linux-5.10.y to solve a list_add > double problem. However, I can not trigger the emulation of these > deprecated instructions in qemu with userspace program as below, but > cause IABT and DABT, Well that certainly sounds wrong! When you say "in qemu", so you mean in a KVM VM, a TCG VM, or usermode emulation? Can you tell me exactly how you're invoking qemu? Can you give an example of the IABT and DABT you see? > so that I can not verify the correctness of the > patch.Can you give me some help to test the emulation of these > deprecated instructions? > > #include > > #define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ > : : "r" (0) : "memory") > #define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ > : : "r" (0) : "memory") > #define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ > : : "r" (0) : "memory") FWIW, these encodings look correc to me. Thanks, Mark. > > int main(){ > isb(); > dsb(); > dmb(); > return 0; > } > > > > > Signed-off-by: Mark Rutland > > Cc: Catalin Marinas > > Cc: James Morse > > Cc: Joey Gouly > > Cc: Peter Zijlstra > > Cc: Will Deacon > > Signed-off-by: Mark Rutland > > --- > > arch/arm64/include/asm/traps.h | 19 +- > > arch/arm64/kernel/armv8_deprecated.c | 282 +++++++++++++-------------- > > arch/arm64/kernel/traps.c | 40 +--- > > 3 files changed, 149 insertions(+), 192 deletions(-) > > > > diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h > > index 6e5826470bea..1f361e2da516 100644 > > --- a/arch/arm64/include/asm/traps.h > > +++ b/arch/arm64/include/asm/traps.h > > @@ -13,17 +13,16 @@ > > > > struct pt_regs; > > > > -struct undef_hook { > > - struct list_head node; > > - u32 instr_mask; > > - u32 instr_val; > > - u64 pstate_mask; > > - u64 pstate_val; > > - int (*fn)(struct pt_regs *regs, u32 instr); > > -}; > > +#ifdef CONFIG_ARMV8_DEPRECATED > > +bool try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn); > > +#else > > +static inline bool > > +try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn) > > +{ > > + return false; > > +} > > +#endif /* CONFIG_ARMV8_DEPRECATED */ > > > > -void register_undef_hook(struct undef_hook *hook); > > -void unregister_undef_hook(struct undef_hook *hook); > > void force_signal_inject(int signal, int code, unsigned long address, unsigned long err); > > void arm64_notify_segfault(unsigned long addr); > > void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str); > > diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c > > index 7f2ce49dbf97..ed0788cf6bbb 100644 > > --- a/arch/arm64/kernel/armv8_deprecated.c > > +++ b/arch/arm64/kernel/armv8_deprecated.c > > @@ -38,17 +38,24 @@ enum insn_emulation_mode { > > enum legacy_insn_status { > > INSN_DEPRECATED, > > INSN_OBSOLETE, > > + INSN_UNAVAILABLE, > > }; > > > > struct insn_emulation { > > const char *name; > > - struct list_head node; > > enum legacy_insn_status status; > > - struct undef_hook *hooks; > > + bool (*try_emulate)(struct pt_regs *regs, > > + u32 insn); > > int (*set_hw_mode)(bool enable); > > + > > int current_mode; > > int min; > > int max; > > + > > + /* > > + * sysctl for this emulation + a sentinal entry. > > + */ > > + struct ctl_table sysctl[2]; > > }; > > > > #define ARM_OPCODE_CONDTEST_FAIL 0 > > @@ -70,6 +77,7 @@ static unsigned int aarch32_check_condition(u32 opcode, u32 psr) > > return ARM_OPCODE_CONDTEST_UNCOND; > > } > > > > +#ifdef CONFIG_SWP_EMULATION > > /* > > * Implement emulation of the SWP/SWPB instructions using load-exclusive and > > * store-exclusive. > > @@ -222,28 +230,27 @@ static int swp_handler(struct pt_regs *regs, u32 instr) > > return 0; > > } > > > > -/* > > - * Only emulate SWP/SWPB executed in ARM state/User mode. > > - * The kernel must be SWP free and SWP{B} does not exist in Thumb. > > - */ > > -static struct undef_hook swp_hooks[] = { > > - { > > - .instr_mask = 0x0fb00ff0, > > - .instr_val = 0x01000090, > > - .pstate_mask = PSR_AA32_MODE_MASK, > > - .pstate_val = PSR_AA32_MODE_USR, > > - .fn = swp_handler > > - }, > > - { } > > -}; > > +static bool try_emulate_swp(struct pt_regs *regs, u32 insn) > > +{ > > + /* SWP{B} only exists in ARM state and does not exist in Thumb */ > > + if (!compat_user_mode(regs) || compat_thumb_mode(regs)) > > + return false; > > + > > + if ((insn & 0x0fb00ff0) != 0x01000090) > > + return false; > > + > > + return swp_handler(regs, insn) == 0; > > +} > > > > static struct insn_emulation insn_swp = { > > .name = "swp", > > .status = INSN_OBSOLETE, > > - .hooks = swp_hooks, > > + .try_emulate = try_emulate_swp, > > .set_hw_mode = NULL, > > }; > > +#endif /* CONFIG_SWP_EMULATION */ > > > > +#ifdef CONFIG_CP15_BARRIER_EMULATION > > static int cp15barrier_handler(struct pt_regs *regs, u32 instr) > > { > > perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc); > > @@ -306,31 +313,29 @@ static int cp15_barrier_set_hw_mode(bool enable) > > return 0; > > } > > > > -static struct undef_hook cp15_barrier_hooks[] = { > > - { > > - .instr_mask = 0x0fff0fdf, > > - .instr_val = 0x0e070f9a, > > - .pstate_mask = PSR_AA32_MODE_MASK, > > - .pstate_val = PSR_AA32_MODE_USR, > > - .fn = cp15barrier_handler, > > - }, > > - { > > - .instr_mask = 0x0fff0fff, > > - .instr_val = 0x0e070f95, > > - .pstate_mask = PSR_AA32_MODE_MASK, > > - .pstate_val = PSR_AA32_MODE_USR, > > - .fn = cp15barrier_handler, > > - }, > > - { } > > -}; > > +static bool try_emulate_cp15_barrier(struct pt_regs *regs, u32 insn) > > +{ > > + if (!compat_user_mode(regs) || compat_thumb_mode(regs)) > > + return false; > > + > > + if ((insn & 0x0fff0fdf) == 0x0e070f9a) > > + return cp15barrier_handler(regs, insn) == 0; > > + > > + if ((insn & 0x0fff0fff) == 0x0e070f95) > > + return cp15barrier_handler(regs, insn) == 0; > > + > > + return false; > > +} > > > > static struct insn_emulation insn_cp15_barrier = { > > .name = "cp15_barrier", > > .status = INSN_DEPRECATED, > > - .hooks = cp15_barrier_hooks, > > + .try_emulate = try_emulate_cp15_barrier, > > .set_hw_mode = cp15_barrier_set_hw_mode, > > }; > > +#endif /* CONFIG_CP15_BARRIER_EMULATION */ > > > > +#ifdef CONFIG_SETEND_EMULATION > > static int setend_set_hw_mode(bool enable) > > { > > if (!cpu_supports_mixed_endian_el0()) > > @@ -378,61 +383,41 @@ static int t16_setend_handler(struct pt_regs *regs, u32 instr) > > return rc; > > } > > > > -static struct undef_hook setend_hooks[] = { > > - { > > - .instr_mask = 0xfffffdff, > > - .instr_val = 0xf1010000, > > - .pstate_mask = PSR_AA32_MODE_MASK, > > - .pstate_val = PSR_AA32_MODE_USR, > > - .fn = a32_setend_handler, > > - }, > > - { > > - /* Thumb mode */ > > - .instr_mask = 0xfffffff7, > > - .instr_val = 0x0000b650, > > - .pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK), > > - .pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR), > > - .fn = t16_setend_handler, > > - }, > > - {} > > -}; > > +static bool try_emulate_setend(struct pt_regs *regs, u32 insn) > > +{ > > + if (compat_thumb_mode(regs) && > > + (insn & 0xfffffff7) == 0x0000b650) > > + return t16_setend_handler(regs, insn) == 0; > > + > > + if (compat_user_mode(regs) && > > + (insn & 0xfffffdff) == 0xf1010000) > > + return a32_setend_handler(regs, insn) == 0; > > + > > + return false; > > +} > > > > static struct insn_emulation insn_setend = { > > .name = "setend", > > .status = INSN_DEPRECATED, > > - .hooks = setend_hooks, > > + .try_emulate = try_emulate_setend, > > .set_hw_mode = setend_set_hw_mode, > > }; > > +#endif /* CONFIG_SETEND_EMULATION */ > > + > > +static struct insn_emulation *insn_emulations[] = { > > +#ifdef CONFIG_SWP_EMULATION > > + &insn_swp, > > +#endif > > +#ifdef CONFIG_CP15_BARRIER_EMULATION > > + &insn_cp15_barrier, > > +#endif > > +#ifdef CONFIG_SETEND_EMULATION > > + &insn_setend, > > +#endif > > +}; > > > > -static LIST_HEAD(insn_emulation); > > -static int nr_insn_emulated __initdata; > > -static DEFINE_RAW_SPINLOCK(insn_emulation_lock); > > static DEFINE_MUTEX(insn_emulation_mutex); > > > > -static void register_emulation_hooks(struct insn_emulation *insn) > > -{ > > - struct undef_hook *hook; > > - > > - BUG_ON(!insn->hooks); > > - > > - for (hook = insn->hooks; hook->instr_mask; hook++) > > - register_undef_hook(hook); > > - > > - pr_notice("Registered %s emulation handler\n", insn->name); > > -} > > - > > -static void remove_emulation_hooks(struct insn_emulation *insn) > > -{ > > - struct undef_hook *hook; > > - > > - BUG_ON(!insn->hooks); > > - > > - for (hook = insn->hooks; hook->instr_mask; hook++) > > - unregister_undef_hook(hook); > > - > > - pr_notice("Removed %s emulation handler\n", insn->name); > > -} > > - > > static void enable_insn_hw_mode(void *data) > > { > > struct insn_emulation *insn = (struct insn_emulation *)data; > > @@ -469,18 +454,24 @@ static int run_all_insn_set_hw_mode(unsigned int cpu) > > { > > int rc = 0; > > unsigned long flags; > > - struct insn_emulation *insn; > > > > - raw_spin_lock_irqsave(&insn_emulation_lock, flags); > > - list_for_each_entry(insn, &insn_emulation, node) { > > - bool enable = (insn->current_mode == INSN_HW); > > + /* > > + * Disable IRQs to serialize against an IPI from > > + * run_all_cpu_set_hw_mode(), ensuring the HW is programmed to the most > > + * recent enablement state if the two race with one another. > > + */ > > + local_irq_save(flags); > > + for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) { > > + struct insn_emulation *insn = insn_emulations[i]; > > + bool enable = READ_ONCE(insn->current_mode) == INSN_HW; > > if (insn->set_hw_mode && insn->set_hw_mode(enable)) { > > pr_warn("CPU[%u] cannot support the emulation of %s", > > cpu, insn->name); > > rc = -EINVAL; > > } > > } > > - raw_spin_unlock_irqrestore(&insn_emulation_lock, flags); > > + local_irq_restore(flags); > > + > > return rc; > > } > > > > @@ -493,7 +484,6 @@ static int update_insn_emulation_mode(struct insn_emulation *insn, > > case INSN_UNDEF: /* Nothing to be done */ > > break; > > case INSN_EMULATE: > > - remove_emulation_hooks(insn); > > break; > > case INSN_HW: > > if (!run_all_cpu_set_hw_mode(insn, false)) > > @@ -505,7 +495,6 @@ static int update_insn_emulation_mode(struct insn_emulation *insn, > > case INSN_UNDEF: > > break; > > case INSN_EMULATE: > > - register_emulation_hooks(insn); > > break; > > case INSN_HW: > > ret = run_all_cpu_set_hw_mode(insn, true); > > @@ -517,34 +506,6 @@ static int update_insn_emulation_mode(struct insn_emulation *insn, > > return ret; > > } > > > > -static void __init register_insn_emulation(struct insn_emulation *insn) > > -{ > > - unsigned long flags; > > - > > - insn->min = INSN_UNDEF; > > - > > - switch (insn->status) { > > - case INSN_DEPRECATED: > > - insn->current_mode = INSN_EMULATE; > > - /* Disable the HW mode if it was turned on at early boot time */ > > - run_all_cpu_set_hw_mode(insn, false); > > - insn->max = INSN_HW; > > - break; > > - case INSN_OBSOLETE: > > - insn->current_mode = INSN_UNDEF; > > - insn->max = INSN_EMULATE; > > - break; > > - } > > - > > - raw_spin_lock_irqsave(&insn_emulation_lock, flags); > > - list_add(&insn->node, &insn_emulation); > > - nr_insn_emulated++; > > - raw_spin_unlock_irqrestore(&insn_emulation_lock, flags); > > - > > - /* Register any handlers if required */ > > - update_insn_emulation_mode(insn, INSN_UNDEF); > > -} > > - > > static int emulation_proc_handler(struct ctl_table *table, int write, > > void *buffer, size_t *lenp, > > loff_t *ppos) > > @@ -562,7 +523,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write, > > ret = update_insn_emulation_mode(insn, prev_mode); > > if (ret) { > > /* Mode change failed, revert to previous mode. */ > > - insn->current_mode = prev_mode; > > + WRITE_ONCE(insn->current_mode, prev_mode); > > update_insn_emulation_mode(insn, INSN_UNDEF); > > } > > ret: > > @@ -570,21 +531,34 @@ static int emulation_proc_handler(struct ctl_table *table, int write, > > return ret; > > } > > > > -static void __init register_insn_emulation_sysctl(void) > > +static void __init register_insn_emulation(struct insn_emulation *insn) > > { > > - unsigned long flags; > > - int i = 0; > > - struct insn_emulation *insn; > > - struct ctl_table *insns_sysctl, *sysctl; > > + struct ctl_table *sysctl; > > > > - insns_sysctl = kcalloc(nr_insn_emulated + 1, sizeof(*sysctl), > > - GFP_KERNEL); > > - if (!insns_sysctl) > > - return; > > + insn->min = INSN_UNDEF; > > > > - raw_spin_lock_irqsave(&insn_emulation_lock, flags); > > - list_for_each_entry(insn, &insn_emulation, node) { > > - sysctl = &insns_sysctl[i]; > > + switch (insn->status) { > > + case INSN_DEPRECATED: > > + insn->current_mode = INSN_EMULATE; > > + /* Disable the HW mode if it was turned on at early boot time */ > > + run_all_cpu_set_hw_mode(insn, false); > > + insn->max = INSN_HW; > > + break; > > + case INSN_OBSOLETE: > > + insn->current_mode = INSN_UNDEF; > > + insn->max = INSN_EMULATE; > > + break; > > + case INSN_UNAVAILABLE: > > + insn->current_mode = INSN_UNDEF; > > + insn->max = INSN_UNDEF; > > + break; > > + } > > + > > + /* Program the HW if required */ > > + update_insn_emulation_mode(insn, INSN_UNDEF); > > + > > + if (insn->status != INSN_UNAVAILABLE) { > > + sysctl = &insn->sysctl[0]; > > > > sysctl->mode = 0644; > > sysctl->maxlen = sizeof(int); > > @@ -594,11 +568,32 @@ static void __init register_insn_emulation_sysctl(void) > > sysctl->extra1 = &insn->min; > > sysctl->extra2 = &insn->max; > > sysctl->proc_handler = emulation_proc_handler; > > - i++; > > + > > + register_sysctl("abi", sysctl); > > + } > > +} > > + > > +bool try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn) > > +{ > > + for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) { > > + struct insn_emulation *ie = insn_emulations[i]; > > + > > + if (ie->status == INSN_UNAVAILABLE) > > + continue; > > + > > + /* > > + * A trap may race with the mode being changed > > + * INSN_EMULATE<->INSN_HW. Try to emulate the instruction to > > + * avoid a spurious UNDEF. > > + */ > > + if (READ_ONCE(ie->current_mode) == INSN_UNDEF) > > + continue; > > + > > + if (ie->try_emulate(regs, insn)) > > + return true; > > } > > - raw_spin_unlock_irqrestore(&insn_emulation_lock, flags); > > > > - register_sysctl("abi", insns_sysctl); > > + return false; > > } > > > > /* > > @@ -607,24 +602,25 @@ static void __init register_insn_emulation_sysctl(void) > > */ > > static int __init armv8_deprecated_init(void) > > { > > - if (IS_ENABLED(CONFIG_SWP_EMULATION)) > > - register_insn_emulation(&insn_swp); > > +#ifdef CONFIG_SETEND_EMULATION > > + if (!system_supports_mixed_endian_el0()) { > > + insn_setend.status = INSN_UNAVAILABLE; > > + pr_info("setend instruction emulation is not supported on this system\n"); > > + } > > > > - if (IS_ENABLED(CONFIG_CP15_BARRIER_EMULATION)) > > - register_insn_emulation(&insn_cp15_barrier); > > +#endif > > + for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) { > > + struct insn_emulation *ie = insn_emulations[i]; > > > > - if (IS_ENABLED(CONFIG_SETEND_EMULATION)) { > > - if (system_supports_mixed_endian_el0()) > > - register_insn_emulation(&insn_setend); > > - else > > - pr_info("setend instruction emulation is not supported on this system\n"); > > + if (ie->status == INSN_UNAVAILABLE) > > + continue; > > + > > + register_insn_emulation(ie); > > } > > > > cpuhp_setup_state_nocalls(CPUHP_AP_ARM64_ISNDEP_STARTING, > > "arm64/isndep:starting", > > run_all_insn_set_hw_mode, NULL); > > - register_insn_emulation_sysctl(); > > - > > return 0; > > } > > > > diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c > > index 96eaf1aaec12..4c0caa589e12 100644 > > --- a/arch/arm64/kernel/traps.c > > +++ b/arch/arm64/kernel/traps.c > > @@ -373,27 +373,6 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size) > > regs->pstate &= ~PSR_BTYPE_MASK; > > } > > > > -static LIST_HEAD(undef_hook); > > -static DEFINE_RAW_SPINLOCK(undef_lock); > > - > > -void register_undef_hook(struct undef_hook *hook) > > -{ > > - unsigned long flags; > > - > > - raw_spin_lock_irqsave(&undef_lock, flags); > > - list_add(&hook->node, &undef_hook); > > - raw_spin_unlock_irqrestore(&undef_lock, flags); > > -} > > - > > -void unregister_undef_hook(struct undef_hook *hook) > > -{ > > - unsigned long flags; > > - > > - raw_spin_lock_irqsave(&undef_lock, flags); > > - list_del(&hook->node); > > - raw_spin_unlock_irqrestore(&undef_lock, flags); > > -} > > - > > static int user_insn_read(struct pt_regs *regs, u32 *insnp) > > { > > u32 instr; > > @@ -425,23 +404,6 @@ static int user_insn_read(struct pt_regs *regs, u32 *insnp) > > return 0; > > } > > > > -static int call_undef_hook(struct pt_regs *regs, u32 instr) > > -{ > > - struct undef_hook *hook; > > - unsigned long flags; > > - int (*fn)(struct pt_regs *regs, u32 instr) = NULL; > > - > > - raw_spin_lock_irqsave(&undef_lock, flags); > > - list_for_each_entry(hook, &undef_hook, node) > > - if ((instr & hook->instr_mask) == hook->instr_val && > > - (regs->pstate & hook->pstate_mask) == hook->pstate_val) > > - fn = hook->fn; > > - > > - raw_spin_unlock_irqrestore(&undef_lock, flags); > > - > > - return fn ? fn(regs, instr) : 1; > > -} > > - > > void force_signal_inject(int signal, int code, unsigned long address, unsigned long err) > > { > > const char *desc; > > @@ -502,7 +464,7 @@ void do_el0_undef(struct pt_regs *regs, unsigned long esr) > > if (try_emulate_mrs(regs, insn)) > > return; > > > > - if (call_undef_hook(regs, insn) == 0) > > + if (try_emulate_armv8_deprecated(regs, insn)) > > return; > > > > out_err: > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel