From nobody Mon Mar 23 21:29:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1773420309; cv=none; d=zohomail.com; s=zohoarc; b=TlFmJhsnFI77Evw7FI22x4kn6XYv5Va0bM4AP3tmM0BZIGXxcJqBEcuEXBL6fHEHJIOqrO5MQmn1fpzwfn0AdExU6/7BrxdPEaa+uvdCOMsZpOCKYXEiLY4riySmgdsgx0Bo/9p1iNptjA+gxGJwJhzFJrBGzrqo3C8qBQ9fE4I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773420309; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=yfsWIAex3jEpm8GQ6vF4++T74O/B/5LjYy46X+zBd0E=; b=RY1dxGFgdzpywSNVBv1ctZQSjJvVF3JzjPSnzZUYzqVhkcsRPIXP28HNc3Js2ZTg2Rq7J9TCDPlsqAFHMopp0hPGHRs42kOsBMOChw7w75tIfVkPhYHJzHXrpcvaEbUY4cVn5NhuyM5F29SPIMrgrXDOdqRvAV46zTqHRoe2B2w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1773420309025437.70612738660327; Fri, 13 Mar 2026 09:45:09 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1254117.1550099 (Exim 4.92) (envelope-from ) id 1w15d6-0004Lw-7V; Fri, 13 Mar 2026 16:44:52 +0000 Received: by outflank-mailman (output) from mailman id 1254117.1550099; Fri, 13 Mar 2026 16:44:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w15d6-0004Ln-4E; Fri, 13 Mar 2026 16:44:52 +0000 Received: by outflank-mailman (input) for mailman id 1254117; Fri, 13 Mar 2026 16:44:50 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w15d4-0004GG-OC for xen-devel@lists.xenproject.org; Fri, 13 Mar 2026 16:44:50 +0000 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [2a00:1450:4864:20::52c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f2a23535-1efb-11f1-9ccf-f158ae23cfc8; Fri, 13 Mar 2026 17:44:48 +0100 (CET) Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-661b16ac011so4257325a12.2 for ; Fri, 13 Mar 2026 09:44:48 -0700 (PDT) Received: from fedora (user-109-243-67-101.play-internet.pl. [109.243.67.101]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-66350b86008sm1394733a12.28.2026.03.13.09.44.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Mar 2026 09:44:46 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f2a23535-1efb-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773420287; x=1774025087; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yfsWIAex3jEpm8GQ6vF4++T74O/B/5LjYy46X+zBd0E=; b=CC7GYogW2mcvpVF9v+qXkIgNbWXtWjm/LXSnMAHo5Qr5DyQQDsyyFufada7WvyZJBz O8g1uNNl6VVvSrhl9obFNJQqw6sQ6pqYMx5QLe3JU5bRxJGSmSjCOc3XMgkAl6kAAd4/ MelV/nsty13qKMAs/VWUxR1hNltNFU2gec6vAW06fRDq+hPujeoUPAVG9MOP+FkFgrxX +XjWP/G1nkcUBSz4CoqfA1t3UxwxL+AtRvUqfA+v+2VdeFttiNeebvXtM9KTsUG9d+59 +uU78SQaGogLw6XO10fHIXHyYD3HEHh18wnDb13J3ZVOPcrRp8a33BK1nYv2ERd8jHpF cSpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773420287; x=1774025087; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=yfsWIAex3jEpm8GQ6vF4++T74O/B/5LjYy46X+zBd0E=; b=I5fxY3N8SBLCVxj6XtiUKIsd0vqNepLNZWKfU1jqdofcEllAHWllk5k0DouUHmARrI Z/f9cGJLxQ5kE7AKPZCmtuNm+flMp9DRyrYIoKy1epRzqgG1x6hjlNDtfcyKTf1kmzTF B7d4FMczzu95zRVxPIrXZTnqKDAxNsHgiug58zZyMzC0eRm4wcl1oy/icMD7QFPlRQiJ p+IlrcNoTYOLGJs5ocTKe1e+qQIVK3YWr69UDbLKAlL2eQ7UzQsm9ORRgTdy8/uy1D2T 7VF6x2Emwh3lorxWqRw9qNG4oikI7Q6Q1ejjUCfNOUJgoEKd1pbyAMzD/IOisr3ksqQd qHsA== X-Gm-Message-State: AOJu0YxvYQi/P6hQZs/fdwwha2RpBvYeJ+F/26lyJJvcfVH8VwTDb7nv y7wBl4Kpk2cS9hALfEsEUT4n0caPScVhEXc3KoiSKnuBzxd3qGWR6wEsJ9vfZQ== X-Gm-Gg: ATEYQzxgIKCa/Nv3rEadHEnoukAvuAyrPF36xxEzuUilUY+xn1ykHybXwQ9M3qfwIaf qStV8/CR8PVRcR9EjhdHPwAqJClqOcwSLt9kSyDJckm18HkiUW36MPqnw1ONfexuXjQFdRyDo98 Of4KQJJuZ0bTh5zGochPX3D4VB4AML/sjbmx3fOnA0ftzyg5EGI4MKywZcbp6zYCwLt14jwBNHO 1w901QwH8Ygfn77Uk/c59grqLlHD2kuteVVllbwiNXF+29nDu1NdYc9OWZ8MDHyw94RyulJFbRB jGXZlPI7vH47jeBUA/338lbBjlGVIDwmul4XqQWJCr014uxbX8SQdGJr66rOzzBD0X53GtkwSfh 3JWHfi5gWAAGdeEWFyrX1QTcIwIC3PwABKaas+VADkzm1nX0QI0YNmrmLdv1ldhjE4gWY8jwyPo 57hWBe6dFiyBBpkKihIkLE9H6gNzyQRZ5K/rEqcxieH4eFISQ5pot17d5QsV/uaCKGKg== X-Received: by 2002:a05:6402:5414:b0:659:5c63:e103 with SMTP id 4fb4d7f45d1cf-663ba9b6e96mr2330711a12.11.1773420287152; Fri, 13 Mar 2026 09:44:47 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Romain Caritey , Oleksii Kurochko , Alistair Francis , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini Subject: [PATCH v1 1/4] xen/riscv: add exception table support Date: Fri, 13 Mar 2026 17:44:35 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1773420311381154100 Content-Type: text/plain; charset="utf-8" Introduce exception table handling for RISC-V so faults from selected instructions can be recovered via fixup handlers instead of being treated as fatal. Add the RISC-V exception table format, sorting at boot to allow binary search used furthuer, and lookup from the trap handler. Update the linker script to emit the .ex_table section using introduced common EX_TABLE macro shared with other architectures. Also, the __start___ext_table is aligned now by POINTER_ALIGN instead of just using hard-coded 8 as there is no too much sense to align __start___ext_table by 8 for 32-bit systems. This implementation is based on Linux 6.16. Signed-off-by: Oleksii Kurochko --- Open question: With some renaming the following could be generic, at least, between x86 and RISC-V: - ASM_EXTABLE() definition - All what is conencted with sort_extable(). - With some change of how x86 searchs an extension this cmp_ex_search() could also go to common file. Does it make sense to introduce xen/extable.h and common/extable.c? --- xen/arch/riscv/Kconfig | 1 + xen/arch/riscv/Makefile | 1 + xen/arch/riscv/extables.c | 85 +++++++++++++++++++++++++++ xen/arch/riscv/include/asm/extables.h | 72 +++++++++++++++++++++++ xen/arch/riscv/setup.c | 3 + xen/arch/riscv/traps.c | 3 + xen/arch/riscv/xen.lds.S | 3 + xen/arch/x86/xen.lds.S | 6 +- xen/include/xen/xen.lds.h | 10 ++++ 9 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 xen/arch/riscv/extables.c create mode 100644 xen/arch/riscv/include/asm/extables.h diff --git a/xen/arch/riscv/Kconfig b/xen/arch/riscv/Kconfig index 89876b32175d..a5e87c1757f7 100644 --- a/xen/arch/riscv/Kconfig +++ b/xen/arch/riscv/Kconfig @@ -4,6 +4,7 @@ config RISCV select GENERIC_BUG_FRAME select GENERIC_UART_INIT select HAS_DEVICE_TREE_DISCOVERY + select HAS_EX_TABLE select HAS_PMAP select HAS_UBSAN select HAS_VMAP diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index ffbd7062e214..6b3f3ed90bdb 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -3,6 +3,7 @@ obj-y +=3D cpufeature.o obj-y +=3D domain.o obj-$(CONFIG_EARLY_PRINTK) +=3D early_printk.o obj-y +=3D entry.o +obj-$(CONFIG_HAS_EX_TABLE) +=3D extables.o obj-y +=3D imsic.o obj-y +=3D intc.o obj-y +=3D irq.o diff --git a/xen/arch/riscv/extables.c b/xen/arch/riscv/extables.c new file mode 100644 index 000000000000..5e6e453ead29 --- /dev/null +++ b/xen/arch/riscv/extables.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include +#include + +#define EX_FIELD(ptr, field) ((unsigned long)&(ptr)->field + (ptr)->field) + +static inline unsigned long ex_insn(const struct exception_table_entry *ex) +{ + return EX_FIELD(ex, insn); +} + +static inline unsigned long ex_fixup(const struct exception_table_entry *e= x) +{ + return EX_FIELD(ex, fixup); +} + +static void __init cf_check swap_ex(void *a, void *b) +{ + struct exception_table_entry *x =3D a, *y =3D b, tmp; + int delta =3D b - a; + + tmp =3D *x; + x->insn =3D y->insn + delta; + y->insn =3D tmp.insn - delta; + + x->fixup =3D y->fixup + delta; + y->fixup =3D tmp.fixup - delta; +} + +static int __init cf_check cmp_ex_sort(const void *a, const void *b) +{ + const unsigned long l =3D ex_insn(a); + const unsigned long r =3D ex_insn(b); + + /* avoid overflow */ + return (l > r) - (l < r); +} + +void __init sort_extable(void) +{ + sort(__start___ex_table, __stop___ex_table - __start___ex_table, + sizeof(struct exception_table_entry), cmp_ex_sort, swap_ex); +} + +static int cf_check cmp_ex_search(const void *key, const void *elt) +{ + const unsigned long k =3D *(const unsigned long *)key; + const unsigned long insn =3D ex_insn(elt); + + /* avoid overflow */ + return (k > insn) - (k < insn); +} + +static bool ex_handler_fixup(const struct exception_table_entry *ex, + struct cpu_user_regs *regs) +{ + regs->sepc =3D ex_fixup(ex); + + return true; +} + +bool fixup_exception(struct cpu_user_regs *regs) +{ + unsigned long pc =3D regs->sepc; + const struct virtual_region *region =3D find_text_region(pc); + const struct exception_table_entry *ex; + + if ( !region || !region->ex ) + return false; + + ex =3D bsearch(&pc, region->ex, region->ex_end - region->ex, + sizeof(struct exception_table_entry), cmp_ex_search); + + if ( !ex ) + return false; + + return ex_handler_fixup(ex, regs); +} diff --git a/xen/arch/riscv/include/asm/extables.h b/xen/arch/riscv/include= /asm/extables.h new file mode 100644 index 000000000000..139764f3808d --- /dev/null +++ b/xen/arch/riscv/include/asm/extables.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef ASM__RISCV__ASM_EXTABLES_H +#define ASM__RISCV__ASM_EXTABLES_H + +#ifdef __ASSEMBLER__ + +#define ASM_EXTABLE(insn, fixup) \ + .pushsection .ex_table, "a"; \ + .balign 4; \ + .long ((insn) - .); \ + .long ((fixup) - .); \ + .popsection; +.endm + +#else /* __ASSEMBLER__ */ + +#include +#include + +struct cpu_user_regs; + +#define ASM_EXTABLE(insn, fixup) \ + ".pushsection .ex_table, \"a\"\n" \ + ".balign 4\n" \ + ".long ((" #insn ") - .)\n" \ + ".long ((" #fixup ") - .)\n" \ + ".popsection\n" + +/* + * The exception table consists of pairs of relative offsets: the first + * is the relative offset to an instruction that is allowed to fault, + * and the second is the relative offset at which the program should + * continue. No registers are modified, so it is entirely up to the + * continuation code to figure out what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ +struct exception_table_entry { + int32_t insn, fixup; +}; + +extern struct exception_table_entry __start___ex_table[]; +extern struct exception_table_entry __stop___ex_table[]; + +#ifdef CONFIG_HAS_EX_TABLE + +void sort_extable(void); +bool fixup_exception(struct cpu_user_regs *regs); + +#else /* CONFIG_HAS_EX_TABLE */ + +static inline void sort_extable(void) +{ + printk("%s: We don't support .ex_table\n", __func__); +} + +static inline bool fixup_exception(struct cpu_user_regs *regs) +{ + dprintk("%s: We don't support .ex_table\n", __func__); + + return false; +} + +#endif /* CONFIG_HAS_EX_TABLE */ + +#endif /* __ASSEMBLY__ */ + +#endif /* ASM__RISCV__ASM_EXTABLES_H */ diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index cae49bb29626..4be6aa5a434e 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -19,6 +19,7 @@ =20 #include =20 +#include #include #include #include @@ -81,6 +82,8 @@ void __init noreturn start_xen(unsigned long bootcpu_id, =20 smp_prepare_boot_cpu(); =20 + sort_extable(); + set_cpuid_to_hartid(0, bootcpu_id); =20 trap_init(); diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c index 326f2be62823..242af0a7a5f3 100644 --- a/xen/arch/riscv/traps.c +++ b/xen/arch/riscv/traps.c @@ -12,6 +12,7 @@ #include #include =20 +#include #include #include #include @@ -217,6 +218,8 @@ void do_trap(struct cpu_user_regs *cpu_regs) =20 break; } + else if ( fixup_exception(cpu_regs) ) + break; fallthrough; default: if ( cause & CAUSE_IRQ_FLAG ) diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S index 331a7d63d3c9..65f136dce9f7 100644 --- a/xen/arch/riscv/xen.lds.S +++ b/xen/arch/riscv/xen.lds.S @@ -74,6 +74,9 @@ SECTIONS .data.ro_after_init : { __ro_after_init_start =3D .; *(.data.ro_after_init) + + EX_TABLE + . =3D ALIGN(PAGE_SIZE); __ro_after_init_end =3D .; } : text diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index c326538ebbb2..b9e888e5962f 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -113,11 +113,7 @@ SECTIONS __ro_after_init_start =3D .; *(.data.ro_after_init) =20 - . =3D ALIGN(8); - /* Exception table */ - __start___ex_table =3D .; - *(.ex_table) - __stop___ex_table =3D .; + EX_TABLE =20 . =3D ALIGN(PAGE_SIZE); __ro_after_init_end =3D .; diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h index 136849ecd515..85800f942aae 100644 --- a/xen/include/xen/xen.lds.h +++ b/xen/include/xen/xen.lds.h @@ -219,4 +219,14 @@ #define VPCI_ARRAY #endif =20 +#ifdef CONFIG_HAS_EX_TABLE +#define EX_TABLE \ + . =3D ALIGN(POINTER_ALIGN); \ + __start___ex_table =3D .; \ + *(.ex_table) \ + __stop___ex_table =3D .; +#else +#define EX_TABLE +#endif + #endif /* __XEN_LDS_H__ */ --=20 2.53.0