aboutsummaryrefslogtreecommitdiff
path: root/sys/mips
diff options
context:
space:
mode:
authorJustin Hibbits <jhibbits@FreeBSD.org>2020-09-25 17:13:45 +0000
committerJustin Hibbits <jhibbits@FreeBSD.org>2020-09-25 17:13:45 +0000
commit6d5ca5199c509904a202dc2c4f9fba24471d8151 (patch)
treeaea1d51d13964f2fc542afa339b3f64a7f186c41 /sys/mips
parent01d0f9c0e40a44cff5e25842b72075cbaf0864de (diff)
downloadsrc-6d5ca5199c509904a202dc2c4f9fba24471d8151.tar.gz
src-6d5ca5199c509904a202dc2c4f9fba24471d8151.zip
Fix compat32 on mips64
Summary: Two bugs: * Elf32_Auxinfo is broken, using pointers in the union, which are 64-bits not 32. * freebsd32_sysarch() doesn't update the 'user local' register when handling MIPS_SET_TLS, leading to a NULL pointer dereference in the 32-bit application. Reviewed by: #mips, brooks MFC after: 1 week Sponsored by: Juniper Networks, Inc Differential Revision: https://reviews.freebsd.org/D26556
Notes
Notes: svn path=/head/; revision=366162
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/include/elf.h2
-rw-r--r--sys/mips/mips/freebsd32_machdep.c12
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/mips/include/elf.h b/sys/mips/include/elf.h
index d62b237fdac0..a0263bb3a975 100644
--- a/sys/mips/include/elf.h
+++ b/sys/mips/include/elf.h
@@ -105,8 +105,6 @@ typedef struct { /* Auxiliary vector entry on initial stack */
int a_type; /* Entry type. */
union {
int a_val; /* Integer value. */
- void *a_ptr; /* Address. */
- void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
} Elf32_Auxinfo;
diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c
index 1488edb9fb77..13fe21df99af 100644
--- a/sys/mips/mips/freebsd32_machdep.c
+++ b/sys/mips/mips/freebsd32_machdep.c
@@ -58,6 +58,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <machine/cpuinfo.h>
#include <machine/md_var.h>
#include <machine/reg.h>
#include <machine/sigframe.h>
@@ -455,6 +456,17 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap)
switch (uap->op) {
case MIPS_SET_TLS:
td->td_md.md_tls = (void *)(intptr_t)uap->parms;
+
+ /*
+ * If there is an user local register implementation (ULRI)
+ * update it as well. Add the TLS and TCB offsets so the
+ * value in this register is adjusted like in the case of the
+ * rdhwr trap() instruction handler.
+ */
+ if (cpuinfo.userlocal_reg == true) {
+ mips_wr_userlocal((unsigned long)(uap->parms +
+ td->td_md.md_tls_tcb_offset));
+ }
return (0);
case MIPS_GET_TLS:
tlsbase = (int32_t)(intptr_t)td->td_md.md_tls;