From nobody Mon Feb 9 10:39:13 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=1680087110; cv=none; d=zohomail.com; s=zohoarc; b=ZEf5M2WhKH+izf1j7PjstFACuPrlZRFxlSNhC9EOUZ3qG4QdWBIYy1eckvhZ1JI84kzdu2xrnIVFzwbu8BeK3cPExwoTNuLtk9AKJBBdJ3X/ra5HHaNzrlmK+DC3I6BiMj04JLy9fbDQ1k0TMIKf9r+QJJo/V3iT55zYby/Spn8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1680087110; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=G+SyusVLNbqVMrW8ZRpmVQ40Jehx8sJ9+PJYZzoVhT8=; b=jKdsPv/yrlINd1jBRlnYAbHMFUZ1x+ziDEFiJSMExbs11FhVxyZdfJgKwJYYJtTY8g40pg0w06PL39hJ66YQFoxJhnKBOBtIoRCYdJPK9obdRF74PfTsHhhBG5S7KlO0KirjiDAyVnbqeT9SRn4Hz0GAbu80Hq+bAhHO44bNSy8= 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 1680087110867638.9636041870579; Wed, 29 Mar 2023 03:51:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.516184.799907 (Exim 4.92) (envelope-from ) id 1phTOX-00081I-KQ; Wed, 29 Mar 2023 10:51:09 +0000 Received: by outflank-mailman (output) from mailman id 516184.799907; Wed, 29 Mar 2023 10:51:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1phTOX-00081B-HZ; Wed, 29 Mar 2023 10:51:09 +0000 Received: by outflank-mailman (input) for mailman id 516184; Wed, 29 Mar 2023 10:51:08 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1phTOW-0007lb-4E for xen-devel@lists.xenproject.org; Wed, 29 Mar 2023 10:51:08 +0000 Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [2a00:1450:4864:20::12b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 9b88ce0e-ce1f-11ed-85db-49a42c6b2330; Wed, 29 Mar 2023 12:51:06 +0200 (CEST) Received: by mail-lf1-x12b.google.com with SMTP id k37so19602307lfv.0 for ; Wed, 29 Mar 2023 03:51:06 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id j17-20020ac253b1000000b004eb0f6b7ccfsm1173572lfh.134.2023.03.29.03.51.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Mar 2023 03:51:05 -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: 9b88ce0e-ce1f-11ed-85db-49a42c6b2330 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680087066; 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=G+SyusVLNbqVMrW8ZRpmVQ40Jehx8sJ9+PJYZzoVhT8=; b=S+Hrmaxf8pMC9LSHW+l8zJsFz405qpjG46TIID8rth8PoG/9eGviAuSsd5BfnRCdfi pKrDX4q6/vaOmqrcdiTPbMRrZbXKX5ziB/k4/RnxSybDALlRHEN+659Pob8QE3l6BrUS 0ouJyhypqznny50k3ZEXcZzk3+bUVeZPH+ZEsAHGJpqBco8JkkLyEyFwLEr4ljLi8eTb r4vZsi0ADPmqm11AgdrKG4XXw6IbJ0myCwgVvby36Bsj8Dv2ROUs/lXLClRsiOH6R5hn EEfHRY4HQC5bSAD6R+SFHtvH1XdwfuwT+4KWAiowfaFuG9jWFE/WyZgLlvxmLD54Wv1D Oesw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680087066; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G+SyusVLNbqVMrW8ZRpmVQ40Jehx8sJ9+PJYZzoVhT8=; b=hOwPUDKZZLI/E2VOUeoVOo71x8z+Sdyk9N+3ReBa2dvyjutzLyDW8vzNBjeb+OH6zt eS6iid0BYVSWUpsBT6Iy9g+MfTp3C7XHBgFjXLACZLjjRglH65KC+hWWaNamrHODxu7C FTmisusKhjs6vPWXiHS7XO6JrvODLbOdx8WWPPw5YvncSudM/xM5oZQg0H4lNlGEAbFN WZH58s5qMzWBTXFZX818nLz+7UOM0YLm0eUDOiKzhHSJxwcc3Or6t3oG7u+5HhB+kueM ORuxrUODCGoYvxcrkTnObnC6VveHad1X62Yr+qxLcpmlkrBVie9dw3TTqsRetCIOyQe6 IJyg== X-Gm-Message-State: AAQBX9egVdh5Qtkfn1IKfs/AgvqJF6esIqS6uMo8rvebChgw3tfgQ1Jb HVDtwSt/Jm9KNYSNoKgOkzqbYBeFDCo= X-Google-Smtp-Source: AKy350afs6RDHIFsWJidIx/0a45G1DYXY+mEijDW6N78rrBUHoDvE2SsAxa5nH0eoSQaUS90Ds0RuQ== X-Received: by 2002:ac2:490f:0:b0:4e8:4a9d:2ae1 with SMTP id n15-20020ac2490f000000b004e84a9d2ae1mr4551091lfi.32.1680087066129; Wed, 29 Mar 2023 03:51:06 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Julien Grall , Jan Beulich , Andrew Cooper , Stefano Stabellini , Gianluca Guida , Oleksii Kurochko , George Dunlap , Wei Liu Subject: [PATCH v9 1/5] xen: introduce CONFIG_GENERIC_BUG_FRAME Date: Wed, 29 Mar 2023 13:50:28 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1680087111361100006 Content-Type: text/plain; charset="utf-8" A large part of the content of the bug.h is repeated among all architectures, so it was decided to create a new config CONFIG_GENERIC_BUG_FRAME. The version of from x86 was taken as the base version. The patch introduces the following stuff: * common bug.h header * generic implementation of do_bug_frame * new config CONFIG_GENERIC_BUG_FRAME Signed-off-by: Oleksii Kurochko Acked-by: Julien Grall Reviewed-by: Jan Beulich Tested-by: Julien Grall --- Changes in V9: * rename BUILD_BUG_ON_LINE_WIDTH to BUG_CHECK_LINE_WIDTH * Remove from as the patch were merged to staging which move all things used in from to more proper headers. * add "struct cpu_user_regs" to . * add explanation why is included in --- Changes in V8: * move BUILD_BUG_ON_LINE_WIDTH(line) to "ifndef BUG_FRAME_STRUCT" and add= #elif for "ifndef BUG_FRAME_STRUCT" to define stub for BUILD_BUG_ON_LINE_WIDTH. * move from to to fix compilati= on issue ( more details in the changes to the patch [xen/x86: switch x86 to use g= eneric implemetation of bug.h] ). --- Changes in V7: * fix code style. * Remove '#include ' from bug.c. it should be a part of . * move BUILD_BUG_ON_LINE_WIDTH to '#ifndef BUG_FRAME_STRUCT' and define dummy BUILD_BUG_ON_LINE_WIDTH when BUG_FRAME_STRUCT is defined. * remove update prototype of 'void (*fn)(const struct cpu_user_regs *)' to 'void (*fn)(struct cpu_user_regs *)'. * add code to to make sure the type used in run_in_exception_handler() matches the one used here. --- Changes in V6: * fix code style. * change -EINVAL to -ENOENT in case when bug_frame wasn't found in generic do_bug_frame() * change all 'return id' to 'break' inside switch/case of generic do_bug_f= rame() * move up "#ifndef __ASSEMBLY__" to include BUG_DEBUGGER_TRAP_FATAL * update the comment of BUG_ASM_CONST * make the line with 'BUILD_BUG_ON((line) >> (BUG_LINE_LO_WIDTH + BUG_LINE= _HI_WIDTH))' in BUG_FRAME macros more abstract * remove #ifndef BUG_FRAME_STRUCT around BUG_DISP_WIDTH, BUG_LINE_LO_WIDTH= as it is required to be defined before as it is used by x86's when the header is included in assembly code. --- Changes in V5: * Remove "#ifdef BUG_FN_REG..." from generic do_bug_frame() as ARM will use generic implementation fully. --- Changes in V4: * common/bug.c: - Use BUG_DEBUGGER_TRAP_FATAL(regs) mnacros instead of debugger_trap_fata= l(TRAP_invalid_op, regs) in as TRAP_invalid_op is x86-specific thereby BUG_DEBUGG= ER_TRAP_FATAL should be defined for each architecture. - add information about what do_bug_frame() returns. - invert the condition 'if ( region )' in do_bug_frame() to reduce the in= dention. - change type of variable i from 'unsigned int' to 'size_t' as it is com= pared with n_bugs which has type 'size_t' * xen/bug.h: - Introduce generic BUG_DEBUGGER_TRAP_FATAL(regs) mnacros which is used t= o deal with=20 debugger_trap_fatal(TRAP_invalid_op, regs) where TRAP_invalid_op is x86= -specific - remove '#include ' as it doesn't need any more after s= witch to x86 implementation. - remove '#include ' as it isn't needed any more - move bug_*() macros inside '#ifndef BUG_FRAME_STRUCT' - add to fix compile issue with BUILD_ON()... - Add documentation for BUG_ASM_CONST. * Update the commit message --- Changes in V3: * Add debugger_trap_fatal() to do_bug_frame(). It simplifies usage of do_bug_frame() for x86 so making handle_bug_frame() and find_bug_frame() not needed anymore. * Update do_bug_frame() to return -EINVAL if something goes wrong; otherwi= se id of bug_frame * Update _ASM_BUGFRAME_TEXT to make it more portable. * Drop unnecessary comments. * define stub value for TRAP_invalid_op in case if wasn't defined in arch-specific folders. --- Changes in V2: - Switch to x86 implementation as generic as it is more compact ( at least from the point of view of bug frame structure ). - Rename CONFIG_GENERIC_DO_BUG_FRAME to CONFIG_GENERIC_BUG_FRAME. - Change the macro bug_loc(b) to avoid the need for a cast: #define bug_loc(b) ((unsigned long)(b) + (b)->loc_disp) - Rename BUG_FRAME_STUFF to BUG_FRAME_STRUCT - Make macros related to bug frame structure more generic. - Introduce BUG_INSTR and MODIFIER to make _ASM_BUGFRAME_TEXT reusable between x86 and RISC-V. - Rework do_bug_frame() and introduce find_bug_frame() and handle_bug_fra= me() functions to make it reusable by x86. - code style fixes --- xen/common/Kconfig | 3 + xen/common/Makefile | 1 + xen/common/bug.c | 126 +++++++++++++++++++++++++++++++++ xen/include/xen/bug.h | 161 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 xen/common/bug.c create mode 100644 xen/include/xen/bug.h diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 855c843113..3d2123a783 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -29,6 +29,9 @@ config ALTERNATIVE_CALL config ARCH_MAP_DOMAIN_PAGE bool =20 +config GENERIC_BUG_FRAME + bool + config HAS_ALTERNATIVE bool =20 diff --git a/xen/common/Makefile b/xen/common/Makefile index bbd75b4be6..46049eac35 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_ARGO) +=3D argo.o obj-y +=3D bitmap.o +obj-$(CONFIG_GENERIC_BUG_FRAME) +=3D bug.o obj-$(CONFIG_HYPFS_CONFIG) +=3D config_data.o obj-$(CONFIG_CORE_PARKING) +=3D core_parking.o obj-y +=3D cpu.o diff --git a/xen/common/bug.c b/xen/common/bug.c new file mode 100644 index 0000000000..680269b49a --- /dev/null +++ b/xen/common/bug.c @@ -0,0 +1,126 @@ +#include +/* + * Ideally should be included in + * but an issue with compilation can occur as uses + * BUG/ASSERT/etc macros inside but they will be defined later in + * after return from inclusion of : + *=20 + * : + * ... + * : + * ... + * -> some of included header in it uses BUG/ASSERT/e= tc + * ... + * ... + * #define BUG() ... + * ... + * #define ASSERT() ... + * ... + */ +#include +#include +#include +#include +#include +#include +#include + +struct cpu_user_regs; + +/* + * Returns a negative value in case of an error otherwise + * BUGFRAME_{run_fn, warn, bug, assert} + */ +int do_bug_frame(struct cpu_user_regs *regs, unsigned long pc) +{ + const struct bug_frame *bug =3D NULL; + const struct virtual_region *region; + const char *prefix =3D "", *filename, *predicate; + unsigned long fixup; + unsigned int id, lineno; + + region =3D find_text_region(pc); + if ( !region ) + return -EINVAL; + + for ( id =3D 0; id < BUGFRAME_NR; id++ ) + { + const struct bug_frame *b; + size_t i; + + for ( i =3D 0, b =3D region->frame[id].bugs; + i < region->frame[id].n_bugs; b++, i++ ) + { + if ( bug_loc(b) =3D=3D pc ) + { + bug =3D b; + goto found; + } + } + } + + found: + if ( !bug ) + return -ENOENT; + + if ( id =3D=3D BUGFRAME_run_fn ) + { + void (*fn)(struct cpu_user_regs *) =3D bug_ptr(bug); + + fn(regs); + + /* Re-enforce consistent types, because of the casts involved. */ + if ( false ) + run_in_exception_handler(fn); + + return id; + } + + /* WARN, BUG or ASSERT: decode the filename pointer and line number. */ + filename =3D bug_ptr(bug); + if ( !is_kernel(filename) && !is_patch(filename) ) + return -EINVAL; + fixup =3D strlen(filename); + if ( fixup > 50 ) + { + filename +=3D fixup - 47; + prefix =3D "..."; + } + lineno =3D bug_line(bug); + + switch ( id ) + { + case BUGFRAME_warn: + printk("Xen WARN at %s%s:%d\n", prefix, filename, lineno); + show_execution_state(regs); + + break; + + case BUGFRAME_bug: + printk("Xen BUG at %s%s:%d\n", prefix, filename, lineno); + + if ( BUG_DEBUGGER_TRAP_FATAL(regs) ) + break; + + show_execution_state(regs); + panic("Xen BUG at %s%s:%d\n", prefix, filename, lineno); + + case BUGFRAME_assert: + /* ASSERT: decode the predicate string pointer. */ + predicate =3D bug_msg(bug); + if ( !is_kernel(predicate) && !is_patch(predicate) ) + predicate =3D ""; + + printk("Assertion '%s' failed at %s%s:%d\n", + predicate, prefix, filename, lineno); + + if ( BUG_DEBUGGER_TRAP_FATAL(regs) ) + break; + + show_execution_state(regs); + panic("Assertion '%s' failed at %s%s:%d\n", + predicate, prefix, filename, lineno); + } + + return id; +} diff --git a/xen/include/xen/bug.h b/xen/include/xen/bug.h new file mode 100644 index 0000000000..4438b31ee2 --- /dev/null +++ b/xen/include/xen/bug.h @@ -0,0 +1,161 @@ +#ifndef __XEN_BUG_H__ +#define __XEN_BUG_H__ + +#define BUGFRAME_run_fn 0 +#define BUGFRAME_warn 1 +#define BUGFRAME_bug 2 +#define BUGFRAME_assert 3 + +#define BUGFRAME_NR 4 + +#define BUG_DISP_WIDTH 24 +#define BUG_LINE_LO_WIDTH (31 - BUG_DISP_WIDTH) +#define BUG_LINE_HI_WIDTH (31 - BUG_DISP_WIDTH) + +#include + +#ifndef __ASSEMBLY__ + +#ifndef BUG_DEBUGGER_TRAP_FATAL +#define BUG_DEBUGGER_TRAP_FATAL(regs) 0 +#endif + +#include + +#ifndef BUG_FRAME_STRUCT + +struct bug_frame { + signed int loc_disp:BUG_DISP_WIDTH; + unsigned int line_hi:BUG_LINE_HI_WIDTH; + signed int ptr_disp:BUG_DISP_WIDTH; + unsigned int line_lo:BUG_LINE_LO_WIDTH; + signed int msg_disp[]; +}; + +#define bug_loc(b) ((unsigned long)(b) + (b)->loc_disp) + +#define bug_ptr(b) ((const void *)(b) + (b)->ptr_disp) + +#define bug_line(b) (((((b)->line_hi + ((b)->loc_disp < 0)) & = \ + ((1 << BUG_LINE_HI_WIDTH) - 1)) << = \ + BUG_LINE_LO_WIDTH) + = \ + (((b)->line_lo + ((b)->ptr_disp < 0)) & = \ + ((1 << BUG_LINE_LO_WIDTH) - 1))) + +#define bug_msg(b) ((const char *)(b) + (b)->msg_disp[1]) + +#define BUG_CHECK_LINE_WIDTH(line) \ + BUILD_BUG_ON((line) >> (BUG_LINE_LO_WIDTH + BUG_LINE_HI_WIDTH)) + +#elif !defined(BUG_CHECK_LINE_WIDTH) + +#define BUG_CHECK_LINE_WIDTH(line) ((void)(line) + +#endif /* BUG_FRAME_STRUCT */ + + +/* + * Some architectures mark immediate instruction operands in a special way. + * In such cases the special marking may need omitting when specifying + * directive operands. Allow architectures to specify a suitable + * modifier. + */ +#ifndef BUG_ASM_CONST +#define BUG_ASM_CONST "" +#endif + +#ifndef _ASM_BUGFRAME_TEXT + +#define _ASM_BUGFRAME_TEXT(second_frame) = \ + ".Lbug%=3D:"BUG_INSTR"\n" = \ + " .pushsection .bug_frames.%"BUG_ASM_CONST"[bf_type], \"a\", %%progb= its\n" \ + " .p2align 2\n" = \ + ".Lfrm%=3D:\n" = \ + " .long (.Lbug%=3D - .Lfrm%=3D) + %"BUG_ASM_CONST"[bf_line_hi]\n" = \ + " .long (%"BUG_ASM_CONST"[bf_ptr] - .Lfrm%=3D) + %"BUG_ASM_CONST"[bf= _line_lo]\n"\ + " .if " #second_frame "\n" = \ + " .long 0, %"BUG_ASM_CONST"[bf_msg] - .Lfrm%=3D\n" = \ + " .endif\n" = \ + " .popsection\n" + +#define _ASM_BUGFRAME_INFO(type, line, ptr, msg) = \ + [bf_type] "i" (type), = \ + [bf_ptr] "i" (ptr), = \ + [bf_msg] "i" (msg), = \ + [bf_line_lo] "i" ((line & ((1 << BUG_LINE_LO_WIDTH) - 1)) = \ + << BUG_DISP_WIDTH), = \ + [bf_line_hi] "i" (((line) >> BUG_LINE_LO_WIDTH) << BUG_DISP_WIDTH) + +#endif /* _ASM_BUGFRAME_TEXT */ + +#ifndef BUG_FRAME + +#define BUG_FRAME(type, line, ptr, second_frame, msg) do { = \ + BUG_CHECK_LINE_WIDTH(line); \ + BUILD_BUG_ON((type) >=3D BUGFRAME_NR); = \ + asm volatile ( _ASM_BUGFRAME_TEXT(second_frame) = \ + :: _ASM_BUGFRAME_INFO(type, line, ptr, msg) ); = \ +} while ( false ) + +#endif + +#ifndef run_in_exception_handler + +/* + * TODO: untangle header dependences, break BUILD_BUG_ON() out of xen/lib.= h, + * and use a real static inline here to get proper type checking of fn(). + */ +#define run_in_exception_handler(fn) do { \ + (void)((fn) =3D=3D (void (*)(struct cpu_user_regs *))NULL); \ + BUG_FRAME(BUGFRAME_run_fn, 0, fn, 0, NULL); \ +} while ( false ) + +#endif /* run_in_exception_handler */ + +#ifndef WARN +#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, NULL) +#endif + +#ifndef BUG +#define BUG() do { \ + BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, 0, NULL); \ + unreachable(); \ +} while ( false ) +#endif + +#ifndef assert_failed +#define assert_failed(msg) do { \ + BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg); \ + unreachable(); \ +} while ( false ) +#endif + +#ifdef CONFIG_GENERIC_BUG_FRAME + +struct cpu_user_regs; + +/* + * Returns a negative value in case of an error otherwise + * BUGFRAME_{run_fn, warn, bug, assert} + */ +int do_bug_frame(struct cpu_user_regs *regs, unsigned long pc); + +#endif /* CONFIG_GENERIC_BUG_FRAME */ + +extern const struct bug_frame __start_bug_frames[], + __stop_bug_frames_0[], + __stop_bug_frames_1[], + __stop_bug_frames_2[], + __stop_bug_frames_3[]; + +#endif /* !__ASSEMBLY__ */ + +#endif /* __XEN_BUG_H__ */ +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.39.2