From 3b128c054885fe881c3b57a5978de3ea89c81a9c Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Fri, 11 Mar 2022 16:19:35 -0600 Subject: [PATCH] bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) In Linux kernel 5.14 one can dynamically request size of altstacksize based on hardware capabilities with getauxval(AT_MINSIGSTKSZ). This changes allows for Python extension's request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, unblocking use of the ISA in frameworks. Introduced HAVE_LINUX_AUXVEC_H in configure.ac and pyconfig.h.in Used cpython_autoconf:269 docker container to generate configure. --- .../2022-03-10-14-51-11.bpo-46968.ym2QxL.rst | 5 ++++ Modules/faulthandler.c | 26 ++++++++++++++----- configure | 2 +- configure.ac | 2 +- pyconfig.h.in | 3 +++ 5 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst new file mode 100644 index 00000000000..0da5ae76572 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst @@ -0,0 +1,5 @@ +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. +This changes allows for Python extension's request to Linux kernel to use +AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, +unblocking use of the ISA in frameworks. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index db3f4fbe5c6..744698cd7ab 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -20,6 +20,17 @@ # include #endif +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +# define FAULTHANDLER_USE_ALT_STACK +#endif + +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) +# include +# include +#endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) @@ -137,12 +148,6 @@ static fault_handler_t faulthandler_handlers[] = { static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #ifdef FAULTHANDLER_USE_ALT_STACK static stack_t stack; static stack_t old_stack; @@ -1373,6 +1378,15 @@ _PyFaulthandler_Init(int enable) signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; +#ifdef AT_MINSIGSTKSZ + /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery + for the hardware running CPython. This OS feature is available in + Linux kernel version >= 5.14 */ + unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ); + if (at_minstack_size != 0) { + stack.ss_size = SIGSTKSZ + at_minstack_size; + } +#endif #endif memset(&thread, 0, sizeof(thread)); diff --git a/configure b/configure index a8e78ce73e7..4d585eba626 100755 --- a/configure +++ b/configure @@ -8652,7 +8652,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h # checks for header files for ac_header in \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/configure.ac b/configure.ac index 3e7d04b8eae..81262ae38e5 100644 --- a/configure.ac +++ b/configure.ac @@ -2375,7 +2375,7 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) # checks for header files AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 40057e0ff87..1b84ee108fb 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -661,6 +661,9 @@ /* Define to 1 if you have the `linkat' function. */ #undef HAVE_LINKAT +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_AUXVEC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H