From afae3eed15d4ac84022f9050e946667a55c53d78 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 8 Feb 2016 16:59:52 +0000 Subject: [PATCH 01/17] Restore kgzldr on i386 only I previously disconnected kgzdr based on a misunderstanding. I'd still like to transition to supporting only the loader(8)-based boot path for handling compressed kernels, but that can follow the standard deprecation procedure. This reverts r291113. Requested by: dteske --- sys/boot/i386/Makefile | 4 ++++ targets/pseudo/userland/misc/Makefile.depend | 1 + 2 files changed, 5 insertions(+) diff --git a/sys/boot/i386/Makefile b/sys/boot/i386/Makefile index d812d54e701..0c3daed185e 100644 --- a/sys/boot/i386/Makefile +++ b/sys/boot/i386/Makefile @@ -8,6 +8,10 @@ SUBDIR= mbr pmbr boot0 boot0sio btx boot2 cdboot gptboot \ # special boot programs, 'self-extracting boot2+loader' SUBDIR+= pxeldr +.if ${MACHINE_CPUARCH} == "i386" +SUBDIR+= kgzldr +.endif + .if ${MK_ZFS} != "no" SUBDIR+= zfsboot gptzfsboot zfsloader .endif diff --git a/targets/pseudo/userland/misc/Makefile.depend b/targets/pseudo/userland/misc/Makefile.depend index 6d46af1f724..c186f6d4681 100644 --- a/targets/pseudo/userland/misc/Makefile.depend +++ b/targets/pseudo/userland/misc/Makefile.depend @@ -40,6 +40,7 @@ DIRDEPS.x86sys= \ sys/boot/i386/btx/lib \ sys/boot/i386/cdboot \ sys/boot/i386/gptboot \ + sys/boot/i386/kgzldr \ sys/boot/i386/libfirewire \ sys/boot/i386/libi386 \ sys/boot/i386/loader \ From 0df549cba9786d4e805ee578d764af525df934d5 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Mon, 8 Feb 2016 17:30:17 +0000 Subject: [PATCH 02/17] Fix copy/paste error; s/ngX/eXb/ --- share/examples/jails/jib | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 540df097176..b7e1b0b0d8d 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -276,14 +276,14 @@ jib_addm() ifconfig "e${i}a_$name" ether $eiface_devid_a > /dev/null 2>&1 ifconfig "e${i}b_$name" ether $eiface_devid_b > /dev/null 2>&1 - i=$(( $i + 1 )) # on to next ng{i}_name + i=$(( $i + 1 )) # on to next e{i}b_name done # for iface } jib_show_usage="show" jib_show_descr="List possible NAME values for \`show NAME'" jib_show1_usage="show NAME" -jib_show1_descr="Lists ng0_NAME [ng1_NAME ...]" +jib_show1_descr="Lists e0b_NAME [e1b_NAME ...]" jib_show2_usage="show [NAME]" jib_show() { From 626ddc5125b8dbe81afba1201ad8e0f20005eec2 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Mon, 8 Feb 2016 17:36:46 +0000 Subject: [PATCH 03/17] Provide additional information on overall purpose --- share/examples/jails/jib | 6 +++++- share/examples/jails/jng | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index b7e1b0b0d8d..e48f5c49fda 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -33,7 +33,11 @@ ############################################################ INFORMATION # # Use this tool with jail.conf(5) (or rc.conf(5) ``legacy'' configuration) to -# manage `vnet' interfaces. In jail.conf(5) format: +# manage `vnet' interfaces for jails. Designed to automate the creation of vnet +# interface(s) during jail `prestart' and destroy said interface(s) during jail +# `poststop'. +# +# In jail.conf(5) format: # # ### BEGIN EXCERPT ### # diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 605db90d4dd..bb63cd675bd 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -33,7 +33,11 @@ ############################################################ INFORMATION # # Use this tool with jail.conf(5) (or rc.conf(5) ``legacy'' configuration) to -# manage `vnet' interfaces. In jail.conf(5) format: +# manage `vnet' interfaces for jails. Designed to automate the creation of vnet +# interface(s) during jail `prestart' and destroy said interface(s) during jail +# `poststop'. +# +# In jail.conf(5) format: # # ### BEGIN EXCERPT ### # From 43a45064a0975acef2f95bd0c41eafdcfa6cbafc Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Mon, 8 Feb 2016 17:47:36 +0000 Subject: [PATCH 04/17] Adjust MAC allocation algo to support layering --- share/examples/jails/jib | 11 +++++++++-- share/examples/jails/jng | 5 ++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index e48f5c49fda..890c1682e9c 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -267,8 +267,15 @@ jib_addm() 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac - eiface_devid_a=2:$quad$eiface_devid_a - eiface_devid_b=6:$quad$eiface_devid_b + case "$iface_devid" in + ?2:*|?6:*) + eiface_devid_a=a:$quad$eiface_devid_a + eiface_devid_b=e:$quad$eiface_devid_b + ;; + *) + eiface_devid_a=2:$quad$eiface_devid_a + eiface_devid_b=6:$quad$eiface_devid_b + esac num=$(( $num >> 4 )) quad=$(( $num & 15 )) case "$quad" in diff --git a/share/examples/jails/jng b/share/examples/jails/jng index bb63cd675bd..0d9132e23ff 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -297,7 +297,10 @@ jng_bridge() 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac - eiface_devid=2:$quad$eiface_devid + case "$iface_devid" in + ?2:*) eiface_devid=a:$quad$eiface_devid ;; + *) eiface_devid=2:$quad$eiface_devid + esac num=$(( $num >> 4 )) quad=$(( $num & 15 )) case "$quad" in From bd43f0691c95603818dd7df72f24ee318bb0f29f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 8 Feb 2016 19:24:13 +0000 Subject: [PATCH 05/17] If libthr.so is dlopened without RTLD_GLOBAL flag, the libthr symbols do not participate in the global symbols namespace, but rtld locks are still replaced and functions are interposed. In particular, __pthread_map_stacks_exec is resolved to the libc version. If a library is loaded later, which requires adjustment of the stack protection mode, rtld calls into libc __pthread_map_stacks_exec due to the symbols scope. The libc version might recurse into binder and recursively acquire rtld bind lock, causing the hang. Make libc __pthread_map_stacks_exec() interposed, which synchronizes rtld locks and version of the stack exec hook when libthr loaded, regardless of the symbol scope control or symbol resolution order. The __pthread_map_stacks_exec() symbol is removed from the private version in libthr since libc symbol now operates correctly in presence of libthr. Reported and tested by: markj Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- lib/libc/gen/elf_utils.c | 11 +++++++++-- lib/libc/include/libc_private.h | 2 ++ lib/libc/sys/interposing_table.c | 1 + lib/libthr/pthread.map | 2 -- lib/libthr/thread/thr_private.h | 2 ++ lib/libthr/thread/thr_stack.c | 3 +-- lib/libthr/thread/thr_syscalls.c | 1 + 7 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/libc/gen/elf_utils.c b/lib/libc/gen/elf_utils.c index 069f62e53b3..80ab013849b 100644 --- a/lib/libc/gen/elf_utils.c +++ b/lib/libc/gen/elf_utils.c @@ -32,6 +32,7 @@ #include #include #include +#include "libc_private.h" int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __pthread_map_stacks_exec(void); @@ -54,9 +55,8 @@ __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) return (i != phdr_info->dlpi_phnum); } -#pragma weak __pthread_map_stacks_exec void -__pthread_map_stacks_exec(void) +__libc_map_stacks_exec(void) { int mib[2]; struct rlimit rlim; @@ -75,3 +75,10 @@ __pthread_map_stacks_exec(void) rlim.rlim_cur, _rtld_get_stack_prot()); } +#pragma weak __pthread_map_stacks_exec +void +__pthread_map_stacks_exec(void) +{ + + ((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); +} diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 5caf9a36255..554f3a25d5e 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -224,6 +224,7 @@ enum { INTERPOS_kevent, INTERPOS_wait6, INTERPOS_ppoll, + INTERPOS_map_stacks_exec, INTERPOS_MAX }; @@ -381,6 +382,7 @@ int _elf_aux_info(int aux, void *buf, int buflen); struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); +void __libc_map_stacks_exec(); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); diff --git a/lib/libc/sys/interposing_table.c b/lib/libc/sys/interposing_table.c index 08dfbb15b15..75bb2804b75 100644 --- a/lib/libc/sys/interposing_table.c +++ b/lib/libc/sys/interposing_table.c @@ -78,6 +78,7 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = { SLOT(kevent, __sys_kevent), SLOT(wait6, __sys_wait6), SLOT(ppoll, __sys_ppoll), + SLOT(map_stacks_exec, __libc_map_stacks_exec), }; #undef SLOT diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index 0903989a2d2..9fb72ebbad8 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -295,8 +295,6 @@ FBSDprivate_1.0 { _thread_size_key; _thread_state_running; _thread_state_zoombie; - - __pthread_map_stacks_exec; }; FBSD_1.1 { diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 0ba123d6571..6020e074c4d 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -927,6 +927,8 @@ int __thr_sigwait(const sigset_t *set, int *sig); int __thr_sigwaitinfo(const sigset_t *set, siginfo_t *info); int __thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp); +void __thr_map_stacks_exec(void); + struct _spinlock; void __thr_spinunlock(struct _spinlock *lck); void __thr_spinlock(struct _spinlock *lck); diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c index e5d149eedea..74e1329aedf 100644 --- a/lib/libthr/thread/thr_stack.c +++ b/lib/libthr/thread/thr_stack.c @@ -161,9 +161,8 @@ singlethread_map_stacks_exec(void) rlim.rlim_cur, _rtld_get_stack_prot()); } -void __pthread_map_stacks_exec(void); void -__pthread_map_stacks_exec(void) +__thr_map_stacks_exec(void) { struct pthread *curthread, *thrd; struct stack *st; diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index 7c05697ad72..712249b1e57 100644 --- a/lib/libthr/thread/thr_syscalls.c +++ b/lib/libthr/thread/thr_syscalls.c @@ -652,6 +652,7 @@ __thr_interpose_libc(void) SLOT(kevent); SLOT(wait6); SLOT(ppoll); + SLOT(map_stacks_exec); #undef SLOT *(__libc_interposing_slot( INTERPOS__pthread_mutex_init_calloc_cb)) = From 1e9783008363f2252c5521b92aed36fe463c72f5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 8 Feb 2016 19:34:17 +0000 Subject: [PATCH 06/17] Implement -P for boot loader. It's a bit easier to implement here than in boot1, like is normally done. When a keyboard appears in the UEFI device tree, assume -D -h, just like on a BIOS boot. # It is unclear if an ACPI keyboard appearing in the tree means there's # a real keyboard or not. A USB keyboard doesn't seem to appear unless # it is really there. Differential Revision: https://reviews.freebsd.org/D5223 --- sys/boot/efi/loader/main.c | 96 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index 4c3bc7aa3ef..361d3bbd473 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -66,6 +66,7 @@ EFI_GUID hoblist = HOB_LIST_TABLE_GUID; EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; EFI_GUID fdtdtb = FDT_TABLE_GUID; +EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL; #ifdef EFI_ZFS_BOOT static void efi_zfs_probe(void); @@ -94,6 +95,88 @@ cp16to8(const CHAR16 *src, char *dst, size_t len) dst[i] = (char)src[i]; } +static int +has_keyboard(void) +{ + EFI_STATUS status; + EFI_DEVICE_PATH *path; + EFI_HANDLE *hin, *hin_end, *walker; + UINTN sz; + int retval = 0; + + /* + * Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and + * do the typical dance to get the right sized buffer. + */ + sz = 0; + hin = NULL; + status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, 0); + if (status == EFI_BUFFER_TOO_SMALL) { + hin = (EFI_HANDLE *)malloc(sz); + status = BS->LocateHandle(ByProtocol, &inputid, 0, &sz, + hin); + if (EFI_ERROR(status)) + free(hin); + } + if (EFI_ERROR(status)) + return retval; + + /* + * Look at each of the handles. If it supports the device path protocol, + * use it to get the device path for this handle. Then see if that + * device path matches either the USB device path for keyboards or the + * legacy device path for keyboards. + */ + hin_end = &hin[sz / sizeof(*hin)]; + for (walker = hin; walker < hin_end; walker++) { + status = BS->HandleProtocol(*walker, &devid, (VOID **)&path); + if (EFI_ERROR(status)) + continue; + + while (!IsDevicePathEnd(path)) { + /* + * Check for the ACPI keyboard node. All PNP3xx nodes + * are keyboards of different flavors. Note: It is + * unclear of there's always a keyboard node when + * there's a keyboard controller, or if there's only one + * when a keyboard is detected at boot. + */ + if (DevicePathType(path) == ACPI_DEVICE_PATH && + (DevicePathSubType(path) == ACPI_DP || + DevicePathSubType(path) == ACPI_EXTENDED_DP)) { + ACPI_HID_DEVICE_PATH *acpi; + + acpi = (ACPI_HID_DEVICE_PATH *)(void *)path; + if ((EISA_ID_TO_NUM(acpi->HID) & 0xff00) == 0x300 && + (acpi->HID & 0xffff) == PNP_EISA_ID_CONST) { + retval = 1; + goto out; + } + /* + * Check for USB keyboard node, if present. Unlike a + * PS/2 keyboard, these definitely only appear when + * connected to the system. + */ + } else if (DevicePathType(path) == MESSAGING_DEVICE_PATH && + DevicePathSubType(path) == MSG_USB_CLASS_DP) { + USB_CLASS_DEVICE_PATH *usb; + + usb = (USB_CLASS_DEVICE_PATH *)(void *)path; + if (usb->DeviceClass == 3 && /* HID */ + usb->DeviceSubClass == 1 && /* Boot devices */ + usb->DeviceProtocol == 1) { /* Boot keyboards */ + retval = 1; + goto out; + } + } + path = NextDevicePathNode(path); + } + } +out: + free(hin); + return retval; +} + EFI_STATUS main(int argc, CHAR16 *argv[]) { @@ -104,6 +187,7 @@ main(int argc, CHAR16 *argv[]) struct devsw *dev; uint64_t pool_guid; UINTN k; + int has_kbd; archsw.arch_autoload = efi_autoload; archsw.arch_getdev = efi_getdev; @@ -115,6 +199,8 @@ main(int argc, CHAR16 *argv[]) archsw.arch_zfs_probe = efi_zfs_probe; #endif + has_kbd = has_keyboard(); + /* * XXX Chicken-and-egg problem; we want to have console output * early, but some console attributes may depend on reading from @@ -150,15 +236,19 @@ main(int argc, CHAR16 *argv[]) case 'D': howto |= RB_MULTIPLE; break; - case 'm': - howto |= RB_MUTE; - break; case 'h': howto |= RB_SERIAL; break; + case 'm': + howto |= RB_MUTE; + break; case 'p': howto |= RB_PAUSE; break; + case 'P': + if (!has_kbd) + howto |= RB_SERIAL | RB_MULTIPLE; + break; case 'r': howto |= RB_DFLTROOT; break; From 9868276d3be84183a41628bc9eca52b284bb5a9b Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 8 Feb 2016 19:45:55 +0000 Subject: [PATCH 07/17] ficl: Replace rand(3) with random(3). While the later is a better random generator than the former, the main reason of the change is that random() has a better chance to work with libstand(3). At this time we don't include random number generators in bootforth so this has no effect. --- sys/boot/ficl/words.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/ficl/words.c b/sys/boot/ficl/words.c index c32e352b733..5537b13a5a9 100644 --- a/sys/boot/ficl/words.c +++ b/sys/boot/ficl/words.c @@ -4822,7 +4822,7 @@ WORDKIND ficlWordClassify(FICL_WORD *pFW) **************************************************************************/ static void ficlRandom(FICL_VM *pVM) { - PUSHINT(rand()); + PUSHINT(random()); } @@ -4832,7 +4832,7 @@ static void ficlRandom(FICL_VM *pVM) **************************************************************************/ static void ficlSeedRandom(FICL_VM *pVM) { - srand(POPINT()); + srandom(POPUNS()); } #endif From 595b2caa3ff00411f1fed0b9bc413267c1399775 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Mon, 8 Feb 2016 20:03:14 +0000 Subject: [PATCH 08/17] ficl: Replace rand(3) with random(3). Be a little more consistent with random(3) and push an unsigned value. Again, this has no effect as this code doesn't get compiled for the boot code. --- sys/boot/ficl/words.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/ficl/words.c b/sys/boot/ficl/words.c index 5537b13a5a9..0e8f2c4c2fc 100644 --- a/sys/boot/ficl/words.c +++ b/sys/boot/ficl/words.c @@ -4822,7 +4822,7 @@ WORDKIND ficlWordClassify(FICL_WORD *pFW) **************************************************************************/ static void ficlRandom(FICL_VM *pVM) { - PUSHINT(random()); + PUSHUNS(random()); } From bbc7e0d6904e5b32adfc11b2be952ed925ed5ea7 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 8 Feb 2016 20:57:12 +0000 Subject: [PATCH 09/17] kmod.mk: Support a beforebuild target such as bsd.prog.mk has. Sponsored by: EMC / Isilon Storage Division --- sys/conf/kmod.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 819a955fe69..89f37ffe4e4 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -249,7 +249,8 @@ _ILINKS+=x86 .endif CLEANFILES+=${_ILINKS} -all: objwarn ${PROG} +all: beforebuild .WAIT ${PROG} +beforebuild: objwarn beforedepend: ${_ILINKS} From 68d969232c49a7069e2bc137d1e28215277ffa25 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 8 Feb 2016 20:58:52 +0000 Subject: [PATCH 10/17] kmod.mk: Ensure ILINKS are created before building. This allows skipping 'make depend' or running 'make clean all' without getting a flip-flopping dependency due to the exists() just below. Otherwise an error is encountered, such as: fatal error: 'machine/endian.h' file not found. Sponsored by: EMC / Isilon Storage Division --- sys/conf/kmod.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 89f37ffe4e4..61e4ec56d18 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -253,6 +253,7 @@ all: beforebuild .WAIT ${PROG} beforebuild: objwarn beforedepend: ${_ILINKS} +beforebuild: ${_ILINKS} # Ensure that the links exist without depending on it when it exists which # causes all the modules to be rebuilt when the directory pointed to changes. From c5dd49afeca7a9e11e868d9bc2a3589983ac7110 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 8 Feb 2016 22:02:56 +0000 Subject: [PATCH 11/17] Fix the gcc build after r295407. X-MFC-With: r295407 --- lib/libc/include/libc_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 554f3a25d5e..8ee77d932e3 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -382,7 +382,7 @@ int _elf_aux_info(int aux, void *buf, int buflen); struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); -void __libc_map_stacks_exec(); +void __libc_map_stacks_exec(void); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); From 07b1ab582bbc22f48f66ff1da9978cb46e4cace1 Mon Sep 17 00:00:00 2001 From: "Kenneth D. Merry" Date: Mon, 8 Feb 2016 22:13:08 +0000 Subject: [PATCH 12/17] Fix the SCSI Extended INQUIRY probe case when an error is returned and a retry is scheduled. Instead of leaving the device queue frozen, unfreeze the device queue so that the retry can happen. Sponsored by: Spectra Logic MFC after: 3 days --- sys/cam/scsi/scsi_xpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index 7cffd67955f..c0cc310dc5e 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -1518,7 +1518,7 @@ out: } else if (cam_periph_error(done_ccb, 0, SF_RETRY_UA, &softc->saved_ccb) == ERESTART) { - return; + goto outr; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge the queue */ xpt_release_devq(done_ccb->ccb_h.path, /*count*/1, From 6270fa5f72e7f0452b43622b67356e7886e99ec4 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 8 Feb 2016 23:06:27 +0000 Subject: [PATCH 13/17] Mark proc0 as a kernel process via the P_KTHREAD flag. All other kernel processes have this flag set and all threads in proc0 (including thread0) have the similar TDP_KTHREAD flag set. PR: 204999 Submitted by: Oliver Pinter @ HardenedBSD Reviewed by: kib MFC after: 1 week --- sys/kern/init_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index d5f8f4ddbe3..d157d24055a 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -479,7 +479,7 @@ proc0_init(void *dummy __unused) session0.s_leader = p; p->p_sysent = &null_sysvec; - p->p_flag = P_SYSTEM | P_INMEM; + p->p_flag = P_SYSTEM | P_INMEM | P_KTHREAD; p->p_flag2 = 0; p->p_state = PRS_NORMAL; knlist_init_mtx(&p->p_klist, &p->p_mtx); From fb1f4582ffa89f8833d1a51101cf3a42193b2690 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 8 Feb 2016 23:11:23 +0000 Subject: [PATCH 14/17] Call kthread_exit() rather than kproc_exit() for a premature kthread exit. Kernel threads (and processes) are supposed to call kthread_exit() (or kproc_exit()) to terminate. However, the kernel includes a fallback in fork_exit() to force a kthread exit if a kernel thread's "main" routine returns. This fallback was added back when the kernel only had processes and was not updated to call kthread_exit() instead of kproc_exit() when threads were added to the kernel. This mistake was particular exciting when the errant thread belonged to proc0. Due to the missing P_KTHREAD flag the fallback did not kick in and instead tried to return to userland via whatever garbage was in the trapframe. With P_KTHREAD set it tried to terminate proc0 resulting in other amusements. PR: 204999 MFC after: 1 week --- sys/kern/kern_fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 9abe08c037c..34af264fd70 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1040,7 +1040,7 @@ fork_exit(void (*callout)(void *, struct trapframe *), void *arg, if (p->p_flag & P_KTHREAD) { printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n", td->td_name, p->p_pid); - kproc_exit(0); + kthread_exit(); } mtx_assert(&Giant, MA_NOTOWNED); From aeffd7b7ea3e5e62eb3b298786294bf8370645e6 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 9 Feb 2016 00:01:43 +0000 Subject: [PATCH 15/17] Ensure the bss is aligned to a 4-byte address as we use 4-byte aligned stores to clear it. While here reduce the alignment of the data from 4k to 16 byte aligned. This should be more than enough, without wasting too much space. Sponsored by: ABT Systems Ltd --- sys/boot/efi/loader/arch/arm/ldscript.arm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/boot/efi/loader/arch/arm/ldscript.arm b/sys/boot/efi/loader/arch/arm/ldscript.arm index 4dcf302b221..8b4a6dc64b3 100644 --- a/sys/boot/efi/loader/arch/arm/ldscript.arm +++ b/sys/boot/efi/loader/arch/arm/ldscript.arm @@ -15,7 +15,7 @@ SECTIONS } =0 _etext = .; PROVIDE (etext = .); - . = ALIGN(4096); + . = ALIGN(16); .data : { *(.data *.data.*) @@ -24,6 +24,7 @@ SECTIONS *(.rodata.*) CONSTRUCTORS + . = ALIGN(4); PROVIDE (__bss_start = .); *(.sbss) *(.scommon) @@ -31,6 +32,7 @@ SECTIONS *(.dynbss) *(.bss) *(COMMON) + . = ALIGN(4); PROVIDE (__bss_end = .); } /* We want the small data sections together, so single-instruction offsets From 214d45050113f41cd019581327924e55c5a6b850 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 9 Feb 2016 00:15:41 +0000 Subject: [PATCH 16/17] Stop clang from generating movt/movw sequences. These don't get relocated so will access data from an unrelocated address. This is only needed for self relocating code on ARMv7, however this is true for both ubldr and loader.efi, the only two loaders we support on ARMv7. While here also force the fpu to be none as is done in libstand. Sponsored by: ABT Systems Ltd --- sys/boot/Makefile.inc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/boot/Makefile.inc b/sys/boot/Makefile.inc index 3545446762d..17088d782da 100644 --- a/sys/boot/Makefile.inc +++ b/sys/boot/Makefile.inc @@ -1,3 +1,11 @@ # $FreeBSD$ SSP_CFLAGS= + +.if ${MACHINE_CPUARCH} == "arm" +# Do not generate movt/movw, because the relocation fixup for them does not +# translate to the -Bsymbolic -pie format required by self_reloc() in loader(8). +# Also, the fpu is not available in a standalone environment. +CFLAGS.clang+= -mllvm -arm-use-movt=0 +CFLAGS.clang+= -mfpu=none +.endif From 78a38b8f05f9dbb70ca12e0223ef52984f3aa65f Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Tue, 9 Feb 2016 01:41:03 +0000 Subject: [PATCH 17/17] Adjust MAC algo to support interface branching --- share/examples/jails/jib | 44 +++++++++++++++++++++++++++++----------- share/examples/jails/jng | 39 ++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/share/examples/jails/jib b/share/examples/jails/jib index 890c1682e9c..237db12b164 100755 --- a/share/examples/jails/jib +++ b/share/examples/jails/jib @@ -227,32 +227,37 @@ jib_addm() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - # The formula I'm using is ``SP:SS:SI:II:II:II'' where: - # + S denotes 16 bits of sum(1) data, split because P (below). + # The formula I'm using is ``NP:SS:SS:II:II:II'' where: + # + N denotes 4 bits used as a counter to support branching + # each parent interface up to 15 times under the same jail + # name (see S below). # + P denotes the special nibble whose value, if one of # 2, 6, A, or E (but usually 2) denotes a privately # administered MAC address (while remaining routable). + # + S denotes 16 bits, the sum(1) value of the jail name. # + I denotes bits that are inherited from parent interface. # # The S bits are a CRC-16 checksum of NAME, allowing the jail # to change the epair(4) generation order without affecting the - # MAC address. Meanwhile, if the jail NAME changes (e.g., it - # was duplicated and given a new name with no other changes), - # the underlying network interface changes, or the jail is - # moved to another host, the MAC address will be recalculated - # to a new, similarly unique value preventing conflict. + # MAC address. Meanwhile, if... + # + the jail NAME changes (e.g., it was duplicated and given + # a new name with no other changes) + # + the underlying network interface changes + # + the jail is moved to another host + # the MAC address will be recalculated to a new, similarly + # unique value preventing conflict. # iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' ) - eiface_devid_a=${iface_devid#??:??:?} - eiface_devid_b=${iface_devid#??:??:?} + eiface_devid_a=${iface_devid#??:??:??} + eiface_devid_b=${iface_devid#??:??:??} num=$( set -- `echo -n $name | sum` && echo $1 ) quad=$(( $num & 15 )) case "$quad" in 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac - eiface_devid_a=:$quad$eiface_devid_a - eiface_devid_b=:$quad$eiface_devid_b + eiface_devid_a=$quad$eiface_devid_a + eiface_devid_b=$quad$eiface_devid_b num=$(( $num >> 4 )) quad=$(( $num & 15 )) case "$quad" in @@ -267,6 +272,14 @@ jib_addm() 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac + eiface_devid_a=$quad:$eiface_devid_a + eiface_devid_b=$quad:$eiface_devid_b + num=$(( $num >> 4 )) + quad=$(( $num & 15 )) + case "$quad" in + 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; + 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; + esac case "$iface_devid" in ?2:*|?6:*) eiface_devid_a=a:$quad$eiface_devid_a @@ -276,7 +289,14 @@ jib_addm() eiface_devid_a=2:$quad$eiface_devid_a eiface_devid_b=6:$quad$eiface_devid_b esac - num=$(( $num >> 4 )) + eval num=\$_${iface}_num + if [ "$num" ]; then + num=$(( $num + 1 )) + eval _${iface}_num=$num + else + num=0 + local _${iface}_num=$num + fi quad=$(( $num & 15 )) case "$quad" in 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 0d9132e23ff..7a9710f9fb2 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -260,30 +260,35 @@ jng_bridge() # 6. Set the MAC address of the new interface using a sensible # algorithm to prevent conflicts on the network. # - # The formula I'm using is ``SP:SS:SI:II:II:II'' where: - # + S denotes 16 bits of sum(1) data, split because P (below). + # The formula I'm using is ``NP:SS:SS:II:II:II'' where: + # + N denotes 4 bits used as a counter to support branching + # each parent interface up to 15 times under the same jail + # name (see S below). # + P denotes the special nibble whose value, if one of # 2, 6, A, or E (but usually 2) denotes a privately # administered MAC address (while remaining routable). + # + S denotes 16 bits, the sum(1) value of the jail name. # + I denotes bits that are inherited from parent interface. # # The S bits are a CRC-16 checksum of NAME, allowing the jail # to change link numbers in ng_bridge(4) without affecting the - # MAC address. Meanwhile, if the jail NAME changes (e.g., it - # was duplicated and given a new name with no other changes), - # the underlying network interface changes, or the jail is - # moved to another host, the MAC address will be recalculated - # to a new, similarly unique value preventing conflict. + # MAC address. Meanwhile, if... + # + the jail NAME changes (e.g., it was duplicated and given + # a new name with no other changes) + # + the underlying network interface changes + # + the jail is moved to another host + # the MAC address will be recalculated to a new, similarly + # unique value preventing conflict. # iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' ) - eiface_devid=${iface_devid#??:??:?} + eiface_devid=${iface_devid#??:??:??} num=$( set -- `echo -n $name | sum` && echo $1 ) quad=$(( $num & 15 )) case "$quad" in 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac - eiface_devid=:$quad$eiface_devid + eiface_devid=$quad$eiface_devid num=$(( $num >> 4 )) quad=$(( $num & 15 )) case "$quad" in @@ -297,11 +302,25 @@ jng_bridge() 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; esac + eiface_devid=$quad:$eiface_devid + num=$(( $num >> 4 )) + quad=$(( $num & 15 )) + case "$quad" in + 10) quad=a ;; 11) quad=b ;; 12) quad=c ;; + 13) quad=d ;; 14) quad=e ;; 15) quad=f ;; + esac case "$iface_devid" in ?2:*) eiface_devid=a:$quad$eiface_devid ;; *) eiface_devid=2:$quad$eiface_devid esac - num=$(( $num >> 4 )) + eval num=\$_${iface}_num + if [ "$num" ]; then + num=$(( $num + 1 )) + eval _${iface}_num=$num + else + num=0 + local _${iface}_num=$num + fi quad=$(( $num & 15 )) case "$quad" in 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;