Deleted Added
full compact
linux_machdep.c (332315) linux_machdep.c (346812)
1/*-
2 * Copyright (c) 2000 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2000 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/11/sys/i386/linux/linux_machdep.c 332315 2018-04-09 01:07:47Z emaste $");
30__FBSDID("$FreeBSD: stable/11/sys/i386/linux/linux_machdep.c 346812 2019-04-28 09:53:08Z dchagin $");
31
32#include <sys/param.h>
33#include <sys/capsicum.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/imgact.h>
37#include <sys/lock.h>
38#include <sys/malloc.h>

--- 236 unchanged lines hidden (view full) ---

275 int a[2];
276
277 error = copyin(desc, &info, sizeof(struct l_user_desc));
278 if (error) {
279 printf(LMSG("copyin failed!"));
280 } else {
281 idx = info.entry_number;
282
31
32#include <sys/param.h>
33#include <sys/capsicum.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/imgact.h>
37#include <sys/lock.h>
38#include <sys/malloc.h>

--- 236 unchanged lines hidden (view full) ---

275 int a[2];
276
277 error = copyin(desc, &info, sizeof(struct l_user_desc));
278 if (error) {
279 printf(LMSG("copyin failed!"));
280 } else {
281 idx = info.entry_number;
282
283 /*
283 /*
284 * looks like we're getting the idx we returned
285 * in the set_thread_area() syscall
286 */
287 if (idx != 6 && idx != 3) {
288 printf(LMSG("resetting idx!"));
289 idx = 3;
290 }
291
292 /* this doesnt happen in practice */
293 if (idx == 6) {
284 * looks like we're getting the idx we returned
285 * in the set_thread_area() syscall
286 */
287 if (idx != 6 && idx != 3) {
288 printf(LMSG("resetting idx!"));
289 idx = 3;
290 }
291
292 /* this doesnt happen in practice */
293 if (idx == 6) {
294 /* we might copy out the entry_number as 3 */
295 info.entry_number = 3;
294 /* we might copy out the entry_number as 3 */
295 info.entry_number = 3;
296 error = copyout(&info, desc, sizeof(struct l_user_desc));
297 if (error)
298 printf(LMSG("copyout failed!"));
299 }
300
301 a[0] = LINUX_LDT_entry_a(&info);
302 a[1] = LINUX_LDT_entry_b(&info);
303

--- 327 unchanged lines hidden (view full) ---

631 struct segment_descriptor sd;
632
633 error = copyin(args->desc, &info, sizeof(struct l_user_desc));
634 if (error)
635 return (error);
636
637#ifdef DEBUG
638 if (ldebug(set_thread_area))
296 error = copyout(&info, desc, sizeof(struct l_user_desc));
297 if (error)
298 printf(LMSG("copyout failed!"));
299 }
300
301 a[0] = LINUX_LDT_entry_a(&info);
302 a[1] = LINUX_LDT_entry_b(&info);
303

--- 327 unchanged lines hidden (view full) ---

631 struct segment_descriptor sd;
632
633 error = copyin(args->desc, &info, sizeof(struct l_user_desc));
634 if (error)
635 return (error);
636
637#ifdef DEBUG
638 if (ldebug(set_thread_area))
639 printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, %i, %i, %i\n"),
639 printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, %i, %i, %i\n"),
640 info.entry_number,
640 info.entry_number,
641 info.base_addr,
642 info.limit,
643 info.seg_32bit,
641 info.base_addr,
642 info.limit,
643 info.seg_32bit,
644 info.contents,
644 info.contents,
645 info.read_exec_only,
646 info.limit_in_pages,
647 info.seg_not_present,
648 info.useable);
645 info.read_exec_only,
646 info.limit_in_pages,
647 info.seg_not_present,
648 info.useable);
649#endif
650
651 idx = info.entry_number;
649#endif
650
651 idx = info.entry_number;
652 /*
652 /*
653 * Semantics of linux version: every thread in the system has array of
653 * Semantics of linux version: every thread in the system has array of
654 * 3 tls descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown. This
654 * 3 tls descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown. This
655 * syscall loads one of the selected tls decriptors with a value and
656 * also loads GDT descriptors 6, 7 and 8 with the content of the
657 * per-thread descriptors.
658 *
655 * syscall loads one of the selected tls decriptors with a value and
656 * also loads GDT descriptors 6, 7 and 8 with the content of the
657 * per-thread descriptors.
658 *
659 * Semantics of fbsd version: I think we can ignore that linux has 3
659 * Semantics of fbsd version: I think we can ignore that linux has 3
660 * per-thread descriptors and use just the 1st one. The tls_array[]
661 * is used only in set/get-thread_area() syscalls and for loading the
662 * GDT descriptors. In fbsd we use just one GDT descriptor for TLS so
660 * per-thread descriptors and use just the 1st one. The tls_array[]
661 * is used only in set/get-thread_area() syscalls and for loading the
662 * GDT descriptors. In fbsd we use just one GDT descriptor for TLS so
663 * we will load just one.
663 * we will load just one.
664 *
665 * XXX: this doesn't work when a user space process tries to use more
666 * than 1 TLS segment. Comment in the linux sources says wine might do
667 * this.
668 */
669
664 *
665 * XXX: this doesn't work when a user space process tries to use more
666 * than 1 TLS segment. Comment in the linux sources says wine might do
667 * this.
668 */
669
670 /*
671 * we support just GLIBC TLS now
670 /*
671 * we support just GLIBC TLS now
672 * we should let 3 proceed as well because we use this segment so
673 * if code does two subsequent calls it should succeed
674 */
675 if (idx != 6 && idx != -1 && idx != 3)
676 return (EINVAL);
677
672 * we should let 3 proceed as well because we use this segment so
673 * if code does two subsequent calls it should succeed
674 */
675 if (idx != 6 && idx != -1 && idx != 3)
676 return (EINVAL);
677
678 /*
678 /*
679 * we have to copy out the GDT entry we use
680 * FreeBSD uses GDT entry #3 for storing %gs so load that
681 *
682 * XXX: what if a user space program doesn't check this value and tries
679 * we have to copy out the GDT entry we use
680 * FreeBSD uses GDT entry #3 for storing %gs so load that
681 *
682 * XXX: what if a user space program doesn't check this value and tries
683 * to use 6, 7 or 8?
683 * to use 6, 7 or 8?
684 */
685 idx = info.entry_number = 3;
686 error = copyout(&info, args->desc, sizeof(struct l_user_desc));
687 if (error)
688 return (error);
689
690 if (LINUX_LDT_empty(&info)) {
691 a[0] = 0;
692 a[1] = 0;
693 } else {
694 a[0] = LINUX_LDT_entry_a(&info);
695 a[1] = LINUX_LDT_entry_b(&info);
696 }
697
698 memcpy(&sd, &a, sizeof(a));
699#ifdef DEBUG
700 if (ldebug(set_thread_area))
684 */
685 idx = info.entry_number = 3;
686 error = copyout(&info, args->desc, sizeof(struct l_user_desc));
687 if (error)
688 return (error);
689
690 if (LINUX_LDT_empty(&info)) {
691 a[0] = 0;
692 a[1] = 0;
693 } else {
694 a[0] = LINUX_LDT_entry_a(&info);
695 a[1] = LINUX_LDT_entry_b(&info);
696 }
697
698 memcpy(&sd, &a, sizeof(a));
699#ifdef DEBUG
700 if (ldebug(set_thread_area))
701 printf("Segment created in set_thread_area: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
701 printf("Segment created in set_thread_area: lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, type: %i, dpl: %i, p: %i, xx: %i, def32: %i, gran: %i\n", sd.sd_lobase,
702 sd.sd_hibase,
703 sd.sd_lolimit,
704 sd.sd_hilimit,
705 sd.sd_type,
706 sd.sd_dpl,
707 sd.sd_p,
708 sd.sd_xx,
709 sd.sd_def32,
710 sd.sd_gran);
711#endif
712
713 /* this is taken from i386 version of cpu_set_user_tls() */
714 critical_enter();
715 /* set %gs */
716 td->td_pcb->pcb_gsd = sd;
717 PCPU_GET(fsgs_gdt)[1] = sd;
718 load_gs(GSEL(GUGS_SEL, SEL_UPL));
719 critical_exit();
702 sd.sd_hibase,
703 sd.sd_lolimit,
704 sd.sd_hilimit,
705 sd.sd_type,
706 sd.sd_dpl,
707 sd.sd_p,
708 sd.sd_xx,
709 sd.sd_def32,
710 sd.sd_gran);
711#endif
712
713 /* this is taken from i386 version of cpu_set_user_tls() */
714 critical_enter();
715 /* set %gs */
716 td->td_pcb->pcb_gsd = sd;
717 PCPU_GET(fsgs_gdt)[1] = sd;
718 load_gs(GSEL(GUGS_SEL, SEL_UPL));
719 critical_exit();
720
720
721 return (0);
722}
723
724int
725linux_get_thread_area(struct thread *td, struct linux_get_thread_area_args *args)
726{
721 return (0);
722}
723
724int
725linux_get_thread_area(struct thread *td, struct linux_get_thread_area_args *args)
726{
727
727
728 struct l_user_desc info;
729 int error;
730 int idx;
731 struct l_desc_struct desc;
732 struct segment_descriptor sd;
733
734#ifdef DEBUG
735 if (ldebug(get_thread_area))

--- 24 unchanged lines hidden (view full) ---

760 info.contents = LINUX_GET_CONTENTS(&desc);
761 info.read_exec_only = !LINUX_GET_WRITABLE(&desc);
762 info.limit_in_pages = LINUX_GET_LIMIT_PAGES(&desc);
763 info.seg_not_present = !LINUX_GET_PRESENT(&desc);
764 info.useable = LINUX_GET_USEABLE(&desc);
765
766 error = copyout(&info, args->desc, sizeof(struct l_user_desc));
767 if (error)
728 struct l_user_desc info;
729 int error;
730 int idx;
731 struct l_desc_struct desc;
732 struct segment_descriptor sd;
733
734#ifdef DEBUG
735 if (ldebug(get_thread_area))

--- 24 unchanged lines hidden (view full) ---

760 info.contents = LINUX_GET_CONTENTS(&desc);
761 info.read_exec_only = !LINUX_GET_WRITABLE(&desc);
762 info.limit_in_pages = LINUX_GET_LIMIT_PAGES(&desc);
763 info.seg_not_present = !LINUX_GET_PRESENT(&desc);
764 info.useable = LINUX_GET_USEABLE(&desc);
765
766 error = copyout(&info, args->desc, sizeof(struct l_user_desc));
767 if (error)
768 return (EFAULT);
768 return (EFAULT);
769
770 return (0);
771}
772
773/* XXX: this wont work with module - convert it */
774int
775linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
776{
777#ifdef P1003_1B_MQUEUE
769
770 return (0);
771}
772
773/* XXX: this wont work with module - convert it */
774int
775linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
776{
777#ifdef P1003_1B_MQUEUE
778 return sys_kmq_open(td, (struct kmq_open_args *) args);
778 return sys_kmq_open(td, (struct kmq_open_args *) args);
779#else
780 return (ENOSYS);
781#endif
782}
783
784int
785linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
786{
787#ifdef P1003_1B_MQUEUE
779#else
780 return (ENOSYS);
781#endif
782}
783
784int
785linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
786{
787#ifdef P1003_1B_MQUEUE
788 return sys_kmq_unlink(td, (struct kmq_unlink_args *) args);
788 return sys_kmq_unlink(td, (struct kmq_unlink_args *) args);
789#else
790 return (ENOSYS);
791#endif
792}
793
794int
795linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
796{
797#ifdef P1003_1B_MQUEUE
789#else
790 return (ENOSYS);
791#endif
792}
793
794int
795linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
796{
797#ifdef P1003_1B_MQUEUE
798 return sys_kmq_timedsend(td, (struct kmq_timedsend_args *) args);
798 return sys_kmq_timedsend(td, (struct kmq_timedsend_args *) args);
799#else
800 return (ENOSYS);
801#endif
802}
803
804int
805linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args *args)
806{
807#ifdef P1003_1B_MQUEUE
799#else
800 return (ENOSYS);
801#endif
802}
803
804int
805linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args *args)
806{
807#ifdef P1003_1B_MQUEUE
808 return sys_kmq_timedreceive(td, (struct kmq_timedreceive_args *) args);
808 return sys_kmq_timedreceive(td, (struct kmq_timedreceive_args *) args);
809#else
810 return (ENOSYS);
811#endif
812}
813
814int
815linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
816{
817#ifdef P1003_1B_MQUEUE
818 return sys_kmq_notify(td, (struct kmq_notify_args *) args);
819#else
820 return (ENOSYS);
821#endif
822}
823
824int
825linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
826{
827#ifdef P1003_1B_MQUEUE
809#else
810 return (ENOSYS);
811#endif
812}
813
814int
815linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
816{
817#ifdef P1003_1B_MQUEUE
818 return sys_kmq_notify(td, (struct kmq_notify_args *) args);
819#else
820 return (ENOSYS);
821#endif
822}
823
824int
825linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
826{
827#ifdef P1003_1B_MQUEUE
828 return sys_kmq_setattr(td, (struct kmq_setattr_args *) args);
828 return sys_kmq_setattr(td, (struct kmq_setattr_args *) args);
829#else
830 return (ENOSYS);
831#endif
832}
829#else
830 return (ENOSYS);
831#endif
832}