git: 77dfa7cfafb7 - stable/13 - amd64: Cleanups to setting TLS registers for Linux binaries.

John Baldwin jhb at FreeBSD.org
Mon Mar 29 22:11:58 UTC 2021


The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=77dfa7cfafb7afb6095f6f4ff30c4c22646b4989

commit 77dfa7cfafb7afb6095f6f4ff30c4c22646b4989
Author:     John Baldwin <jhb at FreeBSD.org>
AuthorDate: 2021-03-12 17:47:31 +0000
Commit:     John Baldwin <jhb at FreeBSD.org>
CommitDate: 2021-03-29 18:09:41 +0000

    amd64: Cleanups to setting TLS registers for Linux binaries.
    
    - Use update_pcb_bases() when updating FS or GS base addresses to
      permit use of FSBASE and GSBASE in Linux processes.  This also sets
      PCB_FULL_IRET.  linux32 was setting PCB_32BIT which should be a
      no-op (exec sets it).
    
    - Remove write-only variables to construct unused segment descriptors
      for linux32.
    
    Sponsored by:   Netflix
    
    (cherry picked from commit 704547ce1ca56e1123048cd152ed4e468d41d703)
---
 sys/amd64/linux/linux_machdep.c     |  5 +++--
 sys/amd64/linux32/linux32_machdep.c | 21 ++-------------------
 2 files changed, 5 insertions(+), 21 deletions(-)

diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index c2aebcf7df19..1a9d79b0c1ba 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -251,7 +251,7 @@ linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args)
 	switch (args->code) {
 	case LINUX_ARCH_SET_GS:
 		if (args->addr < VM_MAXUSER_ADDRESS) {
-			set_pcb_flags(pcb, PCB_FULL_IRET);
+			update_pcb_bases(pcb);
 			pcb->pcb_gsbase = args->addr;
 			td->td_frame->tf_gs = _ugssel;
 			error = 0;
@@ -260,7 +260,7 @@ linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args)
 		break;
 	case LINUX_ARCH_SET_FS:
 		if (args->addr < VM_MAXUSER_ADDRESS) {
-			set_pcb_flags(pcb, PCB_FULL_IRET);
+			update_pcb_bases(pcb);
 			pcb->pcb_fsbase = args->addr;
 			td->td_frame->tf_fs = _ufssel;
 			error = 0;
@@ -290,6 +290,7 @@ linux_set_cloned_tls(struct thread *td, void *desc)
 		return (EPERM);
 
 	pcb = td->td_pcb;
+	update_pcb_bases(pcb);
 	pcb->pcb_fsbase = (register_t)desc;
 	td->td_frame->tf_fs = _ufssel;
 
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 1883b18eeb60..fde180d74d73 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -394,11 +394,9 @@ linux_old_select(struct thread *td, struct linux_old_select_args *args)
 int
 linux_set_cloned_tls(struct thread *td, void *desc)
 {
-	struct user_segment_descriptor sd;
 	struct l_user_desc info;
 	struct pcb *pcb;
 	int error;
-	int a[2];
 
 	error = copyin(desc, &info, sizeof(struct l_user_desc));
 	if (error) {
@@ -410,14 +408,10 @@ linux_set_cloned_tls(struct thread *td, void *desc)
 		if (error)
 			linux_msg(td, "set_cloned_tls copyout info failed!");
 
-		a[0] = LINUX_LDT_entry_a(&info);
-		a[1] = LINUX_LDT_entry_b(&info);
-
-		memcpy(&sd, &a, sizeof(a));
 		pcb = td->td_pcb;
+		update_pcb_bases(pcb);
 		pcb->pcb_gsbase = (register_t)info.base_addr;
 		td->td_frame->tf_gs = GSEL(GUGS32_SEL, SEL_UPL);
-		set_pcb_flags(pcb, PCB_32BIT);
 	}
 
 	return (error);
@@ -668,9 +662,7 @@ linux_set_thread_area(struct thread *td,
     struct linux_set_thread_area_args *args)
 {
 	struct l_user_desc info;
-	struct user_segment_descriptor sd;
 	struct pcb *pcb;
-	int a[2];
 	int error;
 
 	error = copyin(args->desc, &info, sizeof(struct l_user_desc));
@@ -721,18 +713,9 @@ linux_set_thread_area(struct thread *td,
 	if (error)
 		return (error);
 
-	if (LINUX_LDT_empty(&info)) {
-		a[0] = 0;
-		a[1] = 0;
-	} else {
-		a[0] = LINUX_LDT_entry_a(&info);
-		a[1] = LINUX_LDT_entry_b(&info);
-	}
-
-	memcpy(&sd, &a, sizeof(a));
 	pcb = td->td_pcb;
+	update_pcb_bases(pcb);
 	pcb->pcb_gsbase = (register_t)info.base_addr;
-	set_pcb_flags(pcb, PCB_32BIT);
 	update_gdt_gsbase(td, info.base_addr);
 
 	return (0);


More information about the dev-commits-src-all mailing list