From a66b286e7301cb14f3250e69320e44ff99d22a74 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Wed, 26 Jun 2024 14:31:13 +0100 Subject: [PATCH] arm-gcs/linux-yocto: update to 6.10-rc3 and v9 of the GCS patches Signed-off-by: Ross Burton --- .../recipes-kernel/linux/files/gcs.patch | 1446 ++++++++++------- .../linux/linux-yocto-dev.bbappend | 8 +- 2 files changed, 822 insertions(+), 632 deletions(-) diff --git a/meta-arm-gcs/recipes-kernel/linux/files/gcs.patch b/meta-arm-gcs/recipes-kernel/linux/files/gcs.patch index 9000123a..2c9bd049 100644 --- a/meta-arm-gcs/recipes-kernel/linux/files/gcs.patch +++ b/meta-arm-gcs/recipes-kernel/linux/files/gcs.patch @@ -1,10 +1,7 @@ -Upstream-Status: Submitted [https://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git/log/?h=arm64-gcs] -Signed-off-by: Ross Burton - -From acd6dd784ab9ef8a30a45d6145b5bc17c4373d65 Mon Sep 17 00:00:00 2001 +From 802aaf860bb5f70c9b87385eab6178d3f15cd781 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 18 Jan 2024 21:30:07 +0000 -Subject: [PATCH 02/47] Documentation: userspace-api: Add shadow stack API +Subject: [PATCH 02/50] Documentation: userspace-api: Add shadow stack API documentation There are a number of architectures with shadow stack features which we are @@ -14,6 +11,10 @@ important considerations for userspace code interacting directly with the feature let's provide some documentation covering the common aspects. Signed-off-by: Mark Brown + +Upstream-Status: Submitted [https://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc.git/log/?h=arm64-gcs] +Signed-off-by: Ross Burton + --- Documentation/userspace-api/index.rst | 1 + Documentation/userspace-api/shadow_stack.rst | 41 ++++++++++++++++++++ @@ -21,12 +22,12 @@ Signed-off-by: Mark Brown create mode 100644 Documentation/userspace-api/shadow_stack.rst diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst -index 09f61bd2ac2e..c142183d9c98 100644 +index 5926115ec0ed8..d60a6dc0cbcff 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst -@@ -27,6 +27,7 @@ place where this information is gathered. - iommufd - media/index +@@ -59,6 +59,7 @@ Everything else + + ELF netlink/index + shadow_stack sysfs-platform_profile @@ -34,7 +35,7 @@ index 09f61bd2ac2e..c142183d9c98 100644 futex2 diff --git a/Documentation/userspace-api/shadow_stack.rst b/Documentation/userspace-api/shadow_stack.rst new file mode 100644 -index 000000000000..c576ad3d7ec1 +index 0000000000000..c576ad3d7ec12 --- /dev/null +++ b/Documentation/userspace-api/shadow_stack.rst @@ -0,0 +1,41 @@ @@ -83,10 +84,10 @@ index 000000000000..c576ad3d7ec1 2.34.1 -From 4963da85eea04bd35672dfe2b43306b451c32bcd Mon Sep 17 00:00:00 2001 +From 5c5bd1324b075333416fd10251f61e7970051cd6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 29 Jan 2024 22:29:38 +0000 -Subject: [PATCH 03/47] selftests: Provide helper header for shadow stack +Subject: [PATCH 03/50] selftests: Provide helper header for shadow stack testing While almost all users of shadow stacks should be relying on the dynamic @@ -100,6 +101,7 @@ filesystems to have enablement. Provide a header with helpers for this purpose, intended for use only by test programs directly exercising shadow stack interfaces. +Reviewed-by: Rick Edgecombe Signed-off-by: Mark Brown --- tools/testing/selftests/ksft_shstk.h | 63 ++++++++++++++++++++++++++++ @@ -108,7 +110,7 @@ Signed-off-by: Mark Brown diff --git a/tools/testing/selftests/ksft_shstk.h b/tools/testing/selftests/ksft_shstk.h new file mode 100644 -index 000000000000..85d0747c1802 +index 0000000000000..85d0747c18022 --- /dev/null +++ b/tools/testing/selftests/ksft_shstk.h @@ -0,0 +1,63 @@ @@ -179,10 +181,10 @@ index 000000000000..85d0747c1802 2.34.1 -From dd5a2bea25b99868e19cf250f87fcefff2851857 Mon Sep 17 00:00:00 2001 +From a7f27146a718276ca001393ef91db3f9c583619a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 19 Oct 2023 17:43:34 +0100 -Subject: [PATCH 04/47] mm: Introduce ARCH_HAS_USER_SHADOW_STACK +Subject: [PATCH 04/50] mm: Introduce ARCH_HAS_USER_SHADOW_STACK Since multiple architectures have support for shadow stacks and we need to select support for this feature in several places in the generic code @@ -190,6 +192,8 @@ provide a generic config option that the architectures can select. Suggested-by: David Hildenbrand Acked-by: David Hildenbrand +Reviewed-by: Deepak Gupta +Reviewed-by: Rick Edgecombe Signed-off-by: Mark Brown --- arch/x86/Kconfig | 1 + @@ -199,10 +203,10 @@ Signed-off-by: Mark Brown 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 5edec175b9bf..34553911d07d 100644 +index 1d7122a1883e8..4a5e40d4c14e1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -1952,6 +1952,7 @@ config X86_USER_SHADOW_STACK +@@ -1949,6 +1949,7 @@ config X86_USER_SHADOW_STACK depends on AS_WRUSS depends on X86_64 select ARCH_USES_HIGH_VMA_FLAGS @@ -211,10 +215,10 @@ index 5edec175b9bf..34553911d07d 100644 help Shadow stack protection is a hardware feature that detects function diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 3f78ebbb795f..ff2c601f7d1c 100644 +index f8d35f993fe50..1b56c10775072 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c -@@ -700,7 +700,7 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) +@@ -704,7 +704,7 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR [ilog2(VM_UFFD_MINOR)] = "ui", #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ @@ -224,10 +228,10 @@ index 3f78ebbb795f..ff2c601f7d1c 100644 #endif }; diff --git a/include/linux/mm.h b/include/linux/mm.h -index f5a97dec5169..c0a782eda803 100644 +index 9849dfda44d43..5ec7bc3556578 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -341,7 +341,7 @@ extern unsigned int kobjsize(const void *objp); +@@ -342,7 +342,7 @@ extern unsigned int kobjsize(const void *objp); #endif #endif /* CONFIG_ARCH_HAS_PKEYS */ @@ -237,18 +241,18 @@ index f5a97dec5169..c0a782eda803 100644 * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of * support core mm. diff --git a/mm/Kconfig b/mm/Kconfig -index ffc3a2ba3a8c..9119e016777a 100644 +index b4cb45255a541..45416916dec1e 100644 --- a/mm/Kconfig +++ b/mm/Kconfig -@@ -1261,6 +1261,12 @@ config LOCK_MM_AND_FIND_VMA - config IOMMU_MM_DATA +@@ -1249,6 +1249,12 @@ config IOMMU_MM_DATA + config EXECMEM bool +config ARCH_HAS_USER_SHADOW_STACK + bool + help + The architecture has hardware support for userspace shadow call -+ stacks (eg, x86 CET, arm64 GCS or RISC-V Zicfiss). ++ stacks (eg, x87 CET, arm64 GCS or RISC-V Zicfiss). + source "mm/damon/Kconfig" @@ -257,10 +261,10 @@ index ffc3a2ba3a8c..9119e016777a 100644 2.34.1 -From 8433014f7ee3beaba9ff2e37d1c517f4625db150 Mon Sep 17 00:00:00 2001 +From e5ddf197fb74f41da968a4d2198c11b4b70c2e44 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Oct 2023 19:40:40 +0100 -Subject: [PATCH 05/47] fork: Add shadow stack support to clone3() +Subject: [PATCH 05/50] fork: Add shadow stack support to clone3() Unlike with the normal stack there is no API for configuring the the shadow stack for a new thread, instead the kernel will dynamically allocate a new @@ -268,12 +272,19 @@ shadow stack with the same size as the normal stack. This appears to be due to the shadow stack series having been in development since before the more extensible clone3() was added rather than anything more deliberate. -Add a parameter to clone3() specifying the size of a shadow stack for -the newly created process. If no shadow stack is specified then the -existing implicit allocation behaviour is maintained. +Add parameters to clone3() specifying the location and size of a shadow +stack for the newly created process. If no shadow stack is specified +then the existing implicit allocation behaviour is maintained. -If the architecture does not support shadow stacks the shadow stack size -parameter must be zero, architectures that do support the feature are +If a stack is specified then it is required to have an architecture +defined token placed on the stack, this will be consumed by the new +task. If the token is not provided then this will be reported as a +segmentation fault with si_code SEGV_CPERR, as a runtime shadow stack +protection error would be. This allows architectures to implement the +validation of the token in the child process context. + +If the architecture does not support shadow stacks the shadow stack +parameters must be zero, architectures that do support the feature are expected to enforce the same requirement on individual systems that lack shadow stack support. @@ -284,21 +295,21 @@ parameters, detailed enforcement is left to when the thread is executed. Since we are now using more fields from the kernel_clone_args we pass that into the shadow stack code rather than individual fields. -At present this implemntation does not consume the shadow stack token -atomically as would be desirable. +At present this implementation does not consume the shadow stack token +atomically as would be desirable, it uses a separate read and write. Signed-off-by: Mark Brown --- - arch/x86/include/asm/shstk.h | 11 +++-- - arch/x86/kernel/process.c | 2 +- - arch/x86/kernel/shstk.c | 94 +++++++++++++++++++++++++++--------- - include/linux/sched/task.h | 2 + - include/uapi/linux/sched.h | 13 +++-- - kernel/fork.c | 61 ++++++++++++++++++----- - 6 files changed, 140 insertions(+), 43 deletions(-) + arch/x86/include/asm/shstk.h | 11 ++-- + arch/x86/kernel/process.c | 2 +- + arch/x86/kernel/shstk.c | 104 +++++++++++++++++++++++++++-------- + include/linux/sched/task.h | 13 +++++ + include/uapi/linux/sched.h | 13 ++++- + kernel/fork.c | 76 +++++++++++++++++++++---- + 6 files changed, 176 insertions(+), 43 deletions(-) diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h -index 42fee8959df7..8be7b0a909c3 100644 +index 42fee8959df7b..8be7b0a909c37 100644 --- a/arch/x86/include/asm/shstk.h +++ b/arch/x86/include/asm/shstk.h @@ -6,6 +6,7 @@ @@ -334,7 +345,7 @@ index 42fee8959df7..8be7b0a909c3 100644 static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; } static inline int restore_signal_shadow_stack(void) { return 0; } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c -index ab49ade31b0d..d2bfcd44de05 100644 +index b8441147eb5e8..f206e997f91d2 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -207,7 +207,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) @@ -347,34 +358,51 @@ index ab49ade31b0d..d2bfcd44de05 100644 return PTR_ERR((void *)new_ssp); diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c -index 59e15dd8d0f8..935ced6cf4f5 100644 +index 6f1e9883f0742..953cc08930972 100644 --- a/arch/x86/kernel/shstk.c +++ b/arch/x86/kernel/shstk.c -@@ -191,44 +191,92 @@ void reset_thread_features(void) +@@ -191,44 +191,102 @@ void reset_thread_features(void) current->thread.features_locked = 0; } -unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags, - unsigned long stack_size) -+static bool shstk_consume_token(struct task_struct *tsk, -+ unsigned long addr) ++int arch_shstk_post_fork(struct task_struct *t, struct kernel_clone_args *args) +{ + /* + * SSP is aligned, so reserved bits and mode bit are a zero, just mark + * the token 64-bit. + */ -+ u64 expected = (addr - SS_FRAME_SIZE) | BIT(0); ++ struct mm_struct *mm; ++ unsigned long addr; ++ u64 expected; + u64 val; ++ int ret = -EINVAL;; ++ ++ addr = args->shadow_stack + args->shadow_stack_size - sizeof(u64); ++ expected = (addr - SS_FRAME_SIZE) | BIT(0); ++ ++ mm = get_task_mm(t); ++ if (!mm) ++ return -EFAULT; + + /* This should really be an atomic cpmxchg. It is not. */ -+ __get_user(val, (__user u64 *)addr); ++ if (access_remote_vm(mm, addr, &val, sizeof(val), ++ FOLL_FORCE) != sizeof(val)) ++ goto out; ++ + if (val != expected) -+ return false; ++ goto out; ++ val = 0; ++ if (access_remote_vm(mm, addr, &val, sizeof(val), ++ FOLL_FORCE | FOLL_WRITE) != sizeof(val)) ++ goto out; + -+ if (write_user_shstk_64((u64 __user *)addr, 0)) -+ return false; ++ ret = 0; + -+ return true; ++out: ++ mmput(mm); ++ return ret; +} + +unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, @@ -420,13 +448,6 @@ index 59e15dd8d0f8..935ced6cf4f5 100644 + if (args->shadow_stack) { + addr = args->shadow_stack; + size = args->shadow_stack_size; -+ -+ /* There should be a valid token at the top of the stack. */ -+ if (!shstk_consume_token(tsk, addr + size - sizeof(u64))) { -+ shstk->base = 0; -+ shstk->size = 0; -+ return (unsigned long)ERR_PTR(-EINVAL); -+ } + } else { + /* + * For CLONE_VFORK the child will share the parents @@ -467,7 +488,7 @@ index 59e15dd8d0f8..935ced6cf4f5 100644 return addr + size; } diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index d362aacf9f89..dd577e8dc881 100644 +index d362aacf9f897..56b2013d7fe5b 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -43,6 +43,8 @@ struct kernel_clone_args { @@ -479,8 +500,24 @@ index d362aacf9f89..dd577e8dc881 100644 }; /* +@@ -230,4 +232,15 @@ static inline void task_unlock(struct task_struct *p) + + DEFINE_GUARD(task_lock, struct task_struct *, task_lock(_T), task_unlock(_T)) + ++#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK ++int arch_shstk_post_fork(struct task_struct *p, ++ struct kernel_clone_args *args); ++#else ++static inline int arch_shstk_post_fork(struct task_struct *p, ++ struct kernel_clone_args *args) ++{ ++ return 0; ++} ++#endif ++ + #endif /* _LINUX_SCHED_TASK_H */ diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h -index 3bac0a8ceab2..8b7af52548fd 100644 +index 3bac0a8ceab26..8b7af52548fd9 100644 --- a/include/uapi/linux/sched.h +++ b/include/uapi/linux/sched.h @@ -84,6 +84,10 @@ @@ -514,10 +551,10 @@ index 3bac0a8ceab2..8b7af52548fd 100644 /* * Scheduling policies diff --git a/kernel/fork.c b/kernel/fork.c -index 0d944e92a43f..fca041cc2b8a 100644 +index 99076dbe27d83..d7c5769942f85 100644 --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -123,6 +123,11 @@ +@@ -125,6 +125,11 @@ */ #define MAX_THREADS FUTEX_TID_MASK @@ -529,7 +566,36 @@ index 0d944e92a43f..fca041cc2b8a 100644 /* * Protected counters by write_lock_irq(&tasklist_lock) */ -@@ -3062,7 +3067,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, +@@ -2745,6 +2750,19 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) + return copy_process(NULL, 0, node, &args); + } + ++static void shstk_post_fork(struct task_struct *p, ++ struct kernel_clone_args *args) ++{ ++ if (!IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK)) ++ return; ++ ++ if (!args->shadow_stack) ++ return; ++ ++ if (arch_shstk_post_fork(p, args) != 0) ++ force_sig_fault_to_task(SIGSEGV, SEGV_CPERR, NULL, p); ++} ++ + /* + * Ok, this is the main fork-routine. + * +@@ -2806,6 +2824,8 @@ pid_t kernel_clone(struct kernel_clone_args *args) + */ + trace_sched_process_fork(current, p); + ++ shstk_post_fork(p, args); ++ + pid = get_task_pid(p, PIDTYPE_PID); + nr = pid_vnr(pid); + +@@ -2957,7 +2977,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, CLONE_ARGS_SIZE_VER1); BUILD_BUG_ON(offsetofend(struct clone_args, cgroup) != CLONE_ARGS_SIZE_VER2); @@ -540,7 +606,7 @@ index 0d944e92a43f..fca041cc2b8a 100644 if (unlikely(usize > PAGE_SIZE)) return -E2BIG; -@@ -3095,16 +3102,18 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, +@@ -2990,16 +3012,18 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, return -EINVAL; *kargs = (struct kernel_clone_args){ @@ -569,7 +635,7 @@ index 0d944e92a43f..fca041cc2b8a 100644 }; if (args.set_tid && -@@ -3145,6 +3154,34 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs) +@@ -3040,6 +3064,34 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs) return true; } @@ -604,7 +670,7 @@ index 0d944e92a43f..fca041cc2b8a 100644 static bool clone3_args_valid(struct kernel_clone_args *kargs) { /* Verify that no unknown flags are passed along. */ -@@ -3167,7 +3204,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs) +@@ -3062,7 +3114,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs) kargs->exit_signal) return false; @@ -617,10 +683,44 @@ index 0d944e92a43f..fca041cc2b8a 100644 2.34.1 -From 3f6f2af71e1803c3e2d48f08c3f364efdaec5fcd Mon Sep 17 00:00:00 2001 +From 061afbd50f75fc0792528ff54dd1a8cfc9d3396b Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Wed, 19 Jun 2024 18:18:12 +0100 +Subject: [PATCH 06/50] selftests/clone3: Remove redundant flushes of output + streams + +Since there were widespread issues with output not being flushed the +kselftest framework was modified to explicitly set the output streams +unbuffered in commit 58e2847ad2e6 ("selftests: line buffer test +program's stdout") so there is no need to explicitly flush in the clone3 +tests. + +Signed-off-by: Mark Brown +--- + tools/testing/selftests/clone3/clone3_selftests.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h +index 3d2663fe50ba5..39b5dcba663c3 100644 +--- a/tools/testing/selftests/clone3/clone3_selftests.h ++++ b/tools/testing/selftests/clone3/clone3_selftests.h +@@ -35,8 +35,6 @@ struct __clone_args { + + static pid_t sys_clone3(struct __clone_args *args, size_t size) + { +- fflush(stdout); +- fflush(stderr); + return syscall(__NR_clone3, args, size); + } + +-- +2.34.1 + + +From d5c5c6845bfce26673d41141b7b7768858ea4277 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 19 Oct 2023 15:43:49 +0100 -Subject: [PATCH 06/47] selftests/clone3: Factor more of main loop into +Subject: [PATCH 07/50] selftests/clone3: Factor more of main loop into test_clone3() In order to make it easier to add more configuration for the tests and @@ -636,7 +736,7 @@ Signed-off-by: Mark Brown 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c -index 3c9bf0cd82a8..1108bd8e36d6 100644 +index e61f07973ce5e..e066b201fa64e 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -30,6 +30,19 @@ enum test_mode { @@ -659,7 +759,7 @@ index 3c9bf0cd82a8..1108bd8e36d6 100644 static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) { struct __clone_args args = { -@@ -104,30 +117,40 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) +@@ -109,30 +122,40 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) return 0; } @@ -712,7 +812,7 @@ index 3c9bf0cd82a8..1108bd8e36d6 100644 static bool not_root(void) { if (getuid() != 0) { -@@ -155,16 +178,6 @@ static size_t page_size_plus_8(void) +@@ -160,16 +183,6 @@ static size_t page_size_plus_8(void) return getpagesize() + 8; } @@ -729,7 +829,7 @@ index 3c9bf0cd82a8..1108bd8e36d6 100644 static const struct test tests[] = { { .name = "simple clone3()", -@@ -314,24 +327,8 @@ int main(int argc, char *argv[]) +@@ -319,24 +332,8 @@ int main(int argc, char *argv[]) ksft_set_plan(ARRAY_SIZE(tests)); test_clone3_supported(); @@ -760,10 +860,48 @@ index 3c9bf0cd82a8..1108bd8e36d6 100644 2.34.1 -From 19b4898b0f2850497f787d1e5a3d7a6910d3ca57 Mon Sep 17 00:00:00 2001 +From 553a2ad7825eee4d94bbc149bdf4b75ca8eef9bd Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Fri, 21 Jun 2024 01:27:35 +0100 +Subject: [PATCH 08/50] selftests/clone3: Explicitly handle child exits due to + signals + +In order to improve diagnostics and allow tests to explicitly look for +signals check to see if the child exited due to a signal and if it did +print the code and return it as a positive value, distinct from the +negative errnos currently returned. + +Signed-off-by: Mark Brown +--- + tools/testing/selftests/clone3/clone3.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c +index e066b201fa64e..3b3a08e6a34d7 100644 +--- a/tools/testing/selftests/clone3/clone3.c ++++ b/tools/testing/selftests/clone3/clone3.c +@@ -111,6 +111,13 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) + ksft_print_msg("waitpid() returned %s\n", strerror(errno)); + return -errno; + } ++ ++ if (WIFSIGNALED(status)) { ++ ksft_print_msg("Child exited with signal %d\n", ++ WTERMSIG(status)); ++ return WTERMSIG(status); ++ } ++ + if (!WIFEXITED(status)) { + ksft_print_msg("Child did not exit normally, status 0x%x\n", + status); +-- +2.34.1 + + +From 67595ba0fea2a0cbf31f9598015f7947dd4678e2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 19 Oct 2023 16:15:08 +0100 -Subject: [PATCH 07/47] selftests/clone3: Allow tests to flag if -E2BIG is a +Subject: [PATCH 09/50] selftests/clone3: Allow tests to flag if -E2BIG is a valid error code The clone_args structure is extensible, with the syscall passing in the @@ -786,7 +924,7 @@ Signed-off-by: Mark Brown 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c -index 1108bd8e36d6..6adbfd14c841 100644 +index 3b3a08e6a34d7..26221661e9aec 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -39,6 +39,7 @@ struct test { @@ -797,7 +935,7 @@ index 1108bd8e36d6..6adbfd14c841 100644 enum test_mode test_mode; filter_function filter; }; -@@ -141,6 +142,11 @@ static void test_clone3(const struct test *test) +@@ -153,6 +154,11 @@ static void test_clone3(const struct test *test) ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n", getpid(), ret, test->expected); if (ret != test->expected) { @@ -813,14 +951,15 @@ index 1108bd8e36d6..6adbfd14c841 100644 2.34.1 -From 295f1b6a27b9621402b0d3abeb15a3d2c39a7ddb Mon Sep 17 00:00:00 2001 +From 4c8cf8814957090ce50ad18f318f72e6fe0d1a32 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Oct 2023 23:09:49 +0100 -Subject: [PATCH 08/47] selftests/clone3: Test shadow stack support +Subject: [PATCH 10/50] selftests/clone3: Test shadow stack support Add basic test coverage for specifying the shadow stack for a newly created thread via clone3(), including coverage of the newly extended -argument structure. +argument structure. We check that a user specified shadow stack can be +provided, and that invalid combinations of parameters are rejected. In order to facilitate testing on systems without userspace shadow stack support we manually enable shadow stacks on startup, this is architecture @@ -830,14 +969,22 @@ shadow stacks on the running system by attempting to allocate a shadow stack page during initialisation using map_shadow_stack(), warning if this succeeds when the enable failed. +In order to allow testing of user configured shadow stacks on +architectures with that feature we need to ensure that we do not return +from the function where the clone3() syscall is called in the child +process, doing so would trigger a shadow stack underflow. To do this we +use inline assembly rather than the standard syscall wrapper to call +clone3(). In order to avoid surprises we also use a syscall rather than +the libc exit() function., this should be overly cautious. + Signed-off-by: Mark Brown --- - tools/testing/selftests/clone3/clone3.c | 128 ++++++++++++++++++ - .../selftests/clone3/clone3_selftests.h | 8 ++ - 2 files changed, 136 insertions(+) + tools/testing/selftests/clone3/clone3.c | 135 +++++++++++++++++- + .../selftests/clone3/clone3_selftests.h | 38 +++++ + 2 files changed, 172 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c -index 6adbfd14c841..c468d9b87bd5 100644 +index 26221661e9aec..696fbb6f94963 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -3,6 +3,7 @@ @@ -880,10 +1027,11 @@ index 6adbfd14c841..c468d9b87bd5 100644 }; typedef bool (*filter_function)(void); -@@ -44,6 +54,43 @@ struct test { +@@ -44,6 +54,44 @@ struct test { filter_function filter; }; ++ +/* + * We check for shadow stack support by attempting to use + * map_shadow_stack() since features may have been locked by the @@ -892,7 +1040,7 @@ index 6adbfd14c841..c468d9b87bd5 100644 + */ +static void test_shadow_stack_supported(void) +{ -+ long ret; ++ long ret; + + ret = syscall(__NR_map_shadow_stack, 0, getpagesize(), 0); + if (ret == -1) { @@ -924,11 +1072,12 @@ index 6adbfd14c841..c468d9b87bd5 100644 static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) { struct __clone_args args = { -@@ -89,6 +136,20 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) +@@ -89,6 +137,21 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) case CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG: args.exit_signal = 0x00000000000000f0ULL; break; + case CLONE3_ARGS_SHADOW_STACK: ++ /* We need to specify a normal stack too to avoid corruption */ + args.shadow_stack = get_shadow_stack_page(SHADOW_STACK_SET_TOKEN); + args.shadow_stack_size = getpagesize(); + break; @@ -945,7 +1094,29 @@ index 6adbfd14c841..c468d9b87bd5 100644 } memcpy(&args_ext.args, &args, sizeof(struct __clone_args)); -@@ -179,6 +240,26 @@ static bool no_timenamespace(void) +@@ -102,7 +165,12 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) + + if (pid == 0) { + ksft_print_msg("I am the child, my PID is %d\n", getpid()); +- _exit(EXIT_SUCCESS); ++ /* ++ * Use a raw syscall to ensure we don't get issues ++ * with manually specified shadow stack and exit handlers. ++ */ ++ syscall(__NR_exit, EXIT_SUCCESS); ++ ksft_print_msg("CHILD FAILED TO EXIT PID is %d\n", getpid()); + } + + ksft_print_msg("I am the parent (%d). My child's pid is %d\n", +@@ -112,6 +180,7 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) + ksft_print_msg("waitpid() returned %s\n", strerror(errno)); + return -errno; + } ++ ksft_print_msg("WAITED\n"); + + if (WIFSIGNALED(status)) { + ksft_print_msg("Child exited with signal %d\n", +@@ -191,6 +260,26 @@ static bool no_timenamespace(void) return true; } @@ -972,13 +1143,12 @@ index 6adbfd14c841..c468d9b87bd5 100644 static size_t page_size_plus_8(void) { return getpagesize() + 8; -@@ -322,6 +403,50 @@ static const struct test tests[] = { +@@ -334,6 +423,47 @@ static const struct test tests[] = { .expected = -EINVAL, .test_mode = CLONE3_ARGS_NO_TEST, }, + { + .name = "Shadow stack on system with shadow stack", -+ .flags = CLONE_VM, + .size = 0, + .expected = 0, + .e2big_valid = true, @@ -987,7 +1157,6 @@ index 6adbfd14c841..c468d9b87bd5 100644 + }, + { + .name = "Shadow stack with no pointer", -+ .flags = CLONE_VM, + .size = 0, + .expected = -EINVAL, + .e2big_valid = true, @@ -995,7 +1164,6 @@ index 6adbfd14c841..c468d9b87bd5 100644 + }, + { + .name = "Shadow stack with no size", -+ .flags = CLONE_VM, + .size = 0, + .expected = -EINVAL, + .e2big_valid = true, @@ -1006,7 +1174,7 @@ index 6adbfd14c841..c468d9b87bd5 100644 + .name = "Shadow stack with no token", + .flags = CLONE_VM, + .size = 0, -+ .expected = -EINVAL, ++ .expected = SIGSEGV, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK_NO_TOKEN, + .filter = no_shadow_stack, @@ -1023,7 +1191,7 @@ index 6adbfd14c841..c468d9b87bd5 100644 }; int main(int argc, char *argv[]) -@@ -329,9 +454,12 @@ int main(int argc, char *argv[]) +@@ -341,9 +471,12 @@ int main(int argc, char *argv[]) size_t size; int i; @@ -1037,10 +1205,10 @@ index 6adbfd14c841..c468d9b87bd5 100644 for (i = 0; i < ARRAY_SIZE(tests); i++) test_clone3(&tests[i]); diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h -index 3d2663fe50ba..1011dae85098 100644 +index 39b5dcba663c3..38d82934668a8 100644 --- a/tools/testing/selftests/clone3/clone3_selftests.h +++ b/tools/testing/selftests/clone3/clone3_selftests.h -@@ -31,6 +31,14 @@ struct __clone_args { +@@ -31,12 +31,50 @@ struct __clone_args { __aligned_u64 set_tid; __aligned_u64 set_tid_size; __aligned_u64 cgroup; @@ -1054,15 +1222,51 @@ index 3d2663fe50ba..1011dae85098 100644 +#endif }; ++/* ++ * For architectures with shadow stack support we need to be ++ * absolutely sure that the clone3() syscall will be inline and not a ++ * function call so we open code. ++ */ ++#ifdef __x86_64__ ++static pid_t __always_inline sys_clone3(struct __clone_args *args, size_t size) ++{ ++ long ret; ++ register long _num __asm__ ("rax") = __NR_clone3; ++ register long _args __asm__ ("rdi") = (long)(args); ++ register long _size __asm__ ("rsi") = (long)(size); ++ ++ __asm__ volatile ( ++ "syscall\n" ++ : "=a"(ret) ++ : "r"(_args), "r"(_size), ++ "0"(_num) ++ : "rcx", "r11", "memory", "cc" ++ ); ++ ++ if (ret < 0) { ++ errno = -ret; ++ return -1; ++ } ++ ++ return ret; ++} ++#else static pid_t sys_clone3(struct __clone_args *args, size_t size) + { + return syscall(__NR_clone3, args, size); + } ++#endif + + static inline void test_clone3_supported(void) + { -- 2.34.1 -From e6c930b757134d3ad80f5b1a04ddba670b212abb Mon Sep 17 00:00:00 2001 +From a872040cac3fdcd2d39b6bcdf39a3090c4162d88 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Aug 2023 17:33:47 +0100 -Subject: [PATCH 10/47] arm64/mm: Restructure arch_validate_flags() for +Subject: [PATCH 12/50] arm64/mm: Restructure arch_validate_flags() for extensibility Currently arch_validate_flags() is written in a very non-extensible @@ -1078,7 +1282,7 @@ Signed-off-by: Mark Brown 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h -index 5966ee4a6154..c21849ffdd88 100644 +index 5966ee4a61542..c21849ffdd88c 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -52,11 +52,17 @@ static inline bool arch_validate_prot(unsigned long prot, @@ -1107,10 +1311,10 @@ index 5966ee4a6154..c21849ffdd88 100644 2.34.1 -From 33a83dfb0883de5bb5e1577423a213193aff4677 Mon Sep 17 00:00:00 2001 +From 66bdc8c5b63b58092141260d4454dadfacb839f6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 12 Feb 2023 20:53:44 -0800 -Subject: [PATCH 11/47] prctl: arch-agnostic prctl for shadow stack +Subject: [PATCH 13/50] prctl: arch-agnostic prctl for shadow stack Three architectures (x86, aarch64, riscv) have announced support for shadow stacks with fairly similar functionality. While x86 is using @@ -1147,12 +1351,12 @@ Signed-off-by: Mark Brown 3 files changed, 56 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h -index c0a782eda803..0b1139c5df60 100644 +index 5ec7bc3556578..120abcfaf974a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -4182,4 +4182,8 @@ static inline bool pfn_is_unaccepted_memory(unsigned long pfn) - return range_contains_unaccepted_memory(paddr, paddr + PAGE_SIZE); - } +@@ -4263,4 +4263,8 @@ static inline bool pfn_is_unaccepted_memory(unsigned long pfn) + void vma_pgtable_walk_begin(struct vm_area_struct *vma); + void vma_pgtable_walk_end(struct vm_area_struct *vma); +int arch_get_shadow_stack_status(struct task_struct *t, unsigned long __user *status); +int arch_set_shadow_stack_status(struct task_struct *t, unsigned long status); @@ -1160,24 +1364,24 @@ index c0a782eda803..0b1139c5df60 100644 + #endif /* _LINUX_MM_H */ diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h -index 370ed14b1ae0..3c66ed8f46d8 100644 +index 35791791a879b..557a3d2ac1d48 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h -@@ -306,4 +306,26 @@ struct prctl_mm_map { - # define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc - # define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f +@@ -328,4 +328,26 @@ struct prctl_mm_map { + # define PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC 0x10 /* Clear the aspect on exec */ + # define PR_PPC_DEXCR_CTRL_MASK 0x1f +/* + * Get the current shadow stack configuration for the current thread, + * this will be the value configured via PR_SET_SHADOW_STACK_STATUS. + */ -+#define PR_GET_SHADOW_STACK_STATUS 71 ++#define PR_GET_SHADOW_STACK_STATUS 74 + +/* + * Set the current shadow stack configuration. Enabling the shadow + * stack will cause a shadow stack to be allocated for the thread. + */ -+#define PR_SET_SHADOW_STACK_STATUS 72 ++#define PR_SET_SHADOW_STACK_STATUS 75 +# define PR_SHADOW_STACK_ENABLE (1UL << 0) +# define PR_SHADOW_STACK_WRITE (1UL << 1) +# define PR_SHADOW_STACK_PUSH (1UL << 2) @@ -1187,14 +1391,14 @@ index 370ed14b1ae0..3c66ed8f46d8 100644 + * configuration. All bits may be locked via this call, including + * undefined bits. + */ -+#define PR_LOCK_SHADOW_STACK_STATUS 73 ++#define PR_LOCK_SHADOW_STACK_STATUS 76 + #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/sys.c b/kernel/sys.c -index f8e543f1e38a..242e9f147791 100644 +index 3a2df1bd9f640..7e0c10e867cf5 100644 --- a/kernel/sys.c +++ b/kernel/sys.c -@@ -2315,6 +2315,21 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, +@@ -2324,6 +2324,21 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, return -EINVAL; } @@ -1216,9 +1420,9 @@ index f8e543f1e38a..242e9f147791 100644 #define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE) #ifdef CONFIG_ANON_VMA_NAME -@@ -2757,6 +2772,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, - case PR_RISCV_V_GET_CONTROL: - error = RISCV_V_GET_CONTROL(); +@@ -2782,6 +2797,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + case PR_RISCV_SET_ICACHE_FLUSH_CTX: + error = RISCV_SET_ICACHE_FLUSH_CTX(arg2, arg3); break; + case PR_GET_SHADOW_STACK_STATUS: + if (arg3 || arg4 || arg5) @@ -1242,10 +1446,10 @@ index f8e543f1e38a..242e9f147791 100644 2.34.1 -From d16e43b333735c0ce01575c280197da1989e9739 Mon Sep 17 00:00:00 2001 +From b999f727c6252e72559cce536ee465b264e51ab4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Aug 2023 14:50:18 +0100 -Subject: [PATCH 12/47] mman: Add map_shadow_stack() flags +Subject: [PATCH 14/50] mman: Add map_shadow_stack() flags In preparation for adding arm64 GCS support make the map_shadow_stack() SHADOW_STACK_SET_TOKEN flag generic and add _SET_MARKER. The existing @@ -1264,7 +1468,7 @@ Signed-off-by: Mark Brown 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h -index 46cdc941f958..ac1e6277212b 100644 +index 46cdc941f9586..ac1e6277212b9 100644 --- a/arch/x86/include/uapi/asm/mman.h +++ b/arch/x86/include/uapi/asm/mman.h @@ -5,9 +5,6 @@ @@ -1278,7 +1482,7 @@ index 46cdc941f958..ac1e6277212b 100644 #endif /* _ASM_X86_MMAN_H */ diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h -index 57e8195d0b53..d6a282687af5 100644 +index 57e8195d0b538..d6a282687af51 100644 --- a/include/uapi/asm-generic/mman.h +++ b/include/uapi/asm-generic/mman.h @@ -19,4 +19,8 @@ @@ -1294,10 +1498,10 @@ index 57e8195d0b53..d6a282687af5 100644 2.34.1 -From ff25ae9e38129288ebbeabf5a53360a074157b0a Mon Sep 17 00:00:00 2001 +From f52fed1e45fc1eedb78305f38b74cc54b36fc91f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Mar 2023 17:16:43 +0000 -Subject: [PATCH 13/47] arm64: Document boot requirements for Guarded Control +Subject: [PATCH 15/50] arm64: Document boot requirements for Guarded Control Stacks FEAT_GCS introduces a number of new system registers, we require that @@ -1311,7 +1515,7 @@ Signed-off-by: Mark Brown 1 file changed, 22 insertions(+) diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm64/booting.rst -index b57776a68f15..de3679770c64 100644 +index b57776a68f156..de3679770c645 100644 --- a/Documentation/arch/arm64/booting.rst +++ b/Documentation/arch/arm64/booting.rst @@ -411,6 +411,28 @@ Before jumping into the kernel, the following conditions must be met: @@ -1347,10 +1551,10 @@ index b57776a68f15..de3679770c64 100644 2.34.1 -From 5867bb3606500d88935829c424bcbd0c1afe0277 Mon Sep 17 00:00:00 2001 +From 39d2bab06fb1b6e21ba896425f3c5bda455f4e5d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 4 Jul 2023 00:17:55 +0100 -Subject: [PATCH 14/47] arm64/gcs: Document the ABI for Guarded Control Stacks +Subject: [PATCH 16/50] arm64/gcs: Document the ABI for Guarded Control Stacks Add some documentation of the userspace ABI for Guarded Control Stacks. @@ -1364,7 +1568,7 @@ Signed-off-by: Mark Brown diff --git a/Documentation/arch/arm64/gcs.rst b/Documentation/arch/arm64/gcs.rst new file mode 100644 -index 000000000000..c45c0326836a +index 0000000000000..c45c0326836a4 --- /dev/null +++ b/Documentation/arch/arm64/gcs.rst @@ -0,0 +1,233 @@ @@ -1602,7 +1806,7 @@ index 000000000000..c45c0326836a +* Guarded Control Stack pages will include "ss" in their VmFlags in + /proc//smaps. diff --git a/Documentation/arch/arm64/index.rst b/Documentation/arch/arm64/index.rst -index d08e924204bf..dcf3ee3eb8c0 100644 +index d08e924204bf1..dcf3ee3eb8c08 100644 --- a/Documentation/arch/arm64/index.rst +++ b/Documentation/arch/arm64/index.rst @@ -14,6 +14,7 @@ ARM64 Architecture @@ -1617,10 +1821,10 @@ index d08e924204bf..dcf3ee3eb8c0 100644 2.34.1 -From 41a7e3b42b2776185f78b4a23ac7a5d3019eb203 Mon Sep 17 00:00:00 2001 +From 257fd303f69127cf067d922e56997db78e3b131d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 20 Jun 2023 19:28:37 +0100 -Subject: [PATCH 15/47] arm64/sysreg: Add definitions for architected GCS caps +Subject: [PATCH 17/50] arm64/sysreg: Add definitions for architected GCS caps The architecture defines a format for guarded control stack caps, used to mark the top of an unused GCS in order to limit the potential for @@ -1633,7 +1837,7 @@ Signed-off-by: Mark Brown 1 file changed, 20 insertions(+) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h -index c3b19b376c86..6ed813e856c1 100644 +index af3b206fa4239..325a1daa98ed8 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1064,6 +1064,26 @@ @@ -1667,10 +1871,10 @@ index c3b19b376c86..6ed813e856c1 100644 2.34.1 -From 0c5c6e7f9c231a904a1d04ea1d1a9b1729544fe3 Mon Sep 17 00:00:00 2001 +From 2f8a10699e2a674df32ce70ecf43afdfa28c9527 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 20 Jun 2023 19:31:24 +0100 -Subject: [PATCH 16/47] arm64/gcs: Add manual encodings of GCS instructions +Subject: [PATCH 18/50] arm64/gcs: Add manual encodings of GCS instructions Define C callable functions for GCS instructions used by the kernel. In order to avoid ambitious toolchain requirements for GCS support these are @@ -1690,7 +1894,7 @@ Signed-off-by: Mark Brown diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h new file mode 100644 -index 000000000000..7c5e95218db6 +index 0000000000000..7c5e95218db6b --- /dev/null +++ b/arch/arm64/include/asm/gcs.h @@ -0,0 +1,51 @@ @@ -1746,7 +1950,7 @@ index 000000000000..7c5e95218db6 + +#endif diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h -index 14be5000c5a0..22e10e79f56a 100644 +index 14be5000c5a0c..22e10e79f56ae 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -425,4 +425,26 @@ static inline size_t probe_subpage_writeable(const char __user *uaddr, @@ -1780,10 +1984,10 @@ index 14be5000c5a0..22e10e79f56a 100644 2.34.1 -From d182ff2531f97a9b48dd0a35f8c36a5b2d541d52 Mon Sep 17 00:00:00 2001 +From f0081588cadbd6a4e64c1f64209c29b76586c0ef Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 16 Jul 2023 14:43:47 +0100 -Subject: [PATCH 17/47] arm64/gcs: Provide put_user_gcs() +Subject: [PATCH 19/50] arm64/gcs: Provide put_user_gcs() In order for EL1 to write to an EL0 GCS it must use the GCSSTTR instruction rather than a normal STTR. Provide a put_user_gcs() which does this. @@ -1795,7 +1999,7 @@ Signed-off-by: Mark Brown 1 file changed, 18 insertions(+) diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h -index 22e10e79f56a..e118c3d772c8 100644 +index 22e10e79f56ae..e118c3d772c8d 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -445,6 +445,24 @@ static inline int gcssttr(unsigned long __user *addr, unsigned long val) @@ -1827,10 +2031,10 @@ index 22e10e79f56a..e118c3d772c8 100644 2.34.1 -From 98f4b4d4c95150730f81cff8a1a56cec4d3bd9af Mon Sep 17 00:00:00 2001 +From e149c7101e4fb52b0e365acfc7ee760837d49d46 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Mar 2023 22:35:56 +0000 -Subject: [PATCH 18/47] arm64/cpufeature: Runtime detection of Guarded Control +Subject: [PATCH 20/50] arm64/cpufeature: Runtime detection of Guarded Control Stack (GCS) Add a cpufeature for GCS, allowing other code to conditionally support it @@ -1845,10 +2049,10 @@ Signed-off-by: Mark Brown 3 files changed, 23 insertions(+) diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h -index bd8d4ca81a48..f81a69991394 100644 +index 8b904a757bd34..0ebed5dfe55fc 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h -@@ -825,6 +825,12 @@ static inline bool system_supports_lpa2(void) +@@ -832,6 +832,12 @@ static inline bool system_supports_lpa2(void) return cpus_have_final_cap(ARM64_HAS_LPA2); } @@ -1862,10 +2066,10 @@ index bd8d4ca81a48..f81a69991394 100644 bool try_emulate_mrs(struct pt_regs *regs, u32 isn); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index 8d1a634a403e..b606842ab8c1 100644 +index 48e7029f10548..056d394920f9f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c -@@ -255,6 +255,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { +@@ -291,6 +291,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { }; static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { @@ -1874,7 +2078,7 @@ index 8d1a634a403e..b606842ab8c1 100644 ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME), FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_EL1_SME_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_EL1_MPAM_frac_SHIFT, 4, 0), -@@ -2250,6 +2252,12 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused) +@@ -2347,6 +2349,12 @@ static void cpu_enable_mops(const struct arm64_cpu_capabilities *__unused) sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_MSCEn); } @@ -1887,9 +2091,9 @@ index 8d1a634a403e..b606842ab8c1 100644 /* Internal helper functions to match cpu capability type */ static bool cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap) -@@ -2739,6 +2747,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = { - .type = ARM64_CPUCAP_SYSTEM_FEATURE, - .matches = has_lpa2, +@@ -2869,6 +2877,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = { + .matches = has_nv1, + ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI_NV1) }, + { + .desc = "Guarded Control Stack (GCS)", @@ -1903,11 +2107,11 @@ index 8d1a634a403e..b606842ab8c1 100644 }; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps -index b912b1409fc0..148734504295 100644 +index ac3429d892b9a..66eff95c0824b 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps -@@ -28,6 +28,7 @@ HAS_EPAN - HAS_EVT +@@ -29,6 +29,7 @@ HAS_EVT + HAS_FPMR HAS_FGT HAS_FPSIMD +HAS_GCS @@ -1918,10 +2122,10 @@ index b912b1409fc0..148734504295 100644 2.34.1 -From cfa2c80233b74b7e487afbd8fe4e22cdd7c6bb93 Mon Sep 17 00:00:00 2001 +From 31d2836d393caa031a762a392f70dcb3a9096aab Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 21 Apr 2023 19:37:37 +0100 -Subject: [PATCH 19/47] arm64/mm: Allocate PIE slots for EL0 guarded control +Subject: [PATCH 21/50] arm64/mm: Allocate PIE slots for EL0 guarded control stack Pages used for guarded control stacks need to be described to the hardware @@ -1941,10 +2145,10 @@ Signed-off-by: Mark Brown 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h -index 483dbfa39c4c..14a33e0bece3 100644 +index b11cfb9fdd379..545d54c885203 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h -@@ -129,15 +129,23 @@ extern bool arm64_use_ng_mappings; +@@ -144,15 +144,23 @@ static inline bool __pure lpa2_is_enabled(void) /* 6: PTE_PXN | PTE_WRITE */ /* 7: PAGE_SHARED_EXEC PTE_PXN | PTE_WRITE | PTE_USER */ /* 8: PAGE_KERNEL_ROX PTE_UXN */ @@ -1970,7 +2174,7 @@ index 483dbfa39c4c..14a33e0bece3 100644 PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_X_O) | \ PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX) | \ PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RWX) | \ -@@ -145,6 +153,8 @@ extern bool arm64_use_ng_mappings; +@@ -160,6 +168,8 @@ static inline bool __pure lpa2_is_enabled(void) PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW)) #define PIE_E1 ( \ @@ -1983,10 +2187,10 @@ index 483dbfa39c4c..14a33e0bece3 100644 2.34.1 -From d3fb78871759fd9e703384609bf1ccce903bdca2 Mon Sep 17 00:00:00 2001 +From 7dd12e2cb546f804ead1022d46ae6a62d3dc4523 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 14 Apr 2023 20:29:18 +0100 -Subject: [PATCH 20/47] mm: Define VM_SHADOW_STACK for arm64 when we support +Subject: [PATCH 22/50] mm: Define VM_SHADOW_STACK for arm64 when we support GCS Use VM_HIGH_ARCH_5 for guarded control stack pages. @@ -2000,7 +2204,7 @@ Signed-off-by: Mark Brown 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst -index 104c6d047d9b..0392c3b74650 100644 +index 7c3a565ffbef3..105312a0b33dd 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -570,7 +570,7 @@ encoded manner. The codes are the following: @@ -2013,10 +2217,10 @@ index 104c6d047d9b..0392c3b74650 100644 Note that there is no guarantee that every flag and associated mnemonic will diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index ff2c601f7d1c..fb0633d8e309 100644 +index 1b56c10775072..6ef1137bcad82 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c -@@ -702,6 +702,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) +@@ -706,6 +706,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ #ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK [ilog2(VM_SHADOW_STACK)] = "ss", @@ -2027,10 +2231,10 @@ index ff2c601f7d1c..fb0633d8e309 100644 }; size_t i; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 0b1139c5df60..6cc304c90c63 100644 +index 120abcfaf974a..73211cfe7b313 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h -@@ -352,7 +352,17 @@ extern unsigned int kobjsize(const void *objp); +@@ -353,7 +353,17 @@ extern unsigned int kobjsize(const void *objp); * for more details on the guard size. */ # define VM_SHADOW_STACK VM_HIGH_ARCH_5 @@ -2053,10 +2257,10 @@ index 0b1139c5df60..6cc304c90c63 100644 2.34.1 -From 4eb47474ec4e4776a45110f9e9e853f69492ed3f Mon Sep 17 00:00:00 2001 +From befe6494800c8c67ff50c36f01ab3265ae562f1f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 21 Apr 2023 20:53:01 +0100 -Subject: [PATCH 21/47] arm64/mm: Map pages for guarded control stack +Subject: [PATCH 23/50] arm64/mm: Map pages for guarded control stack Map pages flagged as being part of a GCS as such rather than using the full set of generic VM flags. @@ -2072,7 +2276,7 @@ Signed-off-by: Mark Brown 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h -index c21849ffdd88..6d3fe6433a62 100644 +index c21849ffdd88c..6d3fe6433a627 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -61,6 +61,15 @@ static inline bool arch_validate_flags(unsigned long vm_flags) @@ -2092,10 +2296,10 @@ index c21849ffdd88..6d3fe6433a62 100644 } diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c -index 645fe60d000f..e44ce6fcfad9 100644 +index 642bdf908b22f..68a17bd09d002 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c -@@ -79,9 +79,20 @@ arch_initcall(adjust_protection_map); +@@ -83,9 +83,20 @@ arch_initcall(adjust_protection_map); pgprot_t vm_get_page_prot(unsigned long vm_flags) { @@ -2121,10 +2325,10 @@ index 645fe60d000f..e44ce6fcfad9 100644 2.34.1 -From e505761a54185aa1c4de33454fca255918036af0 Mon Sep 17 00:00:00 2001 +From fb9b5068a4ff18668afb0d7bd0c0ff419f8acc35 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 8 Mar 2023 00:40:28 +0000 -Subject: [PATCH 22/47] KVM: arm64: Manage GCS registers for guests +Subject: [PATCH 24/50] KVM: arm64: Manage GCS registers for guests GCS introduces a number of system registers for EL1 and EL0, on systems with GCS we need to context switch them and expose them to VMMs to allow @@ -2134,32 +2338,41 @@ nested virtualisation. Traps are already disabled. Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- - arch/arm64/include/asm/kvm_host.h | 12 ++++++++++++ - arch/arm64/kvm/emulate-nested.c | 4 ++++ - arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 17 +++++++++++++++++ - arch/arm64/kvm/sys_regs.c | 22 ++++++++++++++++++++++ - 4 files changed, 55 insertions(+) + arch/arm64/include/asm/kvm_host.h | 14 +++++++ + arch/arm64/include/asm/vncr_mapping.h | 2 + + arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 48 +++++++++++++++++----- + arch/arm64/kvm/sys_regs.c | 25 ++++++++++- + 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h -index 21c57b812569..6c7ea7f9cd92 100644 +index 36b8e97bf49ec..316fb412f3554 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h -@@ -388,6 +388,12 @@ enum vcpu_sysreg { +@@ -411,6 +411,10 @@ enum vcpu_sysreg { GCR_EL1, /* Tag Control Register */ TFSRE0_EL1, /* Tag Fault Status Register (EL0) */ + /* Guarded Control Stack registers */ + GCSCRE0_EL1, /* Guarded Control Stack Control (EL0) */ -+ GCSCR_EL1, /* Guarded Control Stack Control (EL1) */ + GCSPR_EL0, /* Guarded Control Stack Pointer (EL0) */ -+ GCSPR_EL1, /* Guarded Control Stack Pointer (EL1) */ + /* 32bit specific registers. */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ -@@ -1221,6 +1227,12 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature) +@@ -481,6 +485,10 @@ enum vcpu_sysreg { + VNCR(PIR_EL1), /* Permission Indirection Register 1 (EL1) */ + VNCR(PIRE0_EL1), /* Permission Indirection Register 0 (EL1) */ - #define vcpu_has_feature(v, f) __vcpu_has_feature(&(v)->kvm->arch, (f)) ++ /* Guarded Control Stack registers */ ++ VNCR(GCSPR_EL1), /* Guarded Control Stack Pointer (EL1) */ ++ VNCR(GCSCR_EL1), /* Guarded Control Stack Control (EL1) */ ++ + VNCR(HFGRTR_EL2), + VNCR(HFGWTR_EL2), + VNCR(HFGITR_EL2), +@@ -1343,6 +1351,12 @@ static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int feature) + + #define kvm_vcpu_initialized(v) vcpu_get_flag(vcpu, VCPU_INITIALIZED) +static inline bool has_gcs(void) +{ @@ -2170,41 +2383,75 @@ index 21c57b812569..6c7ea7f9cd92 100644 int kvm_trng_call(struct kvm_vcpu *vcpu); #ifdef CONFIG_KVM extern phys_addr_t hyp_mem_base; -diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c -index 431fd429932d..24eb7eccbae4 100644 ---- a/arch/arm64/kvm/emulate-nested.c -+++ b/arch/arm64/kvm/emulate-nested.c -@@ -1098,8 +1098,12 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = { - SR_FGT(SYS_ESR_EL1, HFGxTR, ESR_EL1, 1), - SR_FGT(SYS_DCZID_EL0, HFGxTR, DCZID_EL0, 1), - SR_FGT(SYS_CTR_EL0, HFGxTR, CTR_EL0, 1), -+ SR_FGT(SYS_GCSPR_EL0, HFGxTR, nGCS_EL0, 1), - SR_FGT(SYS_CSSELR_EL1, HFGxTR, CSSELR_EL1, 1), - SR_FGT(SYS_CPACR_EL1, HFGxTR, CPACR_EL1, 1), -+ SR_FGT(SYS_GCSCR_EL1, HFGxTR, nGCS_EL1, 1), -+ SR_FGT(SYS_GCSPR_EL1, HFGxTR, nGCS_EL1, 1), -+ SR_FGT(SYS_GCSCRE0_EL1, HFGxTR, nGCS_EL0, 1), - SR_FGT(SYS_CONTEXTIDR_EL1, HFGxTR, CONTEXTIDR_EL1, 1), - SR_FGT(SYS_CLIDR_EL1, HFGxTR, CLIDR_EL1, 1), - SR_FGT(SYS_CCSIDR_EL1, HFGxTR, CCSIDR_EL1, 1), +diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h +index df2c47c559728..5e83e6f579fd6 100644 +--- a/arch/arm64/include/asm/vncr_mapping.h ++++ b/arch/arm64/include/asm/vncr_mapping.h +@@ -88,6 +88,8 @@ + #define VNCR_PMSIRR_EL1 0x840 + #define VNCR_PMSLATFR_EL1 0x848 + #define VNCR_TRFCR_EL1 0x880 ++#define VNCR_GCSPR_EL1 0x8C0 ++#define VNCR_GCSCR_EL1 0x8D0 + #define VNCR_MPAM1_EL1 0x900 + #define VNCR_MPAMHCR_EL2 0x930 + #define VNCR_MPAMVPMV_EL2 0x938 diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h -index bb6b571ec627..ec34d4a90717 100644 +index 4be6a7fa00708..b20212d80e9b6 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h -@@ -25,6 +25,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) +@@ -16,6 +16,27 @@ + #include + #include + ++static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) ++{ ++ struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; ++ ++ if (!vcpu) ++ vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); ++ ++ return vcpu; ++} ++ ++static inline bool ctxt_has_gcs(struct kvm_cpu_context *ctxt) ++{ ++ struct kvm_vcpu *vcpu; ++ ++ if (!cpus_have_final_cap(ARM64_HAS_GCS)) ++ return false; ++ ++ vcpu = ctxt_to_vcpu(ctxt); ++ return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64PFR1_EL1, GCS, IMP); ++} ++ + static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) + { + ctxt_sys_reg(ctxt, MDSCR_EL1) = read_sysreg(mdscr_el1); +@@ -25,16 +46,8 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, TPIDR_EL0) = read_sysreg(tpidr_el0); ctxt_sys_reg(ctxt, TPIDRRO_EL0) = read_sysreg(tpidrro_el0); -+ if (has_gcs()) +-} +- +-static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) +-{ +- struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; +- +- if (!vcpu) +- vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); +- +- return vcpu; ++ if (ctxt_has_gcs(ctxt)) + ctxt_sys_reg(ctxt, GCSPR_EL0) = read_sysreg_s(SYS_GCSPR_EL0); } static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) -@@ -62,6 +64,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) +@@ -80,6 +93,12 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg_par(); ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1); -+ if (has_gcs()) { ++ if (ctxt_has_gcs(ctxt)) { + ctxt_sys_reg(ctxt, GCSPR_EL1) = read_sysreg_el1(SYS_GCSPR); + ctxt_sys_reg(ctxt, GCSCR_EL1) = read_sysreg_el1(SYS_GCSCR); + ctxt_sys_reg(ctxt, GCSCRE0_EL1) = read_sysreg_s(SYS_GCSCRE0_EL1); @@ -2213,20 +2460,20 @@ index bb6b571ec627..ec34d4a90717 100644 if (ctxt_has_mte(ctxt)) { ctxt_sys_reg(ctxt, TFSR_EL1) = read_sysreg_el1(SYS_TFSR); ctxt_sys_reg(ctxt, TFSRE0_EL1) = read_sysreg_s(SYS_TFSRE0_EL1); -@@ -95,6 +103,8 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) +@@ -113,6 +132,8 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) { write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL0), tpidr_el0); write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0), tpidrro_el0); -+ if (has_gcs()) ++ if (ctxt_has_gcs(ctxt)) + write_sysreg_s(ctxt_sys_reg(ctxt, GCSPR_EL0), SYS_GCSPR_EL0); } static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) -@@ -138,6 +148,13 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) +@@ -156,6 +177,13 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1), par_el1); write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1), tpidr_el1); -+ if (has_gcs()) { ++ if (ctxt_has_gcs(ctxt)) { + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1), SYS_GCSPR); + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1), SYS_GCSCR); + write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1), @@ -2237,10 +2484,10 @@ index bb6b571ec627..ec34d4a90717 100644 write_sysreg_el1(ctxt_sys_reg(ctxt, TFSR_EL1), SYS_TFSR); write_sysreg_s(ctxt_sys_reg(ctxt, TFSRE0_EL1), SYS_TFSRE0_EL1); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c -index 30253bd19917..83ba767e75d2 100644 +index 22b45a15d0688..cf068dcfbd494 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c -@@ -2000,6 +2000,23 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, +@@ -2015,6 +2015,23 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, .visibility = mte_visibility, \ } @@ -2264,7 +2511,17 @@ index 30253bd19917..83ba767e75d2 100644 static unsigned int el2_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { -@@ -2376,6 +2393,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { +@@ -2306,7 +2323,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { + ID_AA64PFR0_EL1_GIC | + ID_AA64PFR0_EL1_AdvSIMD | + ID_AA64PFR0_EL1_FP), }, +- ID_SANITISED(ID_AA64PFR1_EL1), ++ ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_RES0 | ++ ID_AA64PFR1_EL1_BT)), + ID_UNALLOCATED(4,2), + ID_UNALLOCATED(4,3), + ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), +@@ -2390,6 +2408,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { PTRAUTH_KEY(APDB), PTRAUTH_KEY(APGA), @@ -2275,7 +2532,7 @@ index 30253bd19917..83ba767e75d2 100644 { SYS_DESC(SYS_SPSR_EL1), access_spsr}, { SYS_DESC(SYS_ELR_EL1), access_elr}, -@@ -2462,6 +2483,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { +@@ -2476,6 +2498,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_SMIDR_EL1), undef_access }, { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, { SYS_DESC(SYS_CTR_EL0), access_ctr }, @@ -2287,10 +2544,10 @@ index 30253bd19917..83ba767e75d2 100644 2.34.1 -From 371653e2b075a2b4c3f2549d02366d4c168c29c6 Mon Sep 17 00:00:00 2001 +From 4d20a635efb93819c99ab92797445c26defb7411 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 15 Mar 2023 18:48:06 +0000 -Subject: [PATCH 23/47] arm64/gcs: Allow GCS usage at EL0 and EL1 +Subject: [PATCH 25/50] arm64/gcs: Allow GCS usage at EL0 and EL1 There is a control HCRX_EL2.GCSEn which must be set to allow GCS features to take effect at lower ELs and also fine grained traps for GCS @@ -2301,11 +2558,10 @@ Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- arch/arm64/include/asm/el2_setup.h | 17 +++++++++++++++++ - arch/arm64/include/asm/kvm_arm.h | 4 ++-- - 2 files changed, 19 insertions(+), 2 deletions(-) + 1 file changed, 17 insertions(+) diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h -index b7afaa026842..17672563e333 100644 +index fd87c4b8f9840..36aa40c19e85e 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -27,6 +27,14 @@ @@ -2323,7 +2579,7 @@ index b7afaa026842..17672563e333 100644 msr_s SYS_HCRX_EL2, x0 .Lskip_hcrx_\@: .endm -@@ -190,6 +198,15 @@ +@@ -191,6 +199,15 @@ orr x0, x0, #HFGxTR_EL2_nPIR_EL1 orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1 @@ -2339,30 +2595,14 @@ index b7afaa026842..17672563e333 100644 .Lset_fgt_\@: msr_s SYS_HFGRTR_EL2, x0 msr_s SYS_HFGWTR_EL2, x0 -diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h -index 3c6f8ba1e479..a9354c237a97 100644 ---- a/arch/arm64/include/asm/kvm_arm.h -+++ b/arch/arm64/include/asm/kvm_arm.h -@@ -103,9 +103,9 @@ - #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) - - #define HCRX_GUEST_FLAGS \ -- (HCRX_EL2_SMPME | HCRX_EL2_TCR2En | \ -+ (HCRX_EL2_SMPME | HCRX_EL2_TCR2En | HCRX_EL2_GCSEn |\ - (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0)) --#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En) -+#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_GCSEn) - - /* TCR_EL2 Registers bits */ - #define TCR_EL2_DS (1UL << 32) -- 2.34.1 -From d50f122180261521787ac2a91c705554eea2e77a Mon Sep 17 00:00:00 2001 +From 9fbe5600495fa7acfe41e0bb9586f5102f6bf36b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 15 Mar 2023 18:52:09 +0000 -Subject: [PATCH 24/47] arm64/idreg: Add overrride for GCS +Subject: [PATCH 26/50] arm64/idreg: Add overrride for GCS Hook up an override for GCS, allowing it to be disabled from the command line by specifying arm64.nogcs in case there are problems. @@ -2371,14 +2611,14 @@ Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- Documentation/admin-guide/kernel-parameters.txt | 6 ++++++ - arch/arm64/kernel/idreg-override.c | 2 ++ + arch/arm64/kernel/pi/idreg-override.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 31b3a25680d0..e86160251d23 100644 +index b600df82669db..c1151d547b812 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -429,9 +429,15 @@ +@@ -437,9 +437,15 @@ arm64.nobti [ARM64] Unconditionally disable Branch Target Identification support @@ -2394,11 +2634,11 @@ index 31b3a25680d0..e86160251d23 100644 arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension support -diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c -index e30fd9e32ef3..00bcdad53ba9 100644 ---- a/arch/arm64/kernel/idreg-override.c -+++ b/arch/arm64/kernel/idreg-override.c -@@ -110,6 +110,7 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = { +diff --git a/arch/arm64/kernel/pi/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c +index 29d4b6244a6f6..2bb709d784051 100644 +--- a/arch/arm64/kernel/pi/idreg-override.c ++++ b/arch/arm64/kernel/pi/idreg-override.c +@@ -133,6 +133,7 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = { .override = &id_aa64pfr1_override, .fields = { FIELD("bt", ID_AA64PFR1_EL1_BT_SHIFT, NULL ), @@ -2406,7 +2646,7 @@ index e30fd9e32ef3..00bcdad53ba9 100644 FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT, NULL), FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT, pfr1_sme_filter), {} -@@ -190,6 +191,7 @@ static const struct { +@@ -215,6 +216,7 @@ static const struct { { "arm64.nosve", "id_aa64pfr0.sve=0" }, { "arm64.nosme", "id_aa64pfr1.sme=0" }, { "arm64.nobti", "id_aa64pfr1.bt=0" }, @@ -2418,65 +2658,64 @@ index e30fd9e32ef3..00bcdad53ba9 100644 2.34.1 -From cf891db5ab3aad787c1deff23058d51e24b19ce1 Mon Sep 17 00:00:00 2001 +From c02d741b60e1fa1288ee7e2e89619a64b2bced3c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Mar 2023 18:21:38 +0000 -Subject: [PATCH 25/47] arm64/hwcap: Add hwcap for GCS +Subject: [PATCH 27/50] arm64/hwcap: Add hwcap for GCS Provide a hwcap to enable userspace to detect support for GCS. Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- - Documentation/arch/arm64/elf_hwcaps.rst | 3 +++ + Documentation/arch/arm64/elf_hwcaps.rst | 2 ++ arch/arm64/include/asm/hwcap.h | 1 + arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c | 3 +++ arch/arm64/kernel/cpuinfo.c | 1 + - 5 files changed, 9 insertions(+) + 5 files changed, 8 insertions(+) diff --git a/Documentation/arch/arm64/elf_hwcaps.rst b/Documentation/arch/arm64/elf_hwcaps.rst -index ced7b335e2e0..86d4ace9c75c 100644 +index 448c1664879bc..cf87be078f33c 100644 --- a/Documentation/arch/arm64/elf_hwcaps.rst +++ b/Documentation/arch/arm64/elf_hwcaps.rst -@@ -317,6 +317,9 @@ HWCAP2_LRCPC3 - HWCAP2_LSE128 - Functionality implied by ID_AA64ISAR0_EL1.Atomic == 0b0011. +@@ -365,6 +365,8 @@ HWCAP2_SME_SF8DP2 + HWCAP2_SME_SF8DP4 + Functionality implied by ID_AA64SMFR0_EL1.SF8DP4 == 0b1. +HWCAP2_GCS + Functionality implied by ID_AA64PFR1_EL1.GCS == 0b1 -+ + 4. Unused AT_HWCAP bits ----------------------- - diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h -index cd71e09ea14d..e01e6b72a839 100644 +index 4edd3b61df112..fd7e162e7e393 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h -@@ -142,6 +142,7 @@ - #define KERNEL_HWCAP_SVE_B16B16 __khwcap2_feature(SVE_B16B16) - #define KERNEL_HWCAP_LRCPC3 __khwcap2_feature(LRCPC3) - #define KERNEL_HWCAP_LSE128 __khwcap2_feature(LSE128) +@@ -157,6 +157,7 @@ + #define KERNEL_HWCAP_SME_SF8FMA __khwcap2_feature(SME_SF8FMA) + #define KERNEL_HWCAP_SME_SF8DP4 __khwcap2_feature(SME_SF8DP4) + #define KERNEL_HWCAP_SME_SF8DP2 __khwcap2_feature(SME_SF8DP2) +#define KERNEL_HWCAP_GCS __khwcap2_feature(GCS) /* * This yields a mask that user programs can use to figure out what diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h -index 5023599fa278..996b5b5d4c4e 100644 +index 285610e626f5f..328fb7843e2ff 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h -@@ -107,5 +107,6 @@ - #define HWCAP2_SVE_B16B16 (1UL << 45) - #define HWCAP2_LRCPC3 (1UL << 46) - #define HWCAP2_LSE128 (1UL << 47) -+#define HWCAP2_GCS (1UL << 48) +@@ -122,5 +122,6 @@ + #define HWCAP2_SME_SF8FMA (1UL << 60) + #define HWCAP2_SME_SF8DP4 (1UL << 61) + #define HWCAP2_SME_SF8DP2 (1UL << 62) ++#define HWCAP2_GCS (1UL << 63) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index b606842ab8c1..1a92c4502a0b 100644 +index 056d394920f9f..d2d9b0be9c5b8 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c -@@ -2867,6 +2867,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { +@@ -3000,6 +3000,9 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM), HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM), HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM), @@ -2487,13 +2726,13 @@ index b606842ab8c1..1a92c4502a0b 100644 HWCAP_CAP(ID_AA64PFR1_EL1, SSBS, SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS), #ifdef CONFIG_ARM64_BTI diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c -index 47043c0d95ec..b3ec0b89c9e0 100644 +index 09eeaa24d4560..2f539e3101eee 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c -@@ -128,6 +128,7 @@ static const char *const hwcap_str[] = { - [KERNEL_HWCAP_SVE_B16B16] = "sveb16b16", - [KERNEL_HWCAP_LRCPC3] = "lrcpc3", - [KERNEL_HWCAP_LSE128] = "lse128", +@@ -143,6 +143,7 @@ static const char *const hwcap_str[] = { + [KERNEL_HWCAP_SME_SF8FMA] = "smesf8fma", + [KERNEL_HWCAP_SME_SF8DP4] = "smesf8dp4", + [KERNEL_HWCAP_SME_SF8DP2] = "smesf8dp2", + [KERNEL_HWCAP_GCS] = "gcs", }; @@ -2502,10 +2741,10 @@ index 47043c0d95ec..b3ec0b89c9e0 100644 2.34.1 -From bccc68b34269e6ccc69fdbbca6d17131093170f7 Mon Sep 17 00:00:00 2001 +From eb6dab845aa2164ccfdd36aaeaa2fc03b33c0daa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 14 Apr 2023 20:57:45 +0100 -Subject: [PATCH 26/47] arm64/traps: Handle GCS exceptions +Subject: [PATCH 28/50] arm64/traps: Handle GCS exceptions A new exception code is defined for GCS specific faults other than standard load/store faults, for example GCS token validation failures, @@ -2531,7 +2770,7 @@ Signed-off-by: Mark Brown 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h -index 353fe08546cf..20ee9f531864 100644 +index 7abf09df70331..8982b4ab297f0 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -51,7 +51,8 @@ @@ -2544,7 +2783,7 @@ index 353fe08546cf..20ee9f531864 100644 #define ESR_ELx_EC_SERROR (0x2F) #define ESR_ELx_EC_BREAKPT_LOW (0x30) #define ESR_ELx_EC_BREAKPT_CUR (0x31) -@@ -382,6 +383,31 @@ +@@ -376,6 +377,31 @@ #define ESR_ELx_MOPS_ISS_SRCREG(esr) (((esr) & (UL(0x1f) << 5)) >> 5) #define ESR_ELx_MOPS_ISS_SIZEREG(esr) (((esr) & (UL(0x1f) << 0)) >> 0) @@ -2577,7 +2816,7 @@ index 353fe08546cf..20ee9f531864 100644 #include diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h -index ad688e157c9b..99caff458e20 100644 +index f296662590c7f..674518464718f 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -57,6 +57,8 @@ void do_el0_undef(struct pt_regs *regs, unsigned long esr); @@ -2590,10 +2829,10 @@ index ad688e157c9b..99caff458e20 100644 struct pt_regs *regs); void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs); diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c -index 0fc94207e69a..52d78ce63a4e 100644 +index b77a15955f28b..54f2d16d82f41 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c -@@ -429,6 +429,15 @@ static void noinstr el1_bti(struct pt_regs *regs, unsigned long esr) +@@ -463,6 +463,15 @@ static void noinstr el1_bti(struct pt_regs *regs, unsigned long esr) exit_to_kernel_mode(regs); } @@ -2609,7 +2848,7 @@ index 0fc94207e69a..52d78ce63a4e 100644 static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr) { unsigned long far = read_sysreg(far_el1); -@@ -471,6 +480,9 @@ asmlinkage void noinstr el1h_64_sync_handler(struct pt_regs *regs) +@@ -505,6 +514,9 @@ asmlinkage void noinstr el1h_64_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_BTI: el1_bti(regs, esr); break; @@ -2619,7 +2858,7 @@ index 0fc94207e69a..52d78ce63a4e 100644 case ESR_ELx_EC_BREAKPT_CUR: case ESR_ELx_EC_SOFTSTP_CUR: case ESR_ELx_EC_WATCHPT_CUR: -@@ -650,6 +662,14 @@ static void noinstr el0_mops(struct pt_regs *regs, unsigned long esr) +@@ -684,6 +696,14 @@ static void noinstr el0_mops(struct pt_regs *regs, unsigned long esr) exit_to_user_mode(regs); } @@ -2634,7 +2873,7 @@ index 0fc94207e69a..52d78ce63a4e 100644 static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr) { enter_from_user_mode(regs); -@@ -732,6 +752,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs) +@@ -766,6 +786,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_MOPS: el0_mops(regs, esr); break; @@ -2645,7 +2884,7 @@ index 0fc94207e69a..52d78ce63a4e 100644 case ESR_ELx_EC_SOFTSTP_LOW: case ESR_ELx_EC_WATCHPT_LOW: diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c -index 215e6d7f2df8..fb867c6526a6 100644 +index 215e6d7f2df8c..fb867c6526a65 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -500,6 +500,16 @@ void do_el1_bti(struct pt_regs *regs, unsigned long esr) @@ -2677,10 +2916,10 @@ index 215e6d7f2df8..fb867c6526a6 100644 2.34.1 -From a44e4f0ea5726b528c7247c2331301e95de6acea Mon Sep 17 00:00:00 2001 +From 8f813d26be798d51a787d246c94da595c12361f3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Apr 2023 13:59:24 +0100 -Subject: [PATCH 27/47] arm64/mm: Handle GCS data aborts +Subject: [PATCH 29/50] arm64/mm: Handle GCS data aborts All GCS operations at EL0 must happen on a page which is marked as having UnprivGCS access, including read operations. If a GCS operation @@ -2705,29 +2944,19 @@ We also report any GCS faults in VMAs not marked as part of a GCS as access violations, causing a fault to be delivered to userspace if it attempts to do GCS operations outside a GCS. -Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- - arch/arm64/mm/fault.c | 76 ++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 68 insertions(+), 8 deletions(-) + arch/arm64/mm/fault.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c -index 55f6455a8284..c2a36102e143 100644 +index 451ba7cbd5adb..bdc28588163dd 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c -@@ -494,13 +494,30 @@ static void do_bad_area(unsigned long far, unsigned long esr, +@@ -486,6 +486,14 @@ static void do_bad_area(unsigned long far, unsigned long esr, } } -+/* -+ * Note: not valid for EL1 DC IVAC, but we never use that such that it -+ * should fault. EL0 cannot issue DC IVAC (undef). -+ */ -+static bool is_write_abort(unsigned long esr) -+{ -+ return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM); -+} -+ +static bool is_gcs_fault(unsigned long esr) +{ + if (!esr_is_data_abort(esr)) @@ -2736,56 +2965,15 @@ index 55f6455a8284..c2a36102e143 100644 + return ESR_ELx_ISS2(esr) & ESR_ELx_GCS; +} + - #define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000) - #define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000) - - static vm_fault_t __do_page_fault(struct mm_struct *mm, - struct vm_area_struct *vma, unsigned long addr, - unsigned int mm_flags, unsigned long vm_flags, -- struct pt_regs *regs) -+ unsigned long esr, struct pt_regs *regs) + static bool is_el0_instruction_abort(unsigned long esr) { - /* - * Ok, we have a good vm_area for this memory access, so we can handle -@@ -510,6 +527,26 @@ static vm_fault_t __do_page_fault(struct mm_struct *mm, - */ - if (!(vma->vm_flags & vm_flags)) - return VM_FAULT_BADACCESS; -+ -+ if (vma->vm_flags & VM_SHADOW_STACK) { -+ /* -+ * Writes to a GCS must either be generated by a GCS -+ * operation or be from EL1. -+ */ -+ if (is_write_abort(esr) && -+ !(is_gcs_fault(esr) || is_el1_data_abort(esr))) -+ return VM_FAULT_BADACCESS; -+ } else { -+ /* -+ * GCS faults should never happen for pages that are -+ * not part of a GCS and the operation being attempted -+ * can never succeed. -+ */ -+ if (is_gcs_fault(esr)) -+ return VM_FAULT_BADACCESS; -+ } -+ -+ - return handle_mm_fault(vma, addr, mm_flags, regs); - } - -@@ -518,13 +555,23 @@ static bool is_el0_instruction_abort(unsigned long esr) return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW; +@@ -500,6 +508,25 @@ static bool is_write_abort(unsigned long esr) + return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM); } --/* -- * Note: not valid for EL1 DC IVAC, but we never use that such that it -- * should fault. EL0 cannot issue DC IVAC (undef). -- */ --static bool is_write_abort(unsigned long esr) +static bool is_invalid_gcs_access(struct vm_area_struct *vma, u64 esr) - { -- return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM); ++{ + if (!system_supports_gcs()) + return false; + @@ -2801,10 +2989,12 @@ index 55f6455a8284..c2a36102e143 100644 + } + + return false; - } - ++} ++ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, -@@ -561,6 +608,14 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, + struct pt_regs *regs) + { +@@ -535,6 +562,14 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, /* It was exec fault */ vm_flags = VM_EXEC; mm_flags |= FAULT_FLAG_INSTRUCTION; @@ -2819,35 +3009,29 @@ index 55f6455a8284..c2a36102e143 100644 } else if (is_write_abort(esr)) { /* It was write fault */ vm_flags = VM_WRITE; -@@ -594,6 +649,11 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, +@@ -568,6 +603,14 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, if (!vma) goto lock_mmap; + if (is_invalid_gcs_access(vma, esr)) { ++ pr_crit("INVALID GCS\n"); + vma_end_read(vma); -+ goto lock_mmap; ++ fault = 0; ++ si_code = SEGV_CPERR; ++ goto bad_area; + } + if (!(vma->vm_flags & vm_flags)) { vma_end_read(vma); - goto lock_mmap; -@@ -625,7 +685,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, - goto done; - } - -- fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, regs); -+ fault = __do_page_fault(mm, vma, addr, mm_flags, vm_flags, esr, regs); - - /* Quick path to respond to signals */ - if (fault_signal_pending(fault, regs)) { + fault = 0; -- 2.34.1 -From 5fe1e5ee0c88af97929f0a604ac3079542f0aadb Mon Sep 17 00:00:00 2001 +From 9459935e317c9cce98477109a3af40833f631189 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 12 Apr 2023 20:31:01 +0100 -Subject: [PATCH 28/47] arm64/gcs: Context switch GCS state for EL0 +Subject: [PATCH 30/50] arm64/gcs: Context switch GCS state for EL0 There are two registers controlling the GCS state of EL0, GCSPR_EL0 which is the current GCS pointer and GCSCRE0_EL1 which has enable bits for the @@ -2878,7 +3062,7 @@ Signed-off-by: Mark Brown create mode 100644 arch/arm64/mm/gcs.c diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h -index 7c5e95218db6..04594ef59dad 100644 +index 7c5e95218db6b..04594ef59dadd 100644 --- a/arch/arm64/include/asm/gcs.h +++ b/arch/arm64/include/asm/gcs.h @@ -48,4 +48,28 @@ static inline u64 gcsss2(void) @@ -2911,10 +3095,10 @@ index 7c5e95218db6..04594ef59dad 100644 + #endif diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h -index 5b0a04810b23..6fc6dcbd494c 100644 +index f77371232d8c6..c55e3600604a6 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h -@@ -182,6 +182,12 @@ struct thread_struct { +@@ -184,6 +184,12 @@ struct thread_struct { u64 sctlr_user; u64 svcr; u64 tpidr2_el0; @@ -2928,7 +3112,7 @@ index 5b0a04810b23..6fc6dcbd494c 100644 static inline unsigned int thread_get_vl(struct thread_struct *thread, diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c -index 7387b68c745b..fd80b43c2969 100644 +index 4ae31b7af6c31..5f00cb0da9c3c 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -48,6 +48,7 @@ @@ -2972,7 +3156,7 @@ index 7387b68c745b..fd80b43c2969 100644 } void arch_release_task_struct(struct task_struct *tsk) -@@ -474,6 +495,40 @@ static void entry_task_switch(struct task_struct *next) +@@ -471,6 +492,40 @@ static void entry_task_switch(struct task_struct *next) __this_cpu_write(__entry_task, next); } @@ -3013,7 +3197,7 @@ index 7387b68c745b..fd80b43c2969 100644 /* * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. * Ensure access is disabled when switching to a 32bit task, ensure -@@ -533,6 +588,7 @@ struct task_struct *__switch_to(struct task_struct *prev, +@@ -530,6 +585,7 @@ struct task_struct *__switch_to(struct task_struct *prev, ssbs_thread_switch(next); erratum_1418040_thread_switch(next); ptrauth_thread_switch_user(next); @@ -3022,10 +3206,10 @@ index 7387b68c745b..fd80b43c2969 100644 /* * Complete any pending TLB or cache maintenance on this CPU in case diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile -index dbd1bc95967d..4e7cb2f02999 100644 +index 60454256945b8..1a7b3a2f21e6b 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_TRANS_TABLE) += trans_pgd.o +@@ -11,6 +11,7 @@ obj-$(CONFIG_TRANS_TABLE) += trans_pgd.o obj-$(CONFIG_TRANS_TABLE) += trans_pgd-asm.o obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o obj-$(CONFIG_ARM64_MTE) += mteswap.o @@ -3035,7 +3219,7 @@ index dbd1bc95967d..4e7cb2f02999 100644 obj-$(CONFIG_KASAN) += kasan_init.o diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c new file mode 100644 -index 000000000000..b0a67efc522b +index 0000000000000..b0a67efc522bd --- /dev/null +++ b/arch/arm64/mm/gcs.c @@ -0,0 +1,39 @@ @@ -3082,10 +3266,10 @@ index 000000000000..b0a67efc522b 2.34.1 -From ae084320fd60ebe9212701d1da31a466e3aecb61 Mon Sep 17 00:00:00 2001 +From 94201021bb5725ce7c4fc1ad64fa84ad3706af2f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 31 May 2023 16:39:35 +0100 -Subject: [PATCH 29/47] arm64/gcs: Ensure that new threads have a GCS +Subject: [PATCH 31/50] arm64/gcs: Ensure that new threads have a GCS When a new thread is created by a thread with GCS enabled the GCS needs to be specified along with the regular stack. clone3() has been @@ -3113,12 +3297,12 @@ Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown --- arch/arm64/include/asm/gcs.h | 9 +++ - arch/arm64/kernel/process.c | 29 +++++++++ - arch/arm64/mm/gcs.c | 117 +++++++++++++++++++++++++++++++++++ - 3 files changed, 155 insertions(+) + arch/arm64/kernel/process.c | 29 +++++++ + arch/arm64/mm/gcs.c | 143 +++++++++++++++++++++++++++++++++++ + 3 files changed, 181 insertions(+) diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h -index 04594ef59dad..c1f274fdb9c0 100644 +index 04594ef59dadd..c1f274fdb9c02 100644 --- a/arch/arm64/include/asm/gcs.h +++ b/arch/arm64/include/asm/gcs.h @@ -8,6 +8,8 @@ @@ -3152,7 +3336,7 @@ index 04594ef59dad..c1f274fdb9c0 100644 #endif diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c -index fd80b43c2969..8bd66cde0a86 100644 +index 5f00cb0da9c3c..d6d3a96cf2e4b 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -285,9 +285,32 @@ static void flush_gcs(void) @@ -3196,7 +3380,7 @@ index fd80b43c2969..8bd66cde0a86 100644 } int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) -@@ -369,6 +393,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) +@@ -366,6 +390,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) unsigned long stack_start = args->stack; unsigned long tls = args->tls; struct pt_regs *childregs = task_pt_regs(p); @@ -3204,7 +3388,7 @@ index fd80b43c2969..8bd66cde0a86 100644 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); -@@ -410,6 +435,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) +@@ -407,6 +432,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) p->thread.uw.tp_value = tls; p->thread.tpidr2_el0 = 0; } @@ -3216,10 +3400,10 @@ index fd80b43c2969..8bd66cde0a86 100644 /* * A kthread has no context to ERET to, so ensure any buggy diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c -index b0a67efc522b..3cbc3a3d4bc7 100644 +index b0a67efc522bd..4a3ce8e3bdfb5 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c -@@ -8,6 +8,113 @@ +@@ -8,6 +8,139 @@ #include #include @@ -3252,51 +3436,77 @@ index b0a67efc522b..3cbc3a3d4bc7 100644 + return max(PAGE_SIZE, size); +} + -+static bool gcs_consume_token(struct task_struct *tsk, unsigned long user_addr) ++static bool gcs_consume_token(struct mm_struct *mm, unsigned long user_addr) +{ -+ unsigned long expected = GCS_CAP(user_addr); -+ unsigned long val; -+ int ret = 0; ++ u64 expected = GCS_CAP(user_addr); ++ u64 val; ++ int ret; + + /* This should really be an atomic cpmxchg. It is not. */ -+ __get_user_error(val, (__user unsigned long *)user_addr, ret); -+ if (ret != 0) ++ ret = access_remote_vm(mm, user_addr, &val, sizeof(val), ++ FOLL_FORCE); ++ if (ret != sizeof(val)) + return false; + + if (val != expected) + return false; + -+ put_user_gcs(0, (__user unsigned long*)user_addr, &ret); ++ val = 0; ++ ret = access_remote_vm(mm, user_addr, &val, sizeof(val), ++ FOLL_FORCE | FOLL_WRITE); ++ if (ret != sizeof(val)) ++ return false; + -+ return ret == 0; ++ return true; ++} ++ ++int arch_shstk_post_fork(struct task_struct *tsk, ++ struct kernel_clone_args *args) ++{ ++ struct mm_struct *mm; ++ unsigned long addr, size, gcspr_el0; ++ int ret = 0; ++ ++ mm = get_task_mm(tsk); ++ if (!mm) ++ return -EFAULT; ++ ++ addr = args->shadow_stack; ++ size = args->shadow_stack_size; ++ ++ /* ++ * There should be a token, and there is likely to be an optional ++ * end of stack marker above it. ++ */ ++ gcspr_el0 = addr + size - (2 * sizeof(u64)); ++ if (!gcs_consume_token(mm, gcspr_el0)) { ++ gcspr_el0 += sizeof(u64); ++ if (!gcs_consume_token(mm, gcspr_el0)) { ++ ret = -EINVAL; ++ goto out; ++ } ++ } ++ ++ tsk->thread.gcspr_el0 = gcspr_el0 + sizeof(u64); ++ ++out: ++ mmput(mm); ++ ++ return ret; +} + +unsigned long gcs_alloc_thread_stack(struct task_struct *tsk, + const struct kernel_clone_args *args) +{ -+ unsigned long addr, size, gcspr_el0; ++ unsigned long addr, size; + + /* If the user specified a GCS use it. */ + if (args->shadow_stack_size) { + if (!system_supports_gcs()) + return (unsigned long)ERR_PTR(-EINVAL); + ++ /* GCSPR_EL0 will be set up when verifying token post fork */ + addr = args->shadow_stack; -+ size = args->shadow_stack_size; -+ -+ /* -+ * There should be a token, there might be an end of -+ * stack marker. -+ */ -+ gcspr_el0 = addr + size - (2 * sizeof(u64)); -+ if (!gcs_consume_token(tsk, gcspr_el0)) { -+ gcspr_el0 += sizeof(u64); -+ if (!gcs_consume_token(tsk, gcspr_el0)) -+ return (unsigned long)ERR_PTR(-EINVAL); -+ } -+ -+ /* Userspace is responsible for unmapping */ -+ tsk->thread.gcspr_el0 = gcspr_el0 + sizeof(u64); + } else { + + /* @@ -3333,7 +3543,7 @@ index b0a67efc522b..3cbc3a3d4bc7 100644 /* * Apply the GCS mode configured for the specified task to the * hardware. -@@ -30,6 +137,16 @@ void gcs_set_el0_mode(struct task_struct *task) +@@ -30,6 +163,16 @@ void gcs_set_el0_mode(struct task_struct *task) void gcs_free(struct task_struct *task) { @@ -3354,10 +3564,10 @@ index b0a67efc522b..3cbc3a3d4bc7 100644 2.34.1 -From 59d903881df39c2f5ec10d818d303b7fd96a90aa Mon Sep 17 00:00:00 2001 +From a5e6f0bb2817dc6431f147da6b0fcde5191c342a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Apr 2023 20:14:17 +0100 -Subject: [PATCH 30/47] arm64/gcs: Implement shadow stack prctl() interface +Subject: [PATCH 32/50] arm64/gcs: Implement shadow stack prctl() interface Implement the architecture neutral prtctl() interface for setting the shadow stack status, this supports setting and reading the current GCS @@ -3397,7 +3607,7 @@ Signed-off-by: Mark Brown 3 files changed, 104 insertions(+) diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h -index c1f274fdb9c0..48c97e63e56a 100644 +index c1f274fdb9c02..48c97e63e56a1 100644 --- a/arch/arm64/include/asm/gcs.h +++ b/arch/arm64/include/asm/gcs.h @@ -50,6 +50,9 @@ static inline u64 gcsss2(void) @@ -3444,10 +3654,10 @@ index c1f274fdb9c0..48c97e63e56a 100644 #endif diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h -index 6fc6dcbd494c..6a3091ec0f03 100644 +index c55e3600604a6..58eb48cd539fa 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h -@@ -184,6 +184,7 @@ struct thread_struct { +@@ -186,6 +186,7 @@ struct thread_struct { u64 tpidr2_el0; #ifdef CONFIG_ARM64_GCS unsigned int gcs_el0_mode; @@ -3456,10 +3666,10 @@ index 6fc6dcbd494c..6a3091ec0f03 100644 u64 gcs_base; u64 gcs_size; diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c -index 3cbc3a3d4bc7..d5b593d9d9bd 100644 +index 4a3ce8e3bdfb5..c6fae0eb9bd6e 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c -@@ -154,3 +154,84 @@ void gcs_free(struct task_struct *task) +@@ -180,3 +180,84 @@ void gcs_free(struct task_struct *task) task->thread.gcs_base = 0; task->thread.gcs_size = 0; } @@ -3548,10 +3758,10 @@ index 3cbc3a3d4bc7..d5b593d9d9bd 100644 2.34.1 -From 2f3d32fbac2eec5c04aca5e181a52f8d2bca9383 Mon Sep 17 00:00:00 2001 +From a4d14ce3b48a9fbaf54f427724e236c4573e9e08 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 12 Apr 2023 22:29:17 +0100 -Subject: [PATCH 31/47] arm64/mm: Implement map_shadow_stack() +Subject: [PATCH 33/50] arm64/mm: Implement map_shadow_stack() As discussed extensively in the changelog for the addition of this syscall on x86 ("x86/shstk: Introduce map_shadow_stack syscall") the @@ -3576,10 +3786,10 @@ Signed-off-by: Mark Brown 1 file changed, 61 insertions(+) diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c -index d5b593d9d9bd..e238bc9c057d 100644 +index c6fae0eb9bd6e..918d50ba53c6e 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c -@@ -115,6 +115,67 @@ unsigned long gcs_alloc_thread_stack(struct task_struct *tsk, +@@ -141,6 +141,67 @@ unsigned long gcs_alloc_thread_stack(struct task_struct *tsk, return addr; } @@ -3651,10 +3861,10 @@ index d5b593d9d9bd..e238bc9c057d 100644 2.34.1 -From 3251d196916b7a331713cafaaa0265b7205c93a0 Mon Sep 17 00:00:00 2001 +From 2e78d70d45d8206fdb7a29907fbbad5055c8a0a3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 21 Jun 2023 01:28:09 +0100 -Subject: [PATCH 32/47] arm64/signal: Set up and restore the GCS context for +Subject: [PATCH 34/50] arm64/signal: Set up and restore the GCS context for signal handlers When invoking a signal handler we use the GCS configuration and stack @@ -3684,7 +3894,7 @@ Signed-off-by: Mark Brown 3 files changed, 131 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h -index 48c97e63e56a..f50660603ecf 100644 +index 48c97e63e56a1..f50660603ecf5 100644 --- a/arch/arm64/include/asm/gcs.h +++ b/arch/arm64/include/asm/gcs.h @@ -9,6 +9,7 @@ @@ -3696,7 +3906,7 @@ index 48c97e63e56a..f50660603ecf 100644 static inline void gcsb_dsync(void) { diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c -index 425b1bc17a3f..7a063d3e2a8d 100644 +index 4a77f4976e116..a1e0aa38bff9c 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -25,6 +25,7 @@ @@ -3745,7 +3955,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 /* * Do a signal return; undo the signal stack. These are aligned to 128-bit. */ -@@ -815,6 +847,50 @@ static int restore_sigframe(struct pt_regs *regs, +@@ -860,6 +892,50 @@ static int restore_sigframe(struct pt_regs *regs, return err; } @@ -3796,7 +4006,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = current_pt_regs(); -@@ -841,6 +917,9 @@ SYSCALL_DEFINE0(rt_sigreturn) +@@ -886,6 +962,9 @@ SYSCALL_DEFINE0(rt_sigreturn) if (restore_altstack(&frame->uc.uc_stack)) goto badframe; @@ -3806,7 +4016,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 return regs->regs[0]; badframe: -@@ -1071,7 +1150,50 @@ static int get_sigframe(struct rt_sigframe_user_layout *user, +@@ -1130,7 +1209,50 @@ static int get_sigframe(struct rt_sigframe_user_layout *user, return 0; } @@ -3858,7 +4068,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 struct rt_sigframe_user_layout *user, int usig) { __sigrestore_t sigtramp; -@@ -1079,7 +1201,7 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, +@@ -1138,7 +1260,7 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, regs->regs[0] = usig; regs->sp = (unsigned long)user->sigframe; regs->regs[29] = (unsigned long)&user->next_frame->fp; @@ -3867,7 +4077,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 /* * Signal delivery is a (wacky) indirect function call in -@@ -1119,12 +1241,14 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, +@@ -1178,12 +1300,14 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, sme_smstop(); } @@ -3884,7 +4094,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 } static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, -@@ -1147,7 +1271,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, +@@ -1206,7 +1330,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, err |= __save_altstack(&frame->uc.uc_stack, regs->sp); err |= setup_sigframe(&user, regs, set); if (err == 0) { @@ -3894,7 +4104,7 @@ index 425b1bc17a3f..7a063d3e2a8d 100644 err |= copy_siginfo_to_user(&frame->info, &ksig->info); regs->regs[1] = (unsigned long)&frame->info; diff --git a/arch/arm64/mm/gcs.c b/arch/arm64/mm/gcs.c -index e238bc9c057d..e6f505c9bf4a 100644 +index 918d50ba53c6e..7429a4b3600ef 100644 --- a/arch/arm64/mm/gcs.c +++ b/arch/arm64/mm/gcs.c @@ -6,6 +6,7 @@ @@ -3909,10 +4119,10 @@ index e238bc9c057d..e6f505c9bf4a 100644 2.34.1 -From 4f8eb2f612f1df2ca8033dda6114e0e228befdaa Mon Sep 17 00:00:00 2001 +From 5be3b7263dc3ba69030803a046e59269356afb6a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 1 Jun 2023 16:35:46 +0100 -Subject: [PATCH 33/47] arm64/signal: Expose GCS state in signal frames +Subject: [PATCH 35/50] arm64/signal: Expose GCS state in signal frames Add a context for the GCS state and include it in the signal context when running on a system that supports GCS. We reuse the same flags that the @@ -3932,10 +4142,10 @@ Signed-off-by: Mark Brown 2 files changed, 117 insertions(+) diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h -index f23c1dc3f002..7b66d245f2d2 100644 +index 8a45b7a411e04..c2d61e8efc846 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h -@@ -168,6 +168,15 @@ struct zt_context { +@@ -176,6 +176,15 @@ struct zt_context { __u16 __reserved[3]; }; @@ -3952,7 +4162,7 @@ index f23c1dc3f002..7b66d245f2d2 100644 #include diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c -index 7a063d3e2a8d..5b9a45a45f4b 100644 +index a1e0aa38bff9c..f034a1a1d194d 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -88,6 +88,7 @@ struct rt_sigframe_user_layout { @@ -3963,16 +4173,16 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 unsigned long sve_offset; unsigned long tpidr2_offset; unsigned long za_offset; -@@ -214,6 +215,8 @@ struct user_ctxs { - u32 za_size; - struct zt_context __user *zt; +@@ -217,6 +218,8 @@ struct user_ctxs { u32 zt_size; + struct fpmr_context __user *fpmr; + u32 fpmr_size; + struct gcs_context __user *gcs; + u32 gcs_size; }; static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) -@@ -606,6 +609,83 @@ extern int restore_zt_context(struct user_ctxs *user); +@@ -636,6 +639,83 @@ extern int restore_zt_context(struct user_ctxs *user); #endif /* ! CONFIG_ARM64_SME */ @@ -4056,16 +4266,16 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 static int parse_user_sigframe(struct user_ctxs *user, struct rt_sigframe __user *sf) { -@@ -622,6 +702,7 @@ static int parse_user_sigframe(struct user_ctxs *user, - user->tpidr2 = NULL; +@@ -653,6 +733,7 @@ static int parse_user_sigframe(struct user_ctxs *user, user->za = NULL; user->zt = NULL; + user->fpmr = NULL; + user->gcs = NULL; if (!IS_ALIGNED((unsigned long)base, 16)) goto invalid; -@@ -716,6 +797,17 @@ static int parse_user_sigframe(struct user_ctxs *user, - user->zt_size = size; +@@ -758,6 +839,17 @@ static int parse_user_sigframe(struct user_ctxs *user, + user->fpmr_size = size; break; + case GCS_MAGIC: @@ -4082,7 +4292,7 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 case EXTRA_MAGIC: if (have_extra_context) goto invalid; -@@ -835,6 +927,9 @@ static int restore_sigframe(struct pt_regs *regs, +@@ -877,6 +969,9 @@ static int restore_sigframe(struct pt_regs *regs, err = restore_fpsimd_context(&user); } @@ -4092,7 +4302,7 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 if (err == 0 && system_supports_tpidr2() && user.tpidr2) err = restore_tpidr2_context(&user); -@@ -954,6 +1049,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, +@@ -999,6 +1094,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, return err; } @@ -4106,7 +4316,7 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 if (system_supports_sve() || system_supports_sme()) { unsigned int vq = 0; -@@ -1047,6 +1149,12 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user, +@@ -1099,6 +1201,12 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user, __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); } @@ -4123,10 +4333,10 @@ index 7a063d3e2a8d..5b9a45a45f4b 100644 2.34.1 -From 26cb1cbfb9f942ed9d4194d3cc8917e0c636811b Mon Sep 17 00:00:00 2001 +From b48da28b3cdf986270a29a849cd069e5dfcf55c3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 30 Jun 2023 17:32:38 +0100 -Subject: [PATCH 34/47] arm64/ptrace: Expose GCS via ptrace and core files +Subject: [PATCH 36/50] arm64/ptrace: Expose GCS via ptrace and core files Provide a new register type NT_ARM_GCS reporting the current GCS mode and pointer for EL0. Due to the interactions with allocation and @@ -4142,7 +4352,7 @@ Signed-off-by: Mark Brown 3 files changed, 68 insertions(+) diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h -index 7fa2f7036aa7..0f39ba4f3efd 100644 +index 7fa2f7036aa78..0f39ba4f3efd4 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -324,6 +324,14 @@ struct user_za_header { @@ -4161,7 +4371,7 @@ index 7fa2f7036aa7..0f39ba4f3efd 100644 #endif /* _UAPI__ASM_PTRACE_H */ diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c -index e3bef38fc2e2..e291c0145e94 100644 +index 0d022599eb61b..9db0b669fee3c 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -34,6 +34,7 @@ @@ -4172,7 +4382,7 @@ index e3bef38fc2e2..e291c0145e94 100644 #include #include #include -@@ -1411,6 +1412,51 @@ static int tagged_addr_ctrl_set(struct task_struct *target, const struct +@@ -1440,6 +1441,51 @@ static int tagged_addr_ctrl_set(struct task_struct *target, const struct } #endif @@ -4224,7 +4434,7 @@ index e3bef38fc2e2..e291c0145e94 100644 enum aarch64_regset { REGSET_GPR, REGSET_FPR, -@@ -1439,6 +1485,9 @@ enum aarch64_regset { +@@ -1469,6 +1515,9 @@ enum aarch64_regset { #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI REGSET_TAGGED_ADDR_CTRL, #endif @@ -4234,7 +4444,7 @@ index e3bef38fc2e2..e291c0145e94 100644 }; static const struct user_regset aarch64_regsets[] = { -@@ -1590,6 +1639,16 @@ static const struct user_regset aarch64_regsets[] = { +@@ -1628,6 +1677,16 @@ static const struct user_regset aarch64_regsets[] = { .set = tagged_addr_ctrl_set, }, #endif @@ -4252,14 +4462,14 @@ index e3bef38fc2e2..e291c0145e94 100644 static const struct user_regset_view user_aarch64_view = { diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h -index 9417309b7230..436dfc359f61 100644 +index b54b313bcf073..77d4910bbb9d4 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h -@@ -440,6 +440,7 @@ typedef struct elf64_shdr { - #define NT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */ +@@ -441,6 +441,7 @@ typedef struct elf64_shdr { #define NT_ARM_ZA 0x40c /* ARM SME ZA registers */ #define NT_ARM_ZT 0x40d /* ARM SME ZT registers */ -+#define NT_ARM_GCS 0x40e /* ARM GCS state */ + #define NT_ARM_FPMR 0x40e /* ARM floating point mode register */ ++#define NT_ARM_GCS 0x40f /* ARM GCS state */ #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ @@ -4267,10 +4477,10 @@ index 9417309b7230..436dfc359f61 100644 2.34.1 -From 2f6d799ed18f86452b2c1a07ec1a65a2843cab7e Mon Sep 17 00:00:00 2001 +From f6f628d7c414048386c57f0870496b27acaa8da1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Mar 2023 22:34:05 +0000 -Subject: [PATCH 35/47] arm64: Add Kconfig for Guarded Control Stack (GCS) +Subject: [PATCH 37/50] arm64: Add Kconfig for Guarded Control Stack (GCS) Provide a Kconfig option allowing the user to select if GCS support is built into the kernel. @@ -4282,10 +4492,10 @@ Signed-off-by: Mark Brown 1 file changed, 20 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index aa7c1d435139..e0048e4660cf 100644 +index 5d91259ee7b53..248697a29d78f 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -2098,6 +2098,26 @@ config ARM64_EPAN +@@ -2140,6 +2140,26 @@ config ARM64_EPAN if the cpu does not implement the feature. endmenu # "ARMv8.7 architectural features" @@ -4316,10 +4526,10 @@ index aa7c1d435139..e0048e4660cf 100644 2.34.1 -From 56346b042191155ca2397d01de908dc8954592e3 Mon Sep 17 00:00:00 2001 +From c956d4219534a96438827172ade46716d821183d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Mar 2023 18:24:51 +0000 -Subject: [PATCH 36/47] kselftest/arm64: Verify the GCS hwcap +Subject: [PATCH 38/50] kselftest/arm64: Verify the GCS hwcap Add coverage of the GCS hwcap to the hwcap selftest, using a read of GCSPR_EL0 to generate SIGILL without having to worry about enabling GCS. @@ -4331,11 +4541,11 @@ Signed-off-by: Mark Brown 1 file changed, 19 insertions(+) diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c -index 1189e77c8152..bc9e3250a9df 100644 +index d8909b2b535a0..dc54ae894fe52 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c -@@ -63,6 +63,17 @@ static void fp_sigill(void) - asm volatile("fmov s0, #1"); +@@ -98,6 +98,17 @@ static void fpmr_sigill(void) + asm volatile("mrs x0, S3_3_C4_C4_2" : : : "x0"); } +static void gcs_sigill(void) @@ -4352,9 +4562,9 @@ index 1189e77c8152..bc9e3250a9df 100644 static void ilrcpc_sigill(void) { /* LDAPUR W0, [SP, #8] */ -@@ -360,6 +371,14 @@ static const struct hwcap_data { - .cpuinfo = "fp", - .sigill_fn = fp_sigill, +@@ -528,6 +539,14 @@ static const struct hwcap_data { + .sigill_fn = fpmr_sigill, + .sigill_reliable = true, }, + { + .name = "GCS", @@ -4371,10 +4581,10 @@ index 1189e77c8152..bc9e3250a9df 100644 2.34.1 -From 38f47a23529268f26d7378710065e378e4022a95 Mon Sep 17 00:00:00 2001 +From 6924204da3520cd2d6a9548b1806f6146372a8bb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 29 Jan 2024 22:45:01 +0000 -Subject: [PATCH 37/47] kselftest: Provide shadow stack enable helpers for +Subject: [PATCH 39/50] kselftest: Provide shadow stack enable helpers for arm64 Allow test programs to use the shadow stack helpers on arm64. @@ -4386,7 +4596,7 @@ Signed-off-by: Mark Brown 1 file changed, 37 insertions(+) diff --git a/tools/testing/selftests/ksft_shstk.h b/tools/testing/selftests/ksft_shstk.h -index 85d0747c1802..223e24b4eb80 100644 +index 85d0747c18022..302957a0bbd5f 100644 --- a/tools/testing/selftests/ksft_shstk.h +++ b/tools/testing/selftests/ksft_shstk.h @@ -50,6 +50,43 @@ static inline __attribute__((always_inline)) void enable_shadow_stack(void) @@ -4394,7 +4604,7 @@ index 85d0747c1802..223e24b4eb80 100644 #endif +#ifdef __aarch64__ -+#define PR_SET_SHADOW_STACK_STATUS 72 ++#define PR_SET_SHADOW_STACK_STATUS 75 +# define PR_SHADOW_STACK_ENABLE (1UL << 0) + +#define my_syscall2(num, arg1, arg2) \ @@ -4437,10 +4647,64 @@ index 85d0747c1802..223e24b4eb80 100644 2.34.1 -From 99d2e9efa5194a3fa58d64e8c89657952607ca49 Mon Sep 17 00:00:00 2001 +From 0fa89bf3d122e8b4f2aa34b2e108ec4bbfdc5fab Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Wed, 19 Jun 2024 19:11:03 +0100 +Subject: [PATCH 40/50] selftests/clone3: Enable arm64 shadow stack testing + +In order to test shadow stack support in clone3() the clone3() selftests +need to have a fully inline clone3() call, provide one for arm64. + +Signed-off-by: Mark Brown +--- + .../selftests/clone3/clone3_selftests.h | 26 +++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h +index 38d82934668a8..e329150853335 100644 +--- a/tools/testing/selftests/clone3/clone3_selftests.h ++++ b/tools/testing/selftests/clone3/clone3_selftests.h +@@ -69,6 +69,32 @@ static pid_t __always_inline sys_clone3(struct __clone_args *args, size_t size) + + return ret; + } ++#elif defined(__aarch64__) ++static pid_t __always_inline sys_clone3(struct __clone_args *args, size_t size) ++{ ++ register long _num __asm__ ("x8") = __NR_clone3; ++ register long _args __asm__ ("x0") = (long)(args); ++ register long _size __asm__ ("x1") = (long)(size); ++ register long arg2 __asm__ ("x2") = 0; ++ register long arg3 __asm__ ("x3") = 0; ++ register long arg4 __asm__ ("x4") = 0; ++ ++ __asm__ volatile ( ++ "svc #0\n" ++ : "=r"(_args) ++ : "r"(_args), "r"(_size), ++ "r"(_num), "r"(arg2), ++ "r"(arg3), "r"(arg4) ++ : "memory", "cc" ++ ); ++ ++ if ((int)_args < 0) { ++ errno = -((int)_args); ++ return -1; ++ } ++ ++ return _args; ++} + #else + static pid_t sys_clone3(struct __clone_args *args, size_t size) + { +-- +2.34.1 + + +From 4b7b22a1e1f5de060cdc9b5cf3719314c32c5467 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 26 Apr 2023 19:05:43 +0100 -Subject: [PATCH 38/47] kselftest/arm64: Add GCS as a detected feature in the +Subject: [PATCH 41/50] kselftest/arm64: Add GCS as a detected feature in the signal tests In preparation for testing GCS related signal handling add it as a feature @@ -4454,7 +4718,7 @@ Signed-off-by: Mark Brown 2 files changed, 5 insertions(+) diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h -index 1e6273d81575..7ada43688c02 100644 +index 1e6273d815759..7ada43688c024 100644 --- a/tools/testing/selftests/arm64/signal/test_signals.h +++ b/tools/testing/selftests/arm64/signal/test_signals.h @@ -35,6 +35,7 @@ enum { @@ -4474,7 +4738,7 @@ index 1e6273d81575..7ada43688c02 100644 /* * A descriptor used to describe and configure a test case. diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c -index 0dc948db3a4a..89ef95c1af0e 100644 +index 0dc948db3a4a4..89ef95c1af0eb 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.c +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c @@ -30,6 +30,7 @@ static char const *const feats_names[FMAX_END] = { @@ -4498,10 +4762,10 @@ index 0dc948db3a4a..89ef95c1af0e 100644 2.34.1 -From 4d1754e3575bc4546e633d957977edb42718fd79 Mon Sep 17 00:00:00 2001 +From 76863aabcb6b172447f6d85b01496a5971c83c4e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 1 Jun 2023 17:52:08 +0100 -Subject: [PATCH 39/47] kselftest/arm64: Add framework support for GCS to +Subject: [PATCH 42/50] kselftest/arm64: Add framework support for GCS to signal handling tests Teach the framework about the GCS signal context, avoiding warnings on @@ -4515,12 +4779,12 @@ Signed-off-by: Mark Brown 2 files changed, 8 insertions(+) diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c -index 9f580b55b388..1cd124732be4 100644 +index 674b88cc8c394..49d036e979964 100644 --- a/tools/testing/selftests/arm64/signal/testcases/testcases.c +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c -@@ -209,6 +209,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err) - zt = (struct zt_context *)head; - new_flags |= ZT_CTX; +@@ -217,6 +217,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err) + *err = "Bad size for fpmr_context"; + new_flags |= FPMR_CTX; break; + case GCS_MAGIC: + if (flags & GCS_CTX) @@ -4533,14 +4797,14 @@ index 9f580b55b388..1cd124732be4 100644 if (flags & EXTRA_CTX) *err = "Multiple EXTRA_MAGIC"; diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h -index a08ab0d6207a..9b2599745c29 100644 +index 7727126347e0b..dc3cf777dafe4 100644 --- a/tools/testing/selftests/arm64/signal/testcases/testcases.h +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h -@@ -19,6 +19,7 @@ - #define ZA_CTX (1 << 2) +@@ -20,6 +20,7 @@ #define EXTRA_CTX (1 << 3) #define ZT_CTX (1 << 4) -+#define GCS_CTX (1 << 5) + #define FPMR_CTX (1 << 5) ++#define GCS_CTX (1 << 6) #define KSFT_BAD_MAGIC 0xdeadbeef @@ -4548,10 +4812,10 @@ index a08ab0d6207a..9b2599745c29 100644 2.34.1 -From 6cfe93b36e2ac080db62d44ed0bd8a6f972ceffa Mon Sep 17 00:00:00 2001 +From cda93f3a97a6a71c2fad11becac0309814a749e9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Jul 2023 17:40:22 +0100 -Subject: [PATCH 40/47] kselftest/arm64: Allow signals tests to specify an +Subject: [PATCH 43/50] kselftest/arm64: Allow signals tests to specify an expected si_code Currently we ignore si_code unless the expected signal is a SIGSEGV, in @@ -4567,7 +4831,7 @@ Signed-off-by: Mark Brown 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h -index 7ada43688c02..ee75a2c25ce7 100644 +index 7ada43688c024..ee75a2c25ce7e 100644 --- a/tools/testing/selftests/arm64/signal/test_signals.h +++ b/tools/testing/selftests/arm64/signal/test_signals.h @@ -71,6 +71,10 @@ struct tdescr { @@ -4582,7 +4846,7 @@ index 7ada43688c02..ee75a2c25ce7 100644 int sig_unsupp; /* a timeout in second for test completion */ diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c -index 89ef95c1af0e..63deca32b0df 100644 +index 89ef95c1af0eb..63deca32b0dff 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.c +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c @@ -143,16 +143,25 @@ static bool handle_signal_ok(struct tdescr *td, @@ -4625,10 +4889,10 @@ index 89ef95c1af0e..63deca32b0df 100644 2.34.1 -From c48cd5f2f586f4bfc9b17e6101727933d428511e Mon Sep 17 00:00:00 2001 +From 5455426403d03db242b6ea92ac8175704c07165e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 5 Jul 2023 14:43:32 +0100 -Subject: [PATCH 41/47] kselftest/arm64: Always run signals tests with GCS +Subject: [PATCH 44/50] kselftest/arm64: Always run signals tests with GCS enabled Since it is not possible to return from the function that enabled GCS @@ -4647,7 +4911,7 @@ Signed-off-by: Mark Brown 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/arm64/signal/test_signals.c b/tools/testing/selftests/arm64/signal/test_signals.c -index 00051b40d71e..30e95f50db19 100644 +index 00051b40d71ea..30e95f50db19b 100644 --- a/tools/testing/selftests/arm64/signal/test_signals.c +++ b/tools/testing/selftests/arm64/signal/test_signals.c @@ -7,6 +7,10 @@ @@ -4687,7 +4951,7 @@ index 00051b40d71e..30e95f50db19 100644 + exit(current->result); } diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h -index 762c8fe9c54a..1e80808ee105 100644 +index 762c8fe9c54ad..1e80808ee105d 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h @@ -18,6 +18,35 @@ void test_cleanup(struct tdescr *td); @@ -4730,10 +4994,10 @@ index 762c8fe9c54a..1e80808ee105 100644 2.34.1 -From dff5594c2072aa86c028171e06c5c706dc632a0c Mon Sep 17 00:00:00 2001 +From b7a723b546791f570fbc055e195af0cccd87de1a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 6 Apr 2023 00:35:19 +0100 -Subject: [PATCH 42/47] kselftest/arm64: Add very basic GCS test program +Subject: [PATCH 45/50] kselftest/arm64: Add very basic GCS test program This test program just covers the basic GCS ABI, covering aspects of the ABI as standalone features without attempting to integrate things. @@ -4744,16 +5008,16 @@ Signed-off-by: Mark Brown tools/testing/selftests/arm64/Makefile | 2 +- tools/testing/selftests/arm64/gcs/.gitignore | 1 + tools/testing/selftests/arm64/gcs/Makefile | 18 + - tools/testing/selftests/arm64/gcs/basic-gcs.c | 431 ++++++++++++++++++ - tools/testing/selftests/arm64/gcs/gcs-util.h | 90 ++++ - 5 files changed, 541 insertions(+), 1 deletion(-) + tools/testing/selftests/arm64/gcs/basic-gcs.c | 357 ++++++++++++++++++ + tools/testing/selftests/arm64/gcs/gcs-util.h | 90 +++++ + 5 files changed, 467 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/arm64/gcs/.gitignore create mode 100644 tools/testing/selftests/arm64/gcs/Makefile create mode 100644 tools/testing/selftests/arm64/gcs/basic-gcs.c create mode 100644 tools/testing/selftests/arm64/gcs/gcs-util.h diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile -index 28b93cab8c0d..22029e60eff3 100644 +index 28b93cab8c0dd..22029e60eff39 100644 --- a/tools/testing/selftests/arm64/Makefile +++ b/tools/testing/selftests/arm64/Makefile @@ -4,7 +4,7 @@ @@ -4767,14 +5031,14 @@ index 28b93cab8c0d..22029e60eff3 100644 endif diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore new file mode 100644 -index 000000000000..0e5e695ecba5 +index 0000000000000..0e5e695ecba59 --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/.gitignore @@ -0,0 +1 @@ +basic-gcs diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile new file mode 100644 -index 000000000000..61a30f483429 +index 0000000000000..61a30f483429c --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/Makefile @@ -0,0 +1,18 @@ @@ -4798,10 +5062,10 @@ index 000000000000..61a30f483429 + -ffreestanding -Wall $^ -o $@ -lgcc diff --git a/tools/testing/selftests/arm64/gcs/basic-gcs.c b/tools/testing/selftests/arm64/gcs/basic-gcs.c new file mode 100644 -index 000000000000..b3522d606a58 +index 0000000000000..3fb9742342a34 --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/basic-gcs.c -@@ -0,0 +1,431 @@ +@@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 ARM Limited. @@ -4847,7 +5111,7 @@ index 000000000000..b3522d606a58 + &new_mode, 0, 0, 0); + if (ret == 0) { + if (new_mode != mode) { -+ ksft_print_msg("Mode set to %x not %x\n", ++ ksft_print_msg("Mode set to %lx not %lx\n", + new_mode, mode); + ret = -EINVAL; + } @@ -4995,17 +5259,17 @@ index 000000000000..b3522d606a58 + SHADOW_STACK_SET_MARKER | + SHADOW_STACK_SET_TOKEN); + if (buf == MAP_FAILED) { -+ ksft_print_msg("Failed to map %d byte GCS: %d\n", ++ ksft_print_msg("Failed to map %lu byte GCS: %d\n", + page_size, errno); + return false; + } + ksft_print_msg("Mapped GCS at %p-%p\n", buf, -+ (uint64_t)buf + page_size); ++ (void *)((uint64_t)buf + page_size)); + + /* The top of the newly allocated region should be 0 */ + elem = (page_size / sizeof(uint64_t)) - 1; + if (buf[elem]) { -+ ksft_print_msg("Last entry is 0x%lx not 0x0\n", buf[elem]); ++ ksft_print_msg("Last entry is 0x%llx not 0x0\n", buf[elem]); + pass = false; + } + @@ -5015,24 +5279,24 @@ index 000000000000..b3522d606a58 + expected_cap &= GCS_CAP_ADDR_MASK; + expected_cap |= GCS_CAP_VALID_TOKEN; + if (buf[elem] != expected_cap) { -+ ksft_print_msg("Cap entry is 0x%lx not 0x%lx\n", ++ ksft_print_msg("Cap entry is 0x%llx not 0x%llx\n", + buf[elem], expected_cap); + pass = false; + } -+ ksft_print_msg("cap token is 0x%lx\n", buf[elem]); ++ ksft_print_msg("cap token is 0x%llx\n", buf[elem]); + + /* The rest should be zeros */ + for (elem = 0; elem < page_size / sizeof(uint64_t) - 2; elem++) { + if (!buf[elem]) + continue; -+ ksft_print_msg("GCS slot %d is 0x%lx not 0x0\n", ++ ksft_print_msg("GCS slot %d is 0x%llx not 0x0\n", + elem, buf[elem]); + pass = false; + } + + ret = munmap(buf, page_size); + if (ret != 0) { -+ ksft_print_msg("Failed to unmap %d byte GCS: %d\n", ++ ksft_print_msg("Failed to unmap %ld byte GCS: %d\n", + page_size, errno); + pass = false; + } @@ -5102,79 +5366,6 @@ index 000000000000..b3522d606a58 + return pass; +} + -+/* Check that we can explicitly specify a GCS via clone3() */ -+static bool test_clone3(void) -+{ -+ struct clone_args args; -+ unsigned long child_mode; -+ pid_t pid = -1; -+ int status, ret; -+ bool pass; -+ -+ memset(&args, 0, sizeof(args)); -+ args.flags = CLONE_VM; -+ args.shadow_stack = my_syscall3(__NR_map_shadow_stack, 0, page_size, -+ SHADOW_STACK_SET_MARKER | -+ SHADOW_STACK_SET_TOKEN); -+ args.shadow_stack_size = page_size; -+ -+ pid = my_syscall2(__NR_clone3, &args, sizeof(args)); -+ if (pid < 0) { -+ ksft_print_msg("clone3() failed: %d\n", errno); -+ pass = false; -+ goto out; -+ } -+ -+ /* In child? */ -+ if (pid == 0) { -+ /* Do we have GCS enabled? */ -+ ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, -+ &child_mode, 0, 0, 0); -+ if (ret != 0) { -+ ksft_print_msg("PR_GET_SHADOW_STACK_STATUS failed: %d\n", -+ ret); -+ exit(EXIT_FAILURE); -+ } -+ -+ if (!(child_mode & PR_SHADOW_STACK_ENABLE)) { -+ ksft_print_msg("GCS not enabled in child\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ ksft_print_msg("GCS enabled in child\n"); -+ -+ /* We've probably already called a function but make sure */ -+ valid_gcs_function(); -+ -+ exit(EXIT_SUCCESS); -+ } -+ -+ if (waitpid(-1, &status, __WALL) < 0) { -+ ksft_print_msg("waitpid() failed %d\n", errno); -+ pass = false; -+ goto out; -+ } -+ if (WIFEXITED(status)) { -+ if (WEXITSTATUS(status) == EXIT_SUCCESS) { -+ pass = true; -+ } else { -+ ksft_print_msg("Child returned status %d\n", -+ WEXITSTATUS(status)); -+ pass = false; -+ } -+ } else if (WIFSIGNALED(status)) { -+ ksft_print_msg("Child exited due to signal %d\n", -+ WTERMSIG(status)); -+ pass = false; -+ } else { -+ ksft_print_msg("Child exited uncleanly\n"); -+ pass = false; -+ } -+ -+out: -+ return pass; -+} -+ +typedef bool (*gcs_test)(void); + +static struct { @@ -5191,7 +5382,6 @@ index 000000000000..b3522d606a58 + { "enable_invalid", enable_invalid, true }, + { "map_guarded_stack", map_guarded_stack }, + { "fork", test_fork }, -+ { "clone3", test_clone3 }, +}; + +int main(void) @@ -5235,7 +5425,7 @@ index 000000000000..b3522d606a58 +} diff --git a/tools/testing/selftests/arm64/gcs/gcs-util.h b/tools/testing/selftests/arm64/gcs/gcs-util.h new file mode 100644 -index 000000000000..b37801c95604 +index 0000000000000..1ae6864d3f86a --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/gcs-util.h @@ -0,0 +1,90 @@ @@ -5258,9 +5448,9 @@ index 000000000000..b37801c95604 +#endif + +/* Shadow Stack/Guarded Control Stack interface */ -+#define PR_GET_SHADOW_STACK_STATUS 71 -+#define PR_SET_SHADOW_STACK_STATUS 72 -+#define PR_LOCK_SHADOW_STACK_STATUS 73 ++#define PR_GET_SHADOW_STACK_STATUS 74 ++#define PR_SET_SHADOW_STACK_STATUS 75 ++#define PR_LOCK_SHADOW_STACK_STATUS 76 + +# define PR_SHADOW_STACK_ENABLE (1UL << 0) +# define PR_SHADOW_STACK_WRITE (1UL << 1) @@ -5333,10 +5523,10 @@ index 000000000000..b37801c95604 2.34.1 -From 21b5f923dd2284877481d62e62994edfae826f71 Mon Sep 17 00:00:00 2001 +From a1d9c2596cb40d8bde8b9a30c0599e1a9991c5f0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 28 Apr 2023 18:06:06 +0100 -Subject: [PATCH 43/47] kselftest/arm64: Add a GCS test program built with the +Subject: [PATCH 46/50] kselftest/arm64: Add a GCS test program built with the system libc There are things like threads which nolibc struggles with which we want @@ -5355,14 +5545,14 @@ Signed-off-by: Mark Brown create mode 100644 tools/testing/selftests/arm64/gcs/libc-gcs.c diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore -index 0e5e695ecba5..5810c4a163d4 100644 +index 0e5e695ecba59..5810c4a163d44 100644 --- a/tools/testing/selftests/arm64/gcs/.gitignore +++ b/tools/testing/selftests/arm64/gcs/.gitignore @@ -1 +1,2 @@ basic-gcs +libc-gcs diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile -index 61a30f483429..a8fdf21e9a47 100644 +index 61a30f483429c..a8fdf21e9a471 100644 --- a/tools/testing/selftests/arm64/gcs/Makefile +++ b/tools/testing/selftests/arm64/gcs/Makefile @@ -6,7 +6,9 @@ @@ -5377,7 +5567,7 @@ index 61a30f483429..a8fdf21e9a47 100644 include ../../lib.mk diff --git a/tools/testing/selftests/arm64/gcs/gcs-util.h b/tools/testing/selftests/arm64/gcs/gcs-util.h -index b37801c95604..4bafd1d7feb5 100644 +index 1ae6864d3f86a..8ac37dc3c78ea 100644 --- a/tools/testing/selftests/arm64/gcs/gcs-util.h +++ b/tools/testing/selftests/arm64/gcs/gcs-util.h @@ -16,6 +16,16 @@ @@ -5385,7 +5575,7 @@ index b37801c95604..4bafd1d7feb5 100644 #endif +#ifndef NT_ARM_GCS -+#define NT_ARM_GCS 0x40e ++#define NT_ARM_GCS 0x40f + +struct user_gcs { + __u64 features_enabled; @@ -5395,11 +5585,11 @@ index b37801c95604..4bafd1d7feb5 100644 +#endif + /* Shadow Stack/Guarded Control Stack interface */ - #define PR_GET_SHADOW_STACK_STATUS 71 - #define PR_SET_SHADOW_STACK_STATUS 72 + #define PR_GET_SHADOW_STACK_STATUS 74 + #define PR_SET_SHADOW_STACK_STATUS 75 diff --git a/tools/testing/selftests/arm64/gcs/libc-gcs.c b/tools/testing/selftests/arm64/gcs/libc-gcs.c new file mode 100644 -index 000000000000..937f8bee7bdd +index 0000000000000..937f8bee7bdde --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/libc-gcs.c @@ -0,0 +1,736 @@ @@ -6143,10 +6333,10 @@ index 000000000000..937f8bee7bdd 2.34.1 -From 93014b383e621ede703124d9f26b8d0d4f5a010a Mon Sep 17 00:00:00 2001 +From e3d146167717756a3143982048ed8791bd779ae6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 21 Jul 2023 14:21:32 +0100 -Subject: [PATCH 44/47] kselftest/arm64: Add test coverage for GCS mode locking +Subject: [PATCH 47/50] kselftest/arm64: Add test coverage for GCS mode locking Verify that we can lock individual GCS mode bits, that other modes aren't affected and as a side effect also that every combination of @@ -6172,7 +6362,7 @@ Signed-off-by: Mark Brown create mode 100644 tools/testing/selftests/arm64/gcs/gcs-locking.c diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore -index 5810c4a163d4..0c86f53f68ad 100644 +index 5810c4a163d44..0c86f53f68ad2 100644 --- a/tools/testing/selftests/arm64/gcs/.gitignore +++ b/tools/testing/selftests/arm64/gcs/.gitignore @@ -1,2 +1,3 @@ @@ -6180,7 +6370,7 @@ index 5810c4a163d4..0c86f53f68ad 100644 libc-gcs +gcs-locking diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile -index a8fdf21e9a47..2173d6275956 100644 +index a8fdf21e9a471..2173d6275956d 100644 --- a/tools/testing/selftests/arm64/gcs/Makefile +++ b/tools/testing/selftests/arm64/gcs/Makefile @@ -6,7 +6,7 @@ @@ -6194,7 +6384,7 @@ index a8fdf21e9a47..2173d6275956 100644 diff --git a/tools/testing/selftests/arm64/gcs/gcs-locking.c b/tools/testing/selftests/arm64/gcs/gcs-locking.c new file mode 100644 -index 000000000000..f6a73254317e +index 0000000000000..f6a73254317e8 --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/gcs-locking.c @@ -0,0 +1,200 @@ @@ -6402,10 +6592,10 @@ index 000000000000..f6a73254317e 2.34.1 -From 8bb3f253e14703f8c4213fd45ff120d07847cfb9 Mon Sep 17 00:00:00 2001 +From 00b44ec8fa0aeccaebbdd5112a6187c1a7181e0d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 16 Jun 2023 22:13:44 +0100 -Subject: [PATCH 45/47] kselftest/arm64: Add GCS signal tests +Subject: [PATCH 48/50] kselftest/arm64: Add GCS signal tests Do some testing of the signal handling for GCS, checking that a GCS frame has the expected information in it and that the expected signals @@ -6425,19 +6615,19 @@ Signed-off-by: Mark Brown create mode 100644 tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore -index 839e3a252629..26de12918890 100644 +index 1ce5b5eac3866..75d691c132077 100644 --- a/tools/testing/selftests/arm64/signal/.gitignore +++ b/tools/testing/selftests/arm64/signal/.gitignore -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only +@@ -2,6 +2,7 @@ mangle_* fake_sigreturn_* + fpmr_* +gcs_* sme_* ssve_* sve_* diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h -index 1e80808ee105..36fc12b3cd60 100644 +index 1e80808ee105d..36fc12b3cd604 100644 --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h @@ -6,6 +6,7 @@ @@ -6466,7 +6656,7 @@ index 1e80808ee105..36fc12b3cd60 100644 if (td->feats_incompatible & td->feats_supported) diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c new file mode 100644 -index 000000000000..6228448b2ae7 +index 0000000000000..6228448b2ae79 --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/gcs_exception_fault.c @@ -0,0 +1,62 @@ @@ -6534,7 +6724,7 @@ index 000000000000..6228448b2ae7 +}; diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c new file mode 100644 -index 000000000000..b405d82321da +index 0000000000000..b405d82321daf --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/gcs_frame.c @@ -0,0 +1,88 @@ @@ -6628,7 +6818,7 @@ index 000000000000..b405d82321da +}; diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c new file mode 100644 -index 000000000000..faeabb18c4b2 +index 0000000000000..faeabb18c4b2f --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/gcs_write_fault.c @@ -0,0 +1,67 @@ @@ -6703,10 +6893,10 @@ index 000000000000..faeabb18c4b2 2.34.1 -From f378d27d073d96254a972ad48b14f12fa684e9ac Mon Sep 17 00:00:00 2001 +From e81b987237ca8903571306020cf208a02e75d42a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 26 Jul 2023 22:27:08 +0100 -Subject: [PATCH 46/47] kselftest/arm64: Add a GCS stress test +Subject: [PATCH 49/50] kselftest/arm64: Add a GCS stress test Add a stress test which runs one more process than we have CPUs spinning through a very recursive function with frequent syscalls immediately prior @@ -6729,7 +6919,7 @@ Signed-off-by: Mark Brown create mode 100644 tools/testing/selftests/arm64/gcs/gcs-stress.c diff --git a/tools/testing/selftests/arm64/gcs/.gitignore b/tools/testing/selftests/arm64/gcs/.gitignore -index 0c86f53f68ad..1e8d1f6b27f2 100644 +index 0c86f53f68ad2..1e8d1f6b27f2b 100644 --- a/tools/testing/selftests/arm64/gcs/.gitignore +++ b/tools/testing/selftests/arm64/gcs/.gitignore @@ -1,3 +1,5 @@ @@ -6739,7 +6929,7 @@ index 0c86f53f68ad..1e8d1f6b27f2 100644 +gcs-stress +gcs-stress-thread diff --git a/tools/testing/selftests/arm64/gcs/Makefile b/tools/testing/selftests/arm64/gcs/Makefile -index 2173d6275956..d8b06ca51e22 100644 +index 2173d6275956d..d8b06ca51e22a 100644 --- a/tools/testing/selftests/arm64/gcs/Makefile +++ b/tools/testing/selftests/arm64/gcs/Makefile @@ -6,7 +6,8 @@ @@ -6761,10 +6951,10 @@ index 2173d6275956..d8b06ca51e22 100644 + $(CC) -nostdlib $^ -o $@ diff --git a/tools/testing/selftests/arm64/gcs/asm-offsets.h b/tools/testing/selftests/arm64/gcs/asm-offsets.h new file mode 100644 -index 000000000000..e69de29bb2d1 +index 0000000000000..e69de29bb2d1d diff --git a/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S b/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S new file mode 100644 -index 000000000000..2a08d6bf1ced +index 0000000000000..2a08d6bf1cedd --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/gcs-stress-thread.S @@ -0,0 +1,311 @@ @@ -7081,7 +7271,7 @@ index 000000000000..2a08d6bf1ced + svc #0 diff --git a/tools/testing/selftests/arm64/gcs/gcs-stress.c b/tools/testing/selftests/arm64/gcs/gcs-stress.c new file mode 100644 -index 000000000000..23fd8ec37bdc +index 0000000000000..23fd8ec37bdcf --- /dev/null +++ b/tools/testing/selftests/arm64/gcs/gcs-stress.c @@ -0,0 +1,532 @@ @@ -7621,10 +7811,10 @@ index 000000000000..23fd8ec37bdc 2.34.1 -From dd225d77971ba0aec130153db16df53014141756 Mon Sep 17 00:00:00 2001 +From 450d848f1ea499c6985d4d9e66c6da3209cc300b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 21 Jun 2023 17:53:57 +0100 -Subject: [PATCH 47/47] kselftest/arm64: Enable GCS for the FP stress tests +Subject: [PATCH 50/50] kselftest/arm64: Enable GCS for the FP stress tests While it's a bit off topic for them the floating point stress tests do give us some coverage of context thrashing cases, and also of active signal @@ -7643,14 +7833,14 @@ Signed-off-by: Mark Brown 5 files changed, 23 insertions(+) diff --git a/tools/testing/selftests/arm64/fp/assembler.h b/tools/testing/selftests/arm64/fp/assembler.h -index 9b38a0da407d..7012f9f796de 100644 +index 9b38a0da407d8..1fc46a5642c29 100644 --- a/tools/testing/selftests/arm64/fp/assembler.h +++ b/tools/testing/selftests/arm64/fp/assembler.h @@ -65,4 +65,19 @@ endfunction bl puts .endm -+#define PR_SET_SHADOW_STACK_STATUS 72 ++#define PR_SET_SHADOW_STACK_STATUS 75 +# define PR_SHADOW_STACK_ENABLE (1UL << 0) + +.macro enable_gcs @@ -7667,7 +7857,7 @@ index 9b38a0da407d..7012f9f796de 100644 + #endif /* ! ASSEMBLER_H */ diff --git a/tools/testing/selftests/arm64/fp/fpsimd-test.S b/tools/testing/selftests/arm64/fp/fpsimd-test.S -index 8b960d01ed2e..b16fb7f42e3e 100644 +index 8b960d01ed2e0..b16fb7f42e3e4 100644 --- a/tools/testing/selftests/arm64/fp/fpsimd-test.S +++ b/tools/testing/selftests/arm64/fp/fpsimd-test.S @@ -215,6 +215,8 @@ endfunction @@ -7680,7 +7870,7 @@ index 8b960d01ed2e..b16fb7f42e3e 100644 mov w0, #SIGINT diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S -index fff60e2a25ad..2fb4f0b84476 100644 +index fff60e2a25add..2fb4f0b84476b 100644 --- a/tools/testing/selftests/arm64/fp/sve-test.S +++ b/tools/testing/selftests/arm64/fp/sve-test.S @@ -378,6 +378,8 @@ endfunction @@ -7693,7 +7883,7 @@ index fff60e2a25ad..2fb4f0b84476 100644 mov w0, #SIGINT diff --git a/tools/testing/selftests/arm64/fp/za-test.S b/tools/testing/selftests/arm64/fp/za-test.S -index 095b45531640..b2603aba99de 100644 +index 095b455316409..b2603aba99de8 100644 --- a/tools/testing/selftests/arm64/fp/za-test.S +++ b/tools/testing/selftests/arm64/fp/za-test.S @@ -231,6 +231,8 @@ endfunction @@ -7706,7 +7896,7 @@ index 095b45531640..b2603aba99de 100644 mov w0, #SIGINT diff --git a/tools/testing/selftests/arm64/fp/zt-test.S b/tools/testing/selftests/arm64/fp/zt-test.S -index b5c81e81a379..8d9609a49008 100644 +index b5c81e81a3794..8d9609a490085 100644 --- a/tools/testing/selftests/arm64/fp/zt-test.S +++ b/tools/testing/selftests/arm64/fp/zt-test.S @@ -200,6 +200,8 @@ endfunction diff --git a/meta-arm-gcs/recipes-kernel/linux/linux-yocto-dev.bbappend b/meta-arm-gcs/recipes-kernel/linux/linux-yocto-dev.bbappend index 0d6d78b1..28bcc63c 100644 --- a/meta-arm-gcs/recipes-kernel/linux/linux-yocto-dev.bbappend +++ b/meta-arm-gcs/recipes-kernel/linux/linux-yocto-dev.bbappend @@ -1,9 +1,9 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:" -KBRANCH = "v6.8/base" -SRCREV_machine = "e8f897f4afef0031fe618a8e94127a0934896aba" -SRCREV_meta = "69506f439abc9bde9dae104e53c597ed472b5940" -LINUX_VERSION = "6.8.0" +KBRANCH = "v6.10/base" +SRCREV_machine = "83a7eefedc9b56fe7bfeff13b6c7356688ffa670" +SRCREV_meta = "66aec68f0ba1d15ba0e9c19f1ec0d2b4a75c5333" +LINUX_VERSION = "6.10.0" SRC_URI += "file://gcs.patch"