All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleksii Kurochko <oleksii.kurochko@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Oleksii Kurochko <oleksii.kurochko@gmail.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	George Dunlap <george.dunlap@citrix.com>,
	Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
	Stefano Stabellini <sstabellini@kernel.org>, Wei Liu <wl@xen.org>
Subject: [PATCH v1 1/4] xen: introduce CONFIG_GENERIC_BUG_FRAME
Date: Fri,  3 Feb 2023 19:05:47 +0200	[thread overview]
Message-ID: <8adf4aeff96750982e3d670cb3aed11553d546d5.1675441720.git.oleksii.kurochko@gmail.com> (raw)
In-Reply-To: <cover.1675441720.git.oleksii.kurochko@gmail.com>

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 <bug.h> from ARM was taken as the base version,
as it looks the most portable.

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 <oleksii.kurochko@gmail.com>
---
 xen/common/Kconfig    |   6 ++
 xen/common/Makefile   |   1 +
 xen/common/bug.c      |  88 +++++++++++++++++++++++++++++
 xen/include/xen/bug.h | 127 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 222 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 f1ea3199c8..811b4eaf3b 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -92,6 +92,12 @@ config STATIC_MEMORY
 
 	  If unsure, say N.
 
+config GENERIC_DO_BUG_FRAME
+	bool
+	help
+	  Generic do_bug_frame() function is needed to handle the type of bug
+	  frame and print an information about it.
+
 menu "Speculative hardening"
 
 config INDIRECT_THUNK
diff --git a/xen/common/Makefile b/xen/common/Makefile
index bbd75b4be6..7d04c8d3b2 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_ARGO) += argo.o
 obj-y += bitmap.o
+obj-$(CONFIG_GENERIC_DO_BUG_FRAME) += bug.o
 obj-$(CONFIG_HYPFS_CONFIG) += config_data.o
 obj-$(CONFIG_CORE_PARKING) += core_parking.o
 obj-y += cpu.o
diff --git a/xen/common/bug.c b/xen/common/bug.c
new file mode 100644
index 0000000000..393e58d571
--- /dev/null
+++ b/xen/common/bug.c
@@ -0,0 +1,88 @@
+#include <xen/bug.h>
+#include <xen/errno.h>
+#include <xen/types.h>
+#include <xen/kernel.h>
+#include <xen/string.h>
+#include <xen/virtual_region.h>
+
+#include <asm/processor.h>
+
+int do_bug_frame(const struct cpu_user_regs *regs, vaddr_t pc)
+{
+    const struct bug_frame *bug = NULL;
+    const char *prefix = "", *filename, *predicate;
+    unsigned long fixup;
+    int id = -1, lineno;
+    const struct virtual_region *region;
+
+    region = find_text_region(pc);
+    if ( region )
+    {
+        for ( id = 0; id < BUGFRAME_NR; id++ )
+        {
+            const struct bug_frame *b;
+            unsigned int i;
+
+            for ( i = 0, b = region->frame[id].bugs;
+                  i < region->frame[id].n_bugs; b++, i++ )
+            {
+                if ( ((vaddr_t)bug_loc(b)) == pc )
+                {
+                    bug = b;
+                    goto found;
+                }
+            }
+        }
+    }
+ found:
+    if ( !bug )
+        return -ENOENT;
+
+    if ( id == BUGFRAME_run_fn )
+    {
+        void (*fn)(const struct cpu_user_regs *) = (void *)regs->BUG_FN_REG;
+
+        fn(regs);
+        return 0;
+    }
+
+    /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
+    filename = bug_file(bug);
+    if ( !is_kernel(filename) )
+        return -EINVAL;
+    fixup = strlen(filename);
+    if ( fixup > 50 )
+    {
+        filename += fixup - 47;
+        prefix = "...";
+    }
+    lineno = bug_line(bug);
+
+    switch ( id )
+    {
+    case BUGFRAME_warn:
+        printk("Xen WARN at %s%s:%d\n", prefix, filename, lineno);
+        show_execution_state(regs);
+        return 0;
+
+    case BUGFRAME_bug:
+        printk("Xen BUG at %s%s:%d\n", prefix, filename, lineno);
+        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 = bug_msg(bug);
+        if ( !is_kernel(predicate) )
+            predicate = "<unknown>";
+
+        printk("Assertion '%s' failed at %s%s:%d\n",
+               predicate, prefix, filename, lineno);
+        show_execution_state(regs);
+        panic("Assertion '%s' failed at %s%s:%d\n",
+              predicate, prefix, filename, lineno);
+    }
+
+    return -EINVAL;
+}
+
diff --git a/xen/include/xen/bug.h b/xen/include/xen/bug.h
new file mode 100644
index 0000000000..b46dae035e
--- /dev/null
+++ b/xen/include/xen/bug.h
@@ -0,0 +1,127 @@
+#ifndef __XEN_BUG_H__
+#define __XEN_BUG_H__
+
+#define BUG_DISP_WIDTH    24
+#define BUG_LINE_LO_WIDTH (31 - BUG_DISP_WIDTH)
+#define BUG_LINE_HI_WIDTH (31 - BUG_DISP_WIDTH)
+
+#define BUGFRAME_run_fn 0
+#define BUGFRAME_warn   1
+#define BUGFRAME_bug    2
+#define BUGFRAME_assert 3
+
+#define BUGFRAME_NR     4
+
+#ifndef __ASSEMBLY__
+
+#include <xen/errno.h>
+#include <xen/stringify.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+
+#include <asm/bug.h>
+
+#ifndef BUG_FRAME_STUFF
+struct bug_frame {
+    signed int loc_disp;    /* Relative address to the bug address */
+    signed int file_disp;   /* Relative address to the filename */
+    signed int msg_disp;    /* Relative address to the predicate (for ASSERT) */
+    uint16_t line;          /* Line number */
+    uint32_t pad0:16;       /* Padding for 8-bytes align */
+};
+
+#define bug_loc(b) ((const void *)(b) + (b)->loc_disp)
+#define bug_file(b) ((const void *)(b) + (b)->file_disp);
+#define bug_line(b) ((b)->line)
+#define bug_msg(b) ((const char *)(b) + (b)->msg_disp)
+#endif /* BUG_FRAME_STUFF */
+
+#ifndef BUG_FRAME
+/* Many versions of GCC doesn't support the asm %c parameter which would
+ * be preferable to this unpleasantness. We use mergeable string
+ * sections to avoid multiple copies of the string appearing in the
+ * Xen image. BUGFRAME_run_fn needs to be handled separately.
+ */
+#define BUG_FRAME(type, line, file, has_msg, msg) do {                      \
+    BUILD_BUG_ON((line) >> 16);                                             \
+    BUILD_BUG_ON((type) >= BUGFRAME_NR);                                    \
+    asm ("1:"BUG_INSTR"\n"                                                  \
+         ".pushsection .rodata.str, \"aMS\", %progbits, 1\n"                \
+         "2:\t.asciz " __stringify(file) "\n"                               \
+         "3:\n"                                                             \
+         ".if " #has_msg "\n"                                               \
+         "\t.asciz " #msg "\n"                                              \
+         ".endif\n"                                                         \
+         ".popsection\n"                                                    \
+         ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\
+         "4:\n"                                                             \
+         ".p2align 2\n"                                                     \
+         ".long (1b - 4b)\n"                                                \
+         ".long (2b - 4b)\n"                                                \
+         ".long (3b - 4b)\n"                                                \
+         ".hword " __stringify(line) ", 0\n"                                \
+         ".popsection");                                                    \
+} while (0)
+#endif /* BUG_FRAME */
+
+#ifndef run_in_exception_handler
+/*
+ * GCC will not allow to use "i"  when PIE is enabled (Xen doesn't set the
+ * flag but instead rely on the default value from the compiler). So the
+ * easiest way to implement run_in_exception_handler() is to pass the to
+ * be called function in a fixed register.
+ */
+#define  run_in_exception_handler(fn) do {                                  \
+    register void *fn_ asm(__stringify(BUG_FN_REG)) = (fn);                 \
+    asm ("1:"BUG_INSTR"\n"                                                  \
+         ".pushsection .bug_frames." __stringify(BUGFRAME_run_fn) ","       \
+         "             \"a\", %%progbits\n"                                 \
+         "2:\n"                                                             \
+         ".p2align 2\n"                                                     \
+         ".long (1b - 2b)\n"                                                \
+         ".long 0, 0, 0\n"                                                  \
+         ".popsection" :: "r" (fn_));                                       \
+} while (0)
+#endif /* run_in_exception_handler */
+
+#ifndef WARN
+#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "")
+#endif /* WARN */
+
+#ifndef BUG
+#define BUG() do {                                              \
+    BUG_FRAME(BUGFRAME_bug,  __LINE__, __FILE__, 0, "");        \
+    unreachable();                                              \
+} while (0)
+#endif
+
+#ifndef assert_failed
+#define assert_failed(msg) do {                                 \
+    BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg);     \
+    unreachable();                                              \
+} while (0)
+#endif
+
+extern const struct bug_frame __start_bug_frames[],
+                              __stop_bug_frames_0[],
+                              __stop_bug_frames_1[],
+                              __stop_bug_frames_2[],
+                              __stop_bug_frames_3[];
+
+#else /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_X86
+#include <asm/bug.h>
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __XEN_BUG_H__ */
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.39.0



  reply	other threads:[~2023-02-03 17:06 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-03 17:05 [PATCH v1 0/4] introduce generic implementation of macros from bug.h Oleksii Kurochko
2023-02-03 17:05 ` Oleksii Kurochko [this message]
2023-02-13 12:24   ` [PATCH v1 1/4] xen: introduce CONFIG_GENERIC_BUG_FRAME Jan Beulich
2023-02-13 13:19     ` Julien Grall
2023-02-13 13:30       ` Jan Beulich
2023-02-13 13:56         ` Julien Grall
2023-02-13 15:02           ` Jan Beulich
2023-02-13 15:07             ` Julien Grall
2023-02-13 15:14               ` Jan Beulich
2023-02-13 13:33       ` Andrew Cooper
2023-02-13 13:55         ` Julien Grall
2023-02-14 16:22     ` Oleksii
2023-02-14 16:55       ` Jan Beulich
2023-02-15 15:06         ` Oleksii
2023-02-15 17:59         ` Oleksii
2023-02-16  7:31           ` Jan Beulich
2023-02-16 10:44             ` Oleksii
2023-02-16 12:09               ` Oleksii
2023-02-16 12:19                 ` Andrew Cooper
2023-02-16 20:44                   ` Oleksii
2023-02-17  7:12                     ` Jan Beulich
2023-02-17  9:33                       ` Oleksii
2023-02-16 14:55               ` Jan Beulich
2023-02-16 10:48             ` Andrew Cooper
2023-02-16 12:21               ` Oleksii
2023-02-16 14:53               ` Jan Beulich
2023-02-03 17:05 ` [PATCH v1 2/4] xen/arm: switch ARM to use generic implementation of bug.h Oleksii Kurochko
2023-02-13 13:02   ` Jan Beulich
2023-02-14 16:28     ` Oleksii
2023-02-03 17:05 ` [PATCH v1 3/4] xen/x86: switch x86 to use generic implemetation " Oleksii Kurochko
2023-02-13 13:10   ` Jan Beulich
2023-02-14 16:41     ` Oleksii
2023-02-03 17:05 ` [PATCH v1 4/4] xen: change <asm/bug.h> to <xen/bug.h> Oleksii Kurochko
2023-02-13 13:13   ` Jan Beulich
2023-02-14 16:44     ` Oleksii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8adf4aeff96750982e3d670cb3aed11553d546d5.1675441720.git.oleksii.kurochko@gmail.com \
    --to=oleksii.kurochko@gmail.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=george.dunlap@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=sstabellini@kernel.org \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.