aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Dal'Ava Junior <alfredo@FreeBSD.org>2022-10-03 14:51:05 +0000
committerAlfredo Dal'Ava Junior <alfredo@FreeBSD.org>2022-10-06 00:14:19 +0000
commit05f9810b31973fb0d5f07a6eb9a12a22f81c38ad (patch)
tree7fd576505548ed56289ecc3d18a45777d2c08684
parent24c553621905d7c5ed70434377c141b1fbfc0969 (diff)
downloadsrc-05f9810b31973fb0d5f07a6eb9a12a22f81c38ad.tar.gz
src-05f9810b31973fb0d5f07a6eb9a12a22f81c38ad.zip
powerpc: cpuset: add local functions for copyin/copyout
Add local functions to workaround an instruction segment trap (panic) when the indirect functions copyin and copyout are called by an external loadable kernel module (i.e. pfsync, zfs and linuxulator). The crash was triggered by change 47a57144af25a7bd768b29272d50a36fdf2874ba, but kernel binary linked with LLD 9 works fine. LLVM bisect points that LLD behavior chaged after dc06b0bc9ad055d06535462d91bfc2a744b2f589. This is know to affect powerpc targets only and the final fix is still being discussed with the LLVM community. PR: 266730 Reviewed by: luporl, jhibbits (on IRC, previous version) MFC after: 2 days Sponsored by: Instituto de Pesquisas Eldorado (eldorado.org.br) Differential Revision: https://reviews.freebsd.org/D36234 (cherry picked from commit db79bf75ac9eb1b5678ccbaebb45fb88c0e0e1e3)
-rw-r--r--sys/kern/kern_cpuset.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 0670d9a046a7..affc48e78862 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -1743,10 +1743,42 @@ cpuset_check_capabilities(struct thread *td, cpulevel_t level, cpuwhich_t which,
return (0);
}
+#if defined(__powerpc__)
+/*
+ * TODO: At least powerpc64 and powerpc64le kernels panic with
+ * exception 0x480 (instruction segment exception) when copyin/copyout,
+ * are set as a function pointer in cpuset_copy_cb struct and called by
+ * an external module (like pfsync). Tip: copyin/copyout have an ifunc
+ * resolver function.
+ *
+ * Bisect of LLVM shows that the behavior changed on LLVM 10.0 with
+ * https://reviews.llvm.org/rGdc06b0bc9ad055d06535462d91bfc2a744b2f589
+ *
+ * This is a hack/workaround while problem is being discussed with LLVM
+ * community
+ */
+static int
+cpuset_copyin(const void *uaddr, void *kaddr, size_t len)
+{
+ return(copyin(uaddr, kaddr, len));
+}
+
+static int
+cpuset_copyout(const void *kaddr, void *uaddr, size_t len)
+{
+ return(copyout(kaddr, uaddr, len));
+}
+
static const struct cpuset_copy_cb copy_set = {
- .cpuset_copyin = copyin,
- .cpuset_copyout = copyout
+ .cpuset_copyin = cpuset_copyin,
+ .cpuset_copyout = cpuset_copyout
};
+#else
+static const struct cpuset_copy_cb copy_set = {
+ .cpuset_copyin = copyin,
+ .cpuset_copyout = copyout
+};
+#endif
#ifndef _SYS_SYSPROTO_H_
struct cpuset_args {