diff options
Diffstat (limited to 'sys')
50 files changed, 534 insertions, 327 deletions
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 5f8197b..a3d82e8 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -107,6 +107,13 @@ clflush(u_long addr) } static __inline void +clflushopt(u_long addr) +{ + + __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); +} + +static __inline void clts(void) { @@ -154,6 +161,14 @@ ffsl(long mask) return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1); } +#define HAVE_INLINE_FFSLL + +static __inline int +ffsll(long long mask) +{ + return (ffsl((long)mask)); +} + #define HAVE_INLINE_FLS static __inline int @@ -170,6 +185,14 @@ flsl(long mask) return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1); } +#define HAVE_INLINE_FLSLL + +static __inline int +flsll(long long mask) +{ + return (flsl((long)mask)); +} + #endif /* _KERNEL */ static __inline void diff --git a/sys/boot/pc98/boot2/Makefile b/sys/boot/pc98/boot2/Makefile index aa399a0..8d6b20b 100644 --- a/sys/boot/pc98/boot2/Makefile +++ b/sys/boot/pc98/boot2/Makefile @@ -93,6 +93,7 @@ boot2.out: ${BTXCRT} boot2.o sio.o ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} boot2.o: boot2.s + ${CC} ${ACFLAGS} -c boot2.s SRCS= boot2.c boot2.h diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index ea04eef..cde8489 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -929,6 +929,11 @@ ctl_isc_announce_mode(struct ctl_lun *lun, uint32_t initidx, } if (i == CTL_NUM_MODE_PAGES) return; + + /* Don't try to replicate pages not present on this device. */ + if (lun->mode_pages.index[i].page_data == NULL) + return; + bzero(&msg.mode, sizeof(msg.mode)); msg.hdr.msg_type = CTL_MSG_MODE_SYNC; msg.hdr.nexus.targ_port = initidx / CTL_MAX_INIT_PER_PORT; diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c index 25c745b..27c5ad7 100644 --- a/sys/cam/ctl/scsi_ctl.c +++ b/sys/cam/ctl/scsi_ctl.c @@ -1879,7 +1879,7 @@ ctlfe_lun_disable(void *arg, int lun_id) path = lun_softc->periph->path; - if ((xpt_path_target_id(path) == 0) + if ((xpt_path_target_id(path) == softc->target_id) && (xpt_path_lun_id(path) == lun_id)) { break; } diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 0fa5a11..90c917c 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -219,6 +219,7 @@ struct da_softc { uint32_t unmap_max_ranges; uint32_t unmap_max_lba; /* Max LBAs in UNMAP req */ uint64_t ws_max_blks; + da_delete_methods delete_method_pref; da_delete_methods delete_method; da_delete_func_t *delete_func; struct disk_params params; @@ -1805,7 +1806,7 @@ dasysctlinit(void *context, int pending) * the fly. */ SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), - OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW, + OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RWTUN, softc, 0, dadeletemethodsysctl, "A", "BIO_DELETE execution method"); SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), @@ -1916,7 +1917,6 @@ static void dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method) { - softc->delete_method = delete_method; softc->disk->d_delmaxsize = dadeletemaxsize(softc, delete_method); softc->delete_func = da_delete_functions[delete_method]; @@ -1969,25 +1969,17 @@ daprobedone(struct cam_periph *periph, union ccb *ccb) snprintf(buf, sizeof(buf), "Delete methods: <"); sep = 0; - for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) { - if (softc->delete_available & (1 << i)) { - if (sep) { - strlcat(buf, ",", sizeof(buf)); - } else { - sep = 1; - } - strlcat(buf, da_delete_method_names[i], - sizeof(buf)); - if (i == softc->delete_method) { - strlcat(buf, "(*)", sizeof(buf)); - } - } - } - if (sep == 0) { - if (softc->delete_method == DA_DELETE_NONE) - strlcat(buf, "NONE(*)", sizeof(buf)); - else - strlcat(buf, "DISABLED(*)", sizeof(buf)); + for (i = 0; i <= DA_DELETE_MAX; i++) { + if ((softc->delete_available & (1 << i)) == 0 && + i != softc->delete_method) + continue; + if (sep) + strlcat(buf, ",", sizeof(buf)); + strlcat(buf, da_delete_method_names[i], + sizeof(buf)); + if (i == softc->delete_method) + strlcat(buf, "(*)", sizeof(buf)); + sep = 1; } strlcat(buf, ">", sizeof(buf)); printf("%s%d: %s\n", periph->periph_name, @@ -2017,21 +2009,28 @@ daprobedone(struct cam_periph *periph, union ccb *ccb) static void dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method) { - int i, delete_method; + int i, methods; - delete_method = default_method; + /* If available, prefer the method requested by user. */ + i = softc->delete_method_pref; + methods = softc->delete_available | (1 << DA_DELETE_DISABLE); + if (methods & (1 << i)) { + dadeletemethodset(softc, i); + return; + } - /* - * Use the pre-defined order to choose the best - * performing delete. - */ + /* Use the pre-defined order to choose the best performing delete. */ for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) { + if (i == DA_DELETE_ZERO) + continue; if (softc->delete_available & (1 << i)) { dadeletemethodset(softc, i); return; } } - dadeletemethodset(softc, delete_method); + + /* Fallback to default. */ + dadeletemethodset(softc, default_method); } static int @@ -2055,13 +2054,14 @@ dadeletemethodsysctl(SYSCTL_HANDLER_ARGS) return (error); methods = softc->delete_available | (1 << DA_DELETE_DISABLE); for (i = 0; i <= DA_DELETE_MAX; i++) { - if (!(methods & (1 << i)) || - strcmp(buf, da_delete_method_names[i]) != 0) - continue; - dadeletemethodset(softc, i); - return (0); + if (strcmp(buf, da_delete_method_names[i]) == 0) + break; } - return (EINVAL); + if (i > DA_DELETE_MAX) + return (EINVAL); + softc->delete_method_pref = i; + dadeletemethodchoose(softc, DA_DELETE_NONE); + return (0); } static cam_status @@ -3298,6 +3298,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) /* Ensure re-probe doesn't see old delete. */ softc->delete_available = 0; + dadeleteflag(softc, DA_DELETE_ZERO, 1); if (lbp && (softc->quirks & DA_Q_NO_UNMAP) == 0) { /* * Based on older SBC-3 spec revisions @@ -3314,7 +3315,6 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) */ dadeleteflag(softc, DA_DELETE_WS16, 1); dadeleteflag(softc, DA_DELETE_WS10, 1); - dadeleteflag(softc, DA_DELETE_ZERO, 1); dadeleteflag(softc, DA_DELETE_UNMAP, 1); xpt_release_ccb(done_ccb); @@ -3343,8 +3343,6 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) (lbp->flags & SVPD_LBP_WS16)); dadeleteflag(softc, DA_DELETE_WS10, (lbp->flags & SVPD_LBP_WS10)); - dadeleteflag(softc, DA_DELETE_ZERO, - (lbp->flags & SVPD_LBP_WS10)); dadeleteflag(softc, DA_DELETE_UNMAP, (lbp->flags & SVPD_LBP_UNMAP)); } else { diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c index cd6af4e..7038f7f 100644 --- a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c +++ b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c @@ -44,6 +44,14 @@ #endif #define skip_whitespace(p) while ((*(p) == ' ') || (*(p) == '\t')) p++ +#if defined(__FreeBSD__) && !defined(_KERNEL) +/* + * libnvpair is the lowest commen denominator for ZFS related libraries, + * defining aok here makes it usable by all ZFS related libraries + */ +int aok; +#endif + /* * nvpair.c - Provides kernel & userland interfaces for manipulating * name-value pairs. diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c index 07a1b0a..f99aa20 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c @@ -448,7 +448,6 @@ load: DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); return (val); - return (0); } int diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c index 9582c97..3f6cb72 100644 --- a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c @@ -425,7 +425,6 @@ load: DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); return (val); - return (0); } int diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c index 0dd159e..3681d72 100644 --- a/sys/cddl/dev/sdt/sdt.c +++ b/sys/cddl/dev/sdt/sdt.c @@ -100,8 +100,8 @@ static dtrace_pops_t sdt_pops = { static TAILQ_HEAD(, sdt_provider) sdt_prov_list; -eventhandler_tag sdt_kld_load_tag; -eventhandler_tag sdt_kld_unload_try_tag; +static eventhandler_tag sdt_kld_load_tag; +static eventhandler_tag sdt_kld_unload_try_tag; static void sdt_create_provider(struct sdt_provider *prov) @@ -142,6 +142,12 @@ sdt_create_probe(struct sdt_probe *probe) char *to; size_t len; + if (probe->version != (int)sizeof(*probe)) { + printf("ignoring probe %p, version %u expected %u\n", + probe, probe->version, (int)sizeof(*probe)); + return; + } + TAILQ_FOREACH(prov, &sdt_prov_list, prov_entry) if (strcmp(prov->name, probe->prov->name) == 0) break; @@ -163,6 +169,8 @@ sdt_create_probe(struct sdt_probe *probe) * in the C compiler, so we have to respect const vs non-const. */ strlcpy(func, probe->func, sizeof(func)); + if (func[0] == '\0') + strcpy(func, "none"); from = probe->name; to = name; @@ -398,4 +406,3 @@ sdt_modevent(module_t mod __unused, int type, void *data __unused) DEV_MODULE(sdt, sdt_modevent, NULL); MODULE_VERSION(sdt, 1); MODULE_DEPEND(sdt, dtrace, 1, 1, 1); -MODULE_DEPEND(sdt, opensolaris, 1, 1, 1); diff --git a/sys/compat/linux/linux_dtrace.h b/sys/compat/linux/linux_dtrace.h index b713f16..c446b3e 100644 --- a/sys/compat/linux/linux_dtrace.h +++ b/sys/compat/linux/linux_dtrace.h @@ -82,7 +82,7 @@ c, d, e, f) #define LIN_SDT_PROBE4(a, b, c, d, e, f, g) SDT_PROBE4(LINUX_DTRACE, a, b, \ c, d, e, f, g) -#define _LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i) SDT_PROBE(a, b, c, d, \ +#define _LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i) SDT_PROBE5(a, b, c, d, \ e, f, g, h, i) #define LIN_SDT_PROBE5(a, b, c, d, e, f, g, h) _LIN_SDT_PROBE5(LINUX_DTRACE, \ a, b, c, d, e, f, g, h) diff --git a/sys/conf/files b/sys/conf/files index 4c5aed0..f238b12 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3267,7 +3267,7 @@ libkern/bcd.c standard libkern/bsearch.c standard libkern/crc32.c standard libkern/explicit_bzero.c standard -libkern/flsll.c standard +libkern/flsll.c standard libkern/fnmatch.c standard libkern/iconv.c optional libiconv libkern/iconv_converter_if.m optional libiconv diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 1c98eee..ecb7f85 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -92,6 +92,7 @@ libkern/divdi3.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard +libkern/flsll.c standard libkern/lshrdi3.c standard libkern/moddi3.c standard libkern/qdivrem.c standard diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 0a5d1b6..5cd89dc 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -543,8 +543,7 @@ kern/imgact_aout.c optional compat_aout kern/imgact_binmisc.c optional imagact_binmisc kern/imgact_gzip.c optional gzip libkern/divdi3.c standard -libkern/ffsl.c standard -libkern/flsl.c standard +libkern/flsll.c standard libkern/memmove.c standard libkern/memset.c standard libkern/moddi3.c standard diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index abe23b2..79caeaf 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -121,6 +121,7 @@ libkern/bcmp.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard +libkern/flsll.c standard libkern/ia64/__divdi3.S standard libkern/ia64/__divsi3.S standard libkern/ia64/__moddi3.S standard diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 82d9a69..6522bb2 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -56,6 +56,7 @@ kern/subr_dummy_vdso_tc.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard +libkern/flsll.c standard libkern/memmove.c standard libkern/cmpdi2.c optional mips | mipsel libkern/ucmpdi2.c optional mips | mipsel diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 88fa470..a1a9663 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -210,8 +210,7 @@ kern/kern_clocksource.c standard kern/imgact_aout.c optional compat_aout kern/imgact_gzip.c optional gzip libkern/divdi3.c standard -libkern/ffsl.c standard -libkern/flsl.c standard +libkern/flsll.c standard libkern/memmove.c standard libkern/memset.c standard libkern/moddi3.c standard diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index e889a5e..771968a 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -83,6 +83,7 @@ libkern/ffs.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard +libkern/flsll.c standard libkern/lshrdi3.c optional powerpc libkern/memmove.c standard libkern/memset.c standard diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 0a8f574..5775d9b 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -69,6 +69,7 @@ libkern/ffs.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard +libkern/flsll.c standard libkern/memmove.c standard sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus diff --git a/sys/dev/drm2/radeon/radeon_device.c b/sys/dev/drm2/radeon/radeon_device.c index e5c676b..73b2f4c 100644 --- a/sys/dev/drm2/radeon/radeon_device.c +++ b/sys/dev/drm2/radeon/radeon_device.c @@ -1342,14 +1342,10 @@ int radeon_suspend_kms(struct drm_device *dev) radeon_agp_suspend(rdev); - pci_save_state(device_get_parent(dev->dev)); #ifdef FREEBSD_WIP if (state.event == PM_EVENT_SUSPEND) { /* Shut down the device */ pci_disable_device(dev->pdev); -#endif /* FREEBSD_WIP */ - pci_set_powerstate(dev->dev, PCI_POWERSTATE_D3); -#ifdef FREEBSD_WIP } console_lock(); #endif /* FREEBSD_WIP */ @@ -1380,10 +1376,6 @@ int radeon_resume_kms(struct drm_device *dev) #ifdef FREEBSD_WIP console_lock(); -#endif /* FREEBSD_WIP */ - pci_set_powerstate(device_get_parent(dev->dev), PCI_POWERSTATE_D0); - pci_restore_state(device_get_parent(dev->dev)); -#ifdef FREEBSD_WIP if (pci_enable_device(dev->pdev)) { console_unlock(); return -1; diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 6f5441a..3853ed1 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -380,54 +380,12 @@ xhci_start_controller(struct xhci_softc *sc) return (USB_ERR_IOERROR); } - if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) { - device_printf(sc->sc_bus.parent, "Controller does " - "not support 4K page size.\n"); - return (USB_ERR_IOERROR); - } - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS1); - - i = XHCI_HCS1_N_PORTS(temp); - - if (i == 0) { - device_printf(sc->sc_bus.parent, "Invalid number " - "of ports: %u\n", i); - return (USB_ERR_IOERROR); - } - - sc->sc_noport = i; - sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp); - - if (sc->sc_noslot > XHCI_MAX_DEVICES) - sc->sc_noslot = XHCI_MAX_DEVICES; - /* set up number of device slots */ - DPRINTF("CONFIG=0x%08x -> 0x%08x\n", XREAD4(sc, oper, XHCI_CONFIG), sc->sc_noslot); XWRITE4(sc, oper, XHCI_CONFIG, sc->sc_noslot); - DPRINTF("Max slots: %u\n", sc->sc_noslot); - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); - - sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp); - - if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) { - device_printf(sc->sc_bus.parent, "XHCI request " - "too many scratchpads\n"); - return (USB_ERR_NOMEM); - } - - DPRINTF("Max scratch: %u\n", sc->sc_noscratch); - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS3); - - sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) + - XHCI_HCS3_U2_DEL(temp) + 250 /* us */; - temp = XREAD4(sc, oper, XHCI_USBSTS); /* clear interrupts */ @@ -459,29 +417,13 @@ xhci_start_controller(struct xhci_softc *sc) XWRITE4(sc, oper, XHCI_DCBAAP_LO, (uint32_t)addr); XWRITE4(sc, oper, XHCI_DCBAAP_HI, (uint32_t)(addr >> 32)); - /* Setup event table size */ - - temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); - - DPRINTF("HCS2=0x%08x\n", temp); - - temp = XHCI_HCS2_ERST_MAX(temp); - temp = 1U << temp; - if (temp > XHCI_MAX_RSEG) - temp = XHCI_MAX_RSEG; - - sc->sc_erst_max = temp; - + /* set up event table size */ DPRINTF("ERSTSZ=0x%08x -> 0x%08x\n", - XREAD4(sc, runt, XHCI_ERSTSZ(0)), temp); + XREAD4(sc, runt, XHCI_ERSTSZ(0)), sc->sc_erst_max); - XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(temp)); + XWRITE4(sc, runt, XHCI_ERSTSZ(0), XHCI_ERSTS_SET(sc->sc_erst_max)); - /* Check if we should use the default IMOD value */ - if (sc->sc_imod_default == 0) - sc->sc_imod_default = XHCI_IMOD_DEFAULT; - - /* Setup interrupt rate */ + /* set up interrupt rate */ XWRITE4(sc, runt, XHCI_IMOD(0), sc->sc_imod_default); usbd_get_page(&sc->sc_hw.root_pc, 0, &buf_res); @@ -508,8 +450,7 @@ xhci_start_controller(struct xhci_softc *sc) XWRITE4(sc, runt, XHCI_ERSTBA_LO(0), (uint32_t)addr); XWRITE4(sc, runt, XHCI_ERSTBA_HI(0), (uint32_t)(addr >> 32)); - /* Setup interrupter registers */ - + /* set up interrupter registers */ temp = XREAD4(sc, runt, XHCI_IMAN(0)); temp |= XHCI_IMAN_INTR_ENA; XWRITE4(sc, runt, XHCI_IMAN(0), temp); @@ -620,6 +561,12 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) DPRINTF("xHCI version = 0x%04x\n", XREAD2(sc, capa, XHCI_HCIVERSION)); + if (!(XREAD4(sc, oper, XHCI_PAGESIZE) & XHCI_PAGESIZE_4K)) { + device_printf(sc->sc_bus.parent, "Controller does " + "not support 4K page size.\n"); + return (ENXIO); + } + temp = XREAD4(sc, capa, XHCI_HCSPARAMS0); DPRINTF("HCS0 = 0x%08x\n", temp); @@ -638,6 +585,55 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) device_printf(self, "%d bytes context size, %d-bit DMA\n", sc->sc_ctx_is_64_byte ? 64 : 32, (int)sc->sc_bus.dma_bits); + temp = XREAD4(sc, capa, XHCI_HCSPARAMS1); + + /* get number of device slots */ + sc->sc_noport = XHCI_HCS1_N_PORTS(temp); + + if (sc->sc_noport == 0) { + device_printf(sc->sc_bus.parent, "Invalid number " + "of ports: %u\n", sc->sc_noport); + return (ENXIO); + } + + sc->sc_noport = sc->sc_noport; + sc->sc_noslot = XHCI_HCS1_DEVSLOT_MAX(temp); + + DPRINTF("Max slots: %u\n", sc->sc_noslot); + + if (sc->sc_noslot > XHCI_MAX_DEVICES) + sc->sc_noslot = XHCI_MAX_DEVICES; + + temp = XREAD4(sc, capa, XHCI_HCSPARAMS2); + + DPRINTF("HCS2=0x%08x\n", temp); + + /* get number of scratchpads */ + sc->sc_noscratch = XHCI_HCS2_SPB_MAX(temp); + + if (sc->sc_noscratch > XHCI_MAX_SCRATCHPADS) { + device_printf(sc->sc_bus.parent, "XHCI request " + "too many scratchpads\n"); + return (ENOMEM); + } + + DPRINTF("Max scratch: %u\n", sc->sc_noscratch); + + /* get event table size */ + sc->sc_erst_max = 1U << XHCI_HCS2_ERST_MAX(temp); + if (sc->sc_erst_max > XHCI_MAX_RSEG) + sc->sc_erst_max = XHCI_MAX_RSEG; + + temp = XREAD4(sc, capa, XHCI_HCSPARAMS3); + + /* get maximum exit latency */ + sc->sc_exit_lat_max = XHCI_HCS3_U1_DEL(temp) + + XHCI_HCS3_U2_DEL(temp) + 250 /* us */; + + /* Check if we should use the default IMOD value. */ + if (sc->sc_imod_default == 0) + sc->sc_imod_default = XHCI_IMOD_DEFAULT; + /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self), &xhci_iterate_hw_softc)) { diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index c4295aa..e85ac6e 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -86,10 +86,9 @@ static driver_t xhci_driver = { static devclass_t xhci_devclass; -DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, 0, 0); +DRIVER_MODULE(xhci, pci, xhci_driver, xhci_devclass, NULL, NULL); MODULE_DEPEND(xhci, usb, 1, 1, 1); - static const char * xhci_pci_match(device_t self) { @@ -104,6 +103,8 @@ xhci_pci_match(device_t self) case 0x10421b21: return ("ASMedia ASM1042 USB 3.0 controller"); + case 0x11421b21: + return ("ASMedia ASM1042A USB 3.0 controller"); case 0x0f358086: return ("Intel BayTrail USB 3.0 controller"); @@ -114,6 +115,8 @@ xhci_pci_match(device_t self) return ("Intel Lynx Point USB 3.0 controller"); case 0x8cb18086: return ("Intel Wildcat Point USB 3.0 controller"); + case 0x9cb18086: + return ("Broadwell Integrated PCH-LP chipset USB 3.0 controller"); case 0xa01b177d: return ("Cavium ThunderX USB 3.0 controller"); @@ -200,17 +203,31 @@ xhci_pci_attach(device_t self) sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); sc->sc_io_size = rman_get_size(sc->sc_io_res); - /* check for USB 3.0 controllers which don't support 64-bit DMA */ switch (pci_get_devid(self)) { case 0x01941033: /* NEC uPD720200 USB 3.0 controller */ + case 0x00141912: /* NEC uPD720201 USB 3.0 controller */ + /* Don't use 64-bit DMA on these controllers. */ usedma32 = 1; break; case 0x10001b73: /* FL1000G */ /* Fresco Logic host doesn't support MSI. */ usemsi = 0; break; + case 0x0f358086: /* BayTrail */ + case 0x9c318086: /* Panther Point */ + case 0x1e318086: /* Panther Point */ + case 0x8c318086: /* Lynx Point */ + case 0x8cb18086: /* Wildcat Point */ + case 0x9cb18086: /* Broadwell Mobile Integrated */ + /* + * On Intel chipsets, reroute ports from EHCI to XHCI + * controller and use a different IMOD value. + */ + sc->sc_port_route = &xhci_pci_port_route; + sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP; + break; } - + if (xhci_init(sc, self, usedma32)) { device_printf(self, "Could not initialize softc\n"); bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM, @@ -269,20 +286,6 @@ xhci_pci_attach(device_t self) goto error; } - /* On Intel chipsets reroute ports from EHCI to XHCI controller. */ - switch (pci_get_devid(self)) { - case 0x0f358086: /* BayTrail */ - case 0x9c318086: /* Panther Point */ - case 0x1e318086: /* Panther Point */ - case 0x8c318086: /* Lynx Point */ - case 0x8cb18086: /* Wildcat Point */ - sc->sc_port_route = &xhci_pci_port_route; - sc->sc_imod_default = XHCI_IMOD_DEFAULT_LP; - break; - default: - break; - } - xhci_pci_take_controller(self); err = xhci_halt_controller(sc); diff --git a/sys/geom/uncompress/g_uncompress.c b/sys/geom/uncompress/g_uncompress.c index f1cb544..30831db 100644 --- a/sys/geom/uncompress/g_uncompress.c +++ b/sys/geom/uncompress/g_uncompress.c @@ -111,8 +111,8 @@ g_uncompress_softc_free(struct g_uncompress_softc *sc, struct g_geom *gp) { if (gp != NULL) { - printf("%s: %d requests, %d cached\n", - gp->name, sc->req_total, sc->req_cached); + DPRINTF(("%s: %d requests, %d cached\n", + gp->name, sc->req_total, sc->req_cached)); } if (sc->offsets != NULL) { free(sc->offsets, M_GEOM_UNCOMPRESS); @@ -518,7 +518,7 @@ g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags) DPRINTF(("%s: image version too old\n", gp->name)); goto err; } - printf("%s: GEOM_ULZMA image found\n", gp->name); + DPRINTF(("%s: GEOM_ULZMA image found\n", gp->name)); break; case 'V': type = GEOM_UZIP; @@ -526,7 +526,7 @@ g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags) DPRINTF(("%s: image version too old\n", gp->name)); goto err; } - printf("%s: GEOM_UZIP image found\n", gp->name); + DPRINTF(("%s: GEOM_UZIP image found\n", gp->name)); break; default: DPRINTF(("%s: unsupported image type\n", gp->name)); @@ -622,7 +622,7 @@ g_uncompress_taste(struct g_class *mp, struct g_provider *pp, int flags) gp->name, pp2->sectorsize, (intmax_t)pp2->mediasize, pp2->stripeoffset, pp2->stripesize, pp2->flags)); - printf("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz); + DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz)); return (gp); err: @@ -651,7 +651,7 @@ g_uncompress_destroy_geom(struct gctl_req *req, struct g_class *mp, g_topology_assert(); if (gp->softc == NULL) { - printf("%s(%s): gp->softc == NULL\n", __func__, gp->name); + DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name)); return (ENXIO); } diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c index c2ed64b..6c79662 100644 --- a/sys/geom/uzip/g_uzip.c +++ b/sys/geom/uzip/g_uzip.c @@ -94,8 +94,8 @@ g_uzip_softc_free(struct g_uzip_softc *sc, struct g_geom *gp) { if (gp != NULL) { - printf("%s: %d requests, %d cached\n", - gp->name, sc->req_total, sc->req_cached); + DPRINTF(("%s: %d requests, %d cached\n", + gp->name, sc->req_total, sc->req_cached)); } if (sc->offsets != NULL) { free(sc->offsets, M_GEOM_UZIP); @@ -519,7 +519,7 @@ g_uzip_taste(struct g_class *mp, struct g_provider *pp, int flags) gp->name, pp2->sectorsize, (intmax_t)pp2->mediasize, pp2->stripeoffset, pp2->stripesize, pp2->flags)); - printf("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz); + DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz)); return (gp); err: @@ -547,7 +547,7 @@ g_uzip_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) g_topology_assert(); if (gp->softc == NULL) { - printf("%s(%s): gp->softc == NULL\n", __func__, gp->name); + DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name)); return (ENXIO); } diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index 2221ce9..d3a7e08 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -97,6 +97,13 @@ clflush(u_long addr) } static __inline void +clflushopt(u_long addr) +{ + + __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); +} + +static __inline void clts(void) { @@ -184,6 +191,14 @@ ffs(int mask) return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1); } +#define HAVE_INLINE_FFSL + +static __inline int +ffsl(long mask) +{ + return (ffs((int)mask)); +} + #define HAVE_INLINE_FLS static __inline int @@ -192,6 +207,14 @@ fls(int mask) return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); } +#define HAVE_INLINE_FLSL + +static __inline int +flsl(long mask) +{ + return (fls((int)mask)); +} + #endif /* _KERNEL */ static __inline void diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index e66d679..520cc8b 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -715,21 +715,22 @@ fail: static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) { - const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; + struct thread *td; + const Elf_Ehdr *hdr; const Elf_Phdr *phdr; Elf_Auxargs *elf_auxargs; struct vmspace *vmspace; - vm_prot_t prot; - u_long text_size = 0, data_size = 0, total_size = 0; - u_long text_addr = 0, data_addr = 0; - u_long seg_size, seg_addr; - u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0; - int32_t osrel = 0; - int error = 0, i, n, interp_name_len = 0; - const char *interp = NULL, *newinterp = NULL; + const char *err_str, *newinterp; + char *interp, *interp_buf, *path; Elf_Brandinfo *brand_info; - char *path; struct sysentvec *sv; + vm_prot_t prot; + u_long text_size, data_size, total_size, text_addr, data_addr; + u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr; + int32_t osrel; + int error, i, n, interp_name_len, have_interp; + + hdr = (const Elf_Ehdr *)imgp->image_header; /* * Do we have a valid ELF header ? @@ -749,13 +750,25 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if ((hdr->e_phoff > PAGE_SIZE) || (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) { /* Only support headers in first page for now */ + uprintf("Program headers not in the first page\n"); return (ENOEXEC); } - phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); - if (!aligned(phdr, Elf_Addr)) + phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); + if (!aligned(phdr, Elf_Addr)) { + uprintf("Unaligned program headers\n"); return (ENOEXEC); - n = 0; + } + + n = error = 0; baddr = 0; + osrel = 0; + text_size = data_size = total_size = text_addr = data_addr = 0; + entry = proghdr = 0; + interp_name_len = 0; + err_str = newinterp = NULL; + interp = interp_buf = NULL; + td = curthread; + for (i = 0; i < hdr->e_phnum; i++) { switch (phdr[i].p_type) { case PT_LOAD: @@ -765,12 +778,32 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) break; case PT_INTERP: /* Path to interpreter */ - if (phdr[i].p_filesz > MAXPATHLEN || - phdr[i].p_offset > PAGE_SIZE || - phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) - return (ENOEXEC); - interp = imgp->image_header + phdr[i].p_offset; + if (phdr[i].p_filesz > MAXPATHLEN) { + uprintf("Invalid PT_INTERP\n"); + error = ENOEXEC; + goto ret; + } interp_name_len = phdr[i].p_filesz; + if (phdr[i].p_offset > PAGE_SIZE || + interp_name_len > PAGE_SIZE - phdr[i].p_offset) { + VOP_UNLOCK(imgp->vp, 0); + interp_buf = malloc(interp_name_len + 1, M_TEMP, + M_WAITOK); + vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); + error = vn_rdwr(UIO_READ, imgp->vp, interp_buf, + interp_name_len, phdr[i].p_offset, + UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, + NOCRED, NULL, td); + if (error != 0) { + uprintf("i/o error PT_INTERP\n"); + goto ret; + } + interp_buf[interp_name_len] = '\0'; + interp = interp_buf; + } else { + interp = __DECONST(char *, imgp->image_header) + + phdr[i].p_offset; + } break; case PT_GNU_STACK: if (__elfN(nxstack)) @@ -786,11 +819,15 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (brand_info == NULL) { uprintf("ELF binary type \"%u\" not known.\n", hdr->e_ident[EI_OSABI]); - return (ENOEXEC); + error = ENOEXEC; + goto ret; } if (hdr->e_type == ET_DYN) { - if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) - return (ENOEXEC); + if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) { + uprintf("Cannot execute shared object\n"); + error = ENOEXEC; + goto ret; + } /* * Honour the base load address from the dso if it is * non-zero for some reason. @@ -822,8 +859,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->proc->p_sysent = sv; vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); - if (error) - return (error); + if (error != 0) + goto ret; for (i = 0; i < hdr->e_phnum; i++) { switch (phdr[i].p_type) { @@ -836,7 +873,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) phdr[i].p_memsz, phdr[i].p_filesz, prot, sv->sv_pagesize); if (error != 0) - return (error); + goto ret; /* * If this segment contains the program headers, @@ -895,13 +932,21 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) * not actually fault in all the segments pages. */ PROC_LOCK(imgp->proc); - if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) || - text_size > maxtsiz || - total_size > lim_cur(imgp->proc, RLIMIT_VMEM) || - racct_set(imgp->proc, RACCT_DATA, data_size) != 0 || - racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) { + if (data_size > lim_cur(imgp->proc, RLIMIT_DATA)) + err_str = "Data segment size exceeds process limit"; + else if (text_size > maxtsiz) + err_str = "Text segment size exceeds system limit"; + else if (total_size > lim_cur(imgp->proc, RLIMIT_VMEM)) + err_str = "Total segment size exceeds process limit"; + else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0) + err_str = "Data segment size exceeds resource limit"; + else if (racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) + err_str = "Total segment size exceeds resource limit"; + if (err_str != NULL) { PROC_UNLOCK(imgp->proc); - return (ENOMEM); + uprintf("%s\n", err_str); + error = ENOMEM; + goto ret; } vmspace = imgp->proc->p_vmspace; @@ -923,7 +968,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->entry_addr = entry; if (interp != NULL) { - int have_interp = FALSE; + have_interp = FALSE; VOP_UNLOCK(imgp->vp, 0); if (brand_info->emul_path != NULL && brand_info->emul_path[0] != '\0') { @@ -949,7 +994,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); if (error != 0) { uprintf("ELF interpreter %s not found\n", interp); - return (error); + goto ret; } } else addr = et_dyn_addr; @@ -972,6 +1017,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->reloc_base = addr; imgp->proc->p_osrel = osrel; + ret: + free(interp_buf, M_TEMP); return (error); } @@ -2023,19 +2070,42 @@ __elfN(parse_notes)(struct image_params *imgp, Elf_Brandnote *checknote, { const Elf_Note *note, *note0, *note_end; const char *note_name; - int i; + char *buf; + int i, error; + boolean_t res; - if (pnote == NULL || pnote->p_offset > PAGE_SIZE || - pnote->p_filesz > PAGE_SIZE - pnote->p_offset) + /* We need some limit, might as well use PAGE_SIZE. */ + if (pnote == NULL || pnote->p_filesz > PAGE_SIZE) return (FALSE); - - note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset); - note_end = (const Elf_Note *)(imgp->image_header + - pnote->p_offset + pnote->p_filesz); + ASSERT_VOP_LOCKED(imgp->vp, "parse_notes"); + if (pnote->p_offset > PAGE_SIZE || + pnote->p_filesz > PAGE_SIZE - pnote->p_offset) { + VOP_UNLOCK(imgp->vp, 0); + buf = malloc(pnote->p_filesz, M_TEMP, M_WAITOK); + vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY); + error = vn_rdwr(UIO_READ, imgp->vp, buf, pnote->p_filesz, + pnote->p_offset, UIO_SYSSPACE, IO_NODELOCKED, + curthread->td_ucred, NOCRED, NULL, curthread); + if (error != 0) { + uprintf("i/o error PT_NOTE\n"); + res = FALSE; + goto ret; + } + note = note0 = (const Elf_Note *)buf; + note_end = (const Elf_Note *)(buf + pnote->p_filesz); + } else { + note = note0 = (const Elf_Note *)(imgp->image_header + + pnote->p_offset); + note_end = (const Elf_Note *)(imgp->image_header + + pnote->p_offset + pnote->p_filesz); + buf = NULL; + } for (i = 0; i < 100 && note >= note0 && note < note_end; i++) { if (!aligned(note, Elf32_Addr) || (const char *)note_end - - (const char *)note < sizeof(Elf_Note)) - return (FALSE); + (const char *)note < sizeof(Elf_Note)) { + res = FALSE; + goto ret; + } if (note->n_namesz != checknote->hdr.n_namesz || note->n_descsz != checknote->hdr.n_descsz || note->n_type != checknote->hdr.n_type) @@ -2051,17 +2121,21 @@ __elfN(parse_notes)(struct image_params *imgp, Elf_Brandnote *checknote, * from the ELF OSABI-note if necessary. */ if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 && - checknote->trans_osrel != NULL) - return (checknote->trans_osrel(note, osrel)); - return (TRUE); - + checknote->trans_osrel != NULL) { + res = checknote->trans_osrel(note, osrel); + goto ret; + } + res = TRUE; + goto ret; nextnote: note = (const Elf_Note *)((const char *)(note + 1) + roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE) + roundup2(note->n_descsz, ELF_NOTE_ROUNDSIZE)); } - - return (FALSE); + res = FALSE; +ret: + free(buf, M_TEMP); + return (res); } /* diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 9e4a4ff..f82ffec 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -416,7 +416,7 @@ do_execve(td, args, mac_p) | AUDITVNODE1, UIO_SYSSPACE, args->fname, td); } - SDT_PROBE(proc, kernel, , exec, args->fname, 0, 0, 0, 0 ); + SDT_PROBE1(proc, kernel, , exec, args->fname); interpret: if (args->fname != NULL) { @@ -838,7 +838,7 @@ interpret: vfs_mark_atime(imgp->vp, td->td_ucred); - SDT_PROBE(proc, kernel, , exec__success, args->fname, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exec__success, args->fname); VOP_UNLOCK(imgp->vp, 0); done1: @@ -909,7 +909,7 @@ exec_fail: p->p_flag &= ~P_INEXEC; PROC_UNLOCK(p); - SDT_PROBE(proc, kernel, , exec__failure, error, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exec__failure, error); done2: #ifdef MAC diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index f2a61ad..d00a554 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -564,7 +564,7 @@ exit1(struct thread *td, int rv) reason = CLD_DUMPED; else if (WIFSIGNALED(rv)) reason = CLD_KILLED; - SDT_PROBE(proc, kernel, , exit, reason, 0, 0, 0, 0); + SDT_PROBE1(proc, kernel, , exit, reason); #endif /* diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 10b2339..6ca41d4 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/procdesc.h> #include <sys/pioctl.h> +#include <sys/ptrace.h> #include <sys/racct.h> #include <sys/resourcevar.h> #include <sys/sched.h> @@ -478,6 +479,8 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, td2->td_sigstk = td->td_sigstk; td2->td_flags = TDF_INMEM; td2->td_lend_user_pri = PRI_MAX; + td2->td_dbg_sc_code = td->td_dbg_sc_code; + td2->td_dbg_sc_narg = td->td_dbg_sc_narg; #ifdef VIMAGE td2->td_vnet = NULL; @@ -750,7 +753,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, * Tell any interested parties about the new process. */ knote_fork(&p1->p_klist, p2->p_pid); - SDT_PROBE(proc, kernel, , create, p2, p1, flags, 0, 0); + SDT_PROBE3(proc, kernel, , create, p2, p1, flags); /* * Wait until debugger is attached to child. @@ -1049,8 +1052,8 @@ fork_return(struct thread *td, struct trapframe *frame) { struct proc *p, *dbg; + p = td->td_proc; if (td->td_dbgflags & TDB_STOPATFORK) { - p = td->td_proc; sx_xlock(&proctree_lock); PROC_LOCK(p); if ((p->p_pptr->p_flag & (P_TRACED | P_FOLLOWFORK)) == @@ -1067,9 +1070,9 @@ fork_return(struct thread *td, struct trapframe *frame) p->p_pid, p->p_oppid); proc_reparent(p, dbg); sx_xunlock(&proctree_lock); - td->td_dbgflags |= TDB_CHILD; + td->td_dbgflags |= TDB_CHILD | TDB_SCX; ptracestop(td, SIGSTOP); - td->td_dbgflags &= ~TDB_CHILD; + td->td_dbgflags &= ~(TDB_CHILD | TDB_SCX); } else { /* * ... otherwise clear the request. @@ -1079,6 +1082,18 @@ fork_return(struct thread *td, struct trapframe *frame) cv_broadcast(&p->p_dbgwait); } PROC_UNLOCK(p); + } else if (p->p_flag & P_TRACED) { + /* + * This is the start of a new thread in a traced + * process. Report a system call exit event. + */ + PROC_LOCK(p); + td->td_dbgflags |= TDB_SCX; + _STOPEVENT(p, S_SCX, td->td_dbg_sc_code); + if ((p->p_stops & S_PT_SCX) != 0) + ptracestop(td, SIGTRAP); + td->td_dbgflags &= ~TDB_SCX; + PROC_UNLOCK(p); } userret(td, frame); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 8986a58..e051e3e 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -181,9 +181,9 @@ proc_ctor(void *mem, int size, void *arg, int flags) struct proc *p; p = (struct proc *)mem; - SDT_PROBE(proc, kernel, ctor , entry, p, size, arg, flags, 0); + SDT_PROBE4(proc, kernel, ctor , entry, p, size, arg, flags); EVENTHANDLER_INVOKE(process_ctor, p); - SDT_PROBE(proc, kernel, ctor , return, p, size, arg, flags, 0); + SDT_PROBE4(proc, kernel, ctor , return, p, size, arg, flags); return (0); } @@ -199,7 +199,7 @@ proc_dtor(void *mem, int size, void *arg) /* INVARIANTS checks go here */ p = (struct proc *)mem; td = FIRST_THREAD_IN_PROC(p); - SDT_PROBE(proc, kernel, dtor, entry, p, size, arg, td, 0); + SDT_PROBE4(proc, kernel, dtor, entry, p, size, arg, td); if (td != NULL) { #ifdef INVARIANTS KASSERT((p->p_numthreads == 1), @@ -212,7 +212,7 @@ proc_dtor(void *mem, int size, void *arg) EVENTHANDLER_INVOKE(process_dtor, p); if (p->p_ksi != NULL) KASSERT(! KSI_ONQ(p->p_ksi), ("SIGCHLD queue")); - SDT_PROBE(proc, kernel, dtor, return, p, size, arg, 0, 0); + SDT_PROBE3(proc, kernel, dtor, return, p, size, arg); } /* @@ -224,7 +224,7 @@ proc_init(void *mem, int size, int flags) struct proc *p; p = (struct proc *)mem; - SDT_PROBE(proc, kernel, init, entry, p, size, flags, 0, 0); + SDT_PROBE3(proc, kernel, init, entry, p, size, flags); p->p_sched = (struct p_sched *)&p[1]; bzero(&p->p_mtx, sizeof(struct mtx)); mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); @@ -234,7 +234,7 @@ proc_init(void *mem, int size, int flags) TAILQ_INIT(&p->p_threads); /* all threads in proc */ EVENTHANDLER_INVOKE(process_init, p); p->p_stats = pstats_alloc(); - SDT_PROBE(proc, kernel, init, return, p, size, flags, 0, 0); + SDT_PROBE3(proc, kernel, init, return, p, size, flags); return (0); } diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 9a59513..6c69d49 100644 --- a/sys/kern/kern_racct.c +++ b/sys/kern/kern_racct.c @@ -447,7 +447,7 @@ racct_create(struct racct **racctp) if (!racct_enable) return; - SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); + SDT_PROBE1(racct, kernel, racct, create, racctp); KASSERT(*racctp == NULL, ("racct already allocated")); @@ -462,7 +462,7 @@ racct_destroy_locked(struct racct **racctp) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); + SDT_PROBE1(racct, kernel, racct, destroy, racctp); mtx_assert(&racct_lock, MA_OWNED); KASSERT(racctp != NULL, ("NULL racctp")); @@ -540,7 +540,7 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -550,8 +550,8 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount) #ifdef RCTL error = rctl_enforce(p, resource, amount); if (error && RACCT_IS_DENIABLE(resource)) { - SDT_PROBE(racct, kernel, rusage, add__failure, p, resource, - amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__failure, p, resource, + amount); return (error); } #endif @@ -586,8 +586,7 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount, - 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__cred, cred, resource, amount); racct_adjust_resource(cred->cr_ruidinfo->ui_racct, resource, amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) @@ -625,7 +624,7 @@ racct_add_force(struct proc *p, int resource, uint64_t amount) if (!racct_enable) return; - SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, add__force, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -649,7 +648,7 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -681,8 +680,8 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount) if (diff_proc > 0) { error = rctl_enforce(p, resource, diff_proc); if (error && RACCT_IS_DENIABLE(resource)) { - SDT_PROBE(racct, kernel, rusage, set__failure, p, - resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set__failure, p, + resource, amount); return (error); } } @@ -725,7 +724,7 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, set, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -836,7 +835,7 @@ racct_sub(struct proc *p, int resource, uint64_t amount) if (!racct_enable) return; - SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); + SDT_PROBE3(racct, kernel, rusage, sub, p, resource, amount); /* * We need proc lock to dereference p->p_ucred. @@ -863,8 +862,7 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) ASSERT_RACCT_ENABLED(); - SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount, - 0, 0); + SDT_PROBE3(racct, kernel, rusage, sub__cred, cred, resource, amount); #ifdef notyet KASSERT(RACCT_CAN_DROP(resource), diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 909d905..841fc49 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1291,7 +1291,7 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, ksiginfo_t *ksi, reschedule_signals(p, new_block, 0); if (error == 0) { - SDT_PROBE(proc, kernel, , signal__clear, sig, ksi, 0, 0, 0); + SDT_PROBE2(proc, kernel, , signal__clear, sig, ksi); if (ksi->ksi_code == SI_TIMER) itimer_accept(p, ksi->ksi_timerid, ksi); @@ -2108,7 +2108,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) } else sigqueue = &td->td_sigqueue; - SDT_PROBE(proc, kernel, , signal__send, td, p, sig, 0, 0 ); + SDT_PROBE3(proc, kernel, , signal__send, td, p, sig); /* * If the signal is being ignored, @@ -2119,7 +2119,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) */ mtx_lock(&ps->ps_mtx); if (SIGISMEMBER(ps->ps_sigignore, sig)) { - SDT_PROBE(proc, kernel, , signal__discard, td, p, sig, 0, 0 ); + SDT_PROBE3(proc, kernel, , signal__discard, td, p, sig); mtx_unlock(&ps->ps_mtx); if (ksi && (ksi->ksi_flags & KSI_INS)) diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index bcbc3d0..058dc19 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -240,6 +240,8 @@ thread_create(struct thread *td, struct rtprio *rtp, __rangeof(struct thread, td_startcopy, td_endcopy)); newtd->td_proc = td->td_proc; newtd->td_ucred = crhold(td->td_ucred); + newtd->td_dbg_sc_code = td->td_dbg_sc_code; + newtd->td_dbg_sc_narg = td->td_dbg_sc_narg; error = initialize_thread(newtd, thunk); if (error != 0) { diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 71e0f4f..5dc2bb0 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -280,7 +280,7 @@ threadinit(void) thread_zone = uma_zcreate("THREAD", sched_sizeof_thread(), thread_ctor, thread_dtor, thread_init, thread_fini, - 16 - 1, 0); + 16 - 1, UMA_ZONE_NOFREE); tidhashtbl = hashinit(maxproc / 2, M_TIDHASH, &tidhash); rw_init(&tidhash_lock, "tidhash"); } diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 9f23558..c3a2226 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -681,9 +681,9 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc, sbt1 = sbinuptime(); #endif THREAD_NO_SLEEPING(); - SDT_PROBE(callout_execute, kernel, , callout__start, c, 0, 0, 0, 0); + SDT_PROBE1(callout_execute, kernel, , callout__start, c); c_func(c_arg); - SDT_PROBE(callout_execute, kernel, , callout__end, c, 0, 0, 0, 0); + SDT_PROBE1(callout_execute, kernel, , callout__end, c); THREAD_SLEEPING_OK(); #if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING) sbt2 = sbinuptime(); diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index 925d732..1ad7dd0 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -84,9 +84,12 @@ syscallenter(struct thread *td, struct syscall_args *sa) if (error == 0) { STOPEVENT(p, S_SCE, sa->narg); - if (p->p_flag & P_TRACED && p->p_stops & S_PT_SCE) { + if (p->p_flag & P_TRACED) { PROC_LOCK(p); - ptracestop((td), SIGTRAP); + td->td_dbg_sc_code = sa->code; + td->td_dbg_sc_narg = sa->narg; + if (p->p_stops & S_PT_SCE) + ptracestop((td), SIGTRAP); PROC_UNLOCK(p); } if (td->td_dbgflags & TDB_USERWR) { @@ -95,6 +98,10 @@ syscallenter(struct thread *td, struct syscall_args *sa) * debugger modified registers or memory. */ error = (p->p_sysent->sv_fetch_syscall_args)(td, sa); + PROC_LOCK(p); + td->td_dbg_sc_code = sa->code; + td->td_dbg_sc_narg = sa->narg; + PROC_UNLOCK(p); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSCALL)) ktrsyscall(sa->code, sa->narg, sa->args); diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 123dd10..5efec4f 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -96,6 +96,8 @@ struct ptrace_lwpinfo32 { struct siginfo32 pl_siginfo; /* siginfo for signal */ char pl_tdname[MAXCOMLEN + 1]; /* LWP name. */ int pl_child_pid; /* New child pid */ + u_int pl_syscall_code; + u_int pl_syscall_narg; }; #endif @@ -440,7 +442,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve) } #ifdef COMPAT_FREEBSD32 -static int +static int ptrace_vm_entry32(struct thread *td, struct proc *p, struct ptrace_vm_entry32 *pve32) { @@ -480,6 +482,8 @@ ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl, siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo); strcpy(pl32->pl_tdname, pl->pl_tdname); pl32->pl_child_pid = pl->pl_child_pid; + pl32->pl_syscall_code = pl->pl_syscall_code; + pl32->pl_syscall_narg = pl->pl_syscall_narg; } #endif /* COMPAT_FREEBSD32 */ @@ -739,12 +743,23 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) */ switch (req) { case PT_TRACE_ME: - /* Always legal. */ + /* + * Always legal, when there is a parent process which + * could trace us. Otherwise, reject. + */ + if ((p->p_flag & P_TRACED) != 0) { + error = EBUSY; + goto fail; + } + if (p->p_pptr == initproc) { + error = EPERM; + goto fail; + } break; case PT_ATTACH: /* Self */ - if (p->p_pid == td->td_proc->p_pid) { + if (p == td->td_proc) { error = EINVAL; goto fail; } @@ -1210,6 +1225,13 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) pl->pl_sigmask = td2->td_sigmask; pl->pl_siglist = td2->td_siglist; strcpy(pl->pl_tdname, td2->td_name); + if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) != 0) { + pl->pl_syscall_code = td2->td_dbg_sc_code; + pl->pl_syscall_narg = td2->td_dbg_sc_narg; + } else { + pl->pl_syscall_code = 0; + pl->pl_syscall_narg = 0; + } #ifdef COMPAT_FREEBSD32 if (wrap32) ptrace_lwpinfo_to32(pl, pl32); diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 05dff4e..311271b 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -420,11 +420,11 @@ cache_zap(ncp) CTR2(KTR_VFS, "cache_zap(%p) vp %p", ncp, ncp->nc_vp); #ifdef KDTRACE_HOOKS if (ncp->nc_vp != NULL) { - SDT_PROBE(vfs, namecache, zap, done, ncp->nc_dvp, - nc_get_name(ncp), ncp->nc_vp, 0, 0); + SDT_PROBE3(vfs, namecache, zap, done, ncp->nc_dvp, + nc_get_name(ncp), ncp->nc_vp); } else { - SDT_PROBE(vfs, namecache, zap_negative, done, ncp->nc_dvp, - nc_get_name(ncp), 0, 0, 0); + SDT_PROBE2(vfs, namecache, zap_negative, done, ncp->nc_dvp, + nc_get_name(ncp)); } #endif vp = NULL; @@ -499,8 +499,7 @@ retry_wlocked: CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .", dvp, cnp->cn_nameptr); dothits++; - SDT_PROBE(vfs, namecache, lookup, hit, dvp, ".", - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ".", *vpp); if (tsp != NULL) timespecclear(tsp); if (ticksp != NULL) @@ -510,8 +509,8 @@ retry_wlocked: if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { dotdothits++; if (dvp->v_cache_dd == NULL) { - SDT_PROBE(vfs, namecache, lookup, miss, dvp, - "..", NULL, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, + "..", NULL); goto unlock; } if ((cnp->cn_flags & MAKEENTRY) == 0) { @@ -533,8 +532,8 @@ retry_wlocked: goto negative_success; CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", dvp, cnp->cn_nameptr, *vpp); - SDT_PROBE(vfs, namecache, lookup, hit, dvp, "..", - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..", + *vpp); cache_out_ts(ncp, tsp, ticksp); if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) == NCF_DTS && tsp != NULL) @@ -555,8 +554,8 @@ retry_wlocked: /* We failed to find an entry */ if (ncp == NULL) { - SDT_PROBE(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, + NULL); if ((cnp->cn_flags & MAKEENTRY) == 0) { nummisszap++; } else { @@ -584,8 +583,8 @@ retry_wlocked: *vpp = ncp->nc_vp; CTR4(KTR_VFS, "cache_lookup(%p, %s) found %p via ncp %p", dvp, cnp->cn_nameptr, *vpp, ncp); - SDT_PROBE(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp), - *vpp, 0, 0); + SDT_PROBE3(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp), + *vpp); cache_out_ts(ncp, tsp, ticksp); goto success; } @@ -616,8 +615,8 @@ negative_success: nchstats.ncs_neghits++; if (ncp->nc_flag & NCF_WHITE) cnp->cn_flags |= ISWHITEOUT; - SDT_PROBE(vfs, namecache, lookup, hit__negative, dvp, nc_get_name(ncp), - 0, 0, 0); + SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, + nc_get_name(ncp)); cache_out_ts(ncp, tsp, ticksp); CACHE_WUNLOCK(); return (ENOENT); @@ -770,8 +769,7 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp) return; } dvp->v_cache_dd = NULL; - SDT_PROBE(vfs, namecache, enter, done, dvp, "..", vp, - 0, 0); + SDT_PROBE3(vfs, namecache, enter, done, dvp, "..", vp); CACHE_WUNLOCK(); flag = NCF_ISDOTDOT; } @@ -891,12 +889,12 @@ cache_enter_time(dvp, vp, cnp, tsp, dtsp) */ if (vp) { TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst); - SDT_PROBE(vfs, namecache, enter, done, dvp, nc_get_name(ncp), - vp, 0, 0); + SDT_PROBE3(vfs, namecache, enter, done, dvp, nc_get_name(ncp), + vp); } else { TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); - SDT_PROBE(vfs, namecache, enter_negative, done, dvp, - nc_get_name(ncp), 0, 0, 0); + SDT_PROBE2(vfs, namecache, enter_negative, done, dvp, + nc_get_name(ncp)); } if (numneg * ncnegfactor > numcache) { ncp = TAILQ_FIRST(&ncneg); @@ -985,7 +983,7 @@ cache_purge(vp) { CTR1(KTR_VFS, "cache_purge(%p)", vp); - SDT_PROBE(vfs, namecache, purge, done, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purge, done, vp); CACHE_WLOCK(); while (!LIST_EMPTY(&vp->v_cache_src)) cache_zap(LIST_FIRST(&vp->v_cache_src)); @@ -1010,7 +1008,7 @@ cache_purge_negative(vp) struct namecache *cp, *ncp; CTR1(KTR_VFS, "cache_purge_negative(%p)", vp); - SDT_PROBE(vfs, namecache, purge_negative, done, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purge_negative, done, vp); CACHE_WLOCK(); LIST_FOREACH_SAFE(cp, &vp->v_cache_src, nc_src, ncp) { if (cp->nc_vp == NULL) @@ -1030,7 +1028,7 @@ cache_purgevfs(mp) struct namecache *ncp, *nnp; /* Scan hash tables for applicable entries */ - SDT_PROBE(vfs, namecache, purgevfs, done, mp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, purgevfs, done, mp); CACHE_WLOCK(); for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { LIST_FOREACH_SAFE(ncp, ncpp, nc_hash, nnp) { @@ -1252,14 +1250,14 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, vrele(*vp); numfullpathfail4++; error = ENOMEM; - SDT_PROBE(vfs, namecache, fullpath, return, error, - vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, + vp, NULL); return (error); } *buflen -= ncp->nc_nlen; memcpy(buf + *buflen, nc_get_name(ncp), ncp->nc_nlen); - SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp, - nc_get_name(ncp), vp, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, hit, ncp->nc_dvp, + nc_get_name(ncp), vp); dvp = *vp; *vp = ncp->nc_dvp; vref(*vp); @@ -1268,7 +1266,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, CACHE_RLOCK(); return (0); } - SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, fullpath, miss, vp); CACHE_RUNLOCK(); vn_lock(*vp, LK_SHARED | LK_RETRY); @@ -1276,8 +1274,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, vput(*vp); if (error) { numfullpathfail2++; - SDT_PROBE(vfs, namecache, fullpath, return, error, vp, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); return (error); } @@ -1288,8 +1285,7 @@ vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, CACHE_RUNLOCK(); vrele(dvp); error = ENOENT; - SDT_PROBE(vfs, namecache, fullpath, return, error, vp, - NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); return (error); } /* @@ -1317,7 +1313,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, error = 0; slash_prefixed = 0; - SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0); + SDT_PROBE1(vfs, namecache, fullpath, entry, vp); numfullpathcalls++; vref(vp); CACHE_RLOCK(); @@ -1339,8 +1335,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); error = ENOENT; - SDT_PROBE(vfs, namecache, fullpath, return, - error, vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, + error, vp, NULL); break; } vp1 = vp->v_mount->mnt_vnodecovered; @@ -1356,8 +1352,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, vrele(vp); numfullpathfail1++; error = ENOTDIR; - SDT_PROBE(vfs, namecache, fullpath, return, - error, vp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, + error, vp, NULL); break; } error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); @@ -1367,8 +1363,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); error = ENOMEM; - SDT_PROBE(vfs, namecache, fullpath, return, error, - startvp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, error, + startvp, NULL); break; } buf[--buflen] = '/'; @@ -1381,8 +1377,8 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); numfullpathfail4++; - SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM, - startvp, NULL, 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, ENOMEM, + startvp, NULL); return (ENOMEM); } buf[--buflen] = '/'; @@ -1391,8 +1387,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, CACHE_RUNLOCK(); vrele(vp); - SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen, - 0, 0); + SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen); *retbuf = buf + buflen; return (0); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 0d1f2e8..8236f32 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -273,8 +273,8 @@ namei(struct nameidata *ndp) if (ndp->ni_startdir != NULL) vrele(ndp->ni_startdir); } - SDT_PROBE(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf, - cnp->cn_flags, 0, 0); + SDT_PROBE3(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf, + cnp->cn_flags); for (;;) { /* * Check if root directory should replace current directory. @@ -302,8 +302,7 @@ namei(struct nameidata *ndp) error = lookup(ndp); if (error) { namei_cleanup_cnp(cnp); - SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0, - 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, error, NULL); return (error); } /* @@ -315,8 +314,7 @@ namei(struct nameidata *ndp) } else cnp->cn_flags |= HASBUF; - SDT_PROBE(vfs, namei, lookup, return, 0, ndp->ni_vp, - 0, 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, 0, ndp->ni_vp); return (0); } if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { @@ -377,7 +375,7 @@ namei(struct nameidata *ndp) vput(ndp->ni_vp); ndp->ni_vp = NULL; vrele(ndp->ni_dvp); - SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0, 0, 0); + SDT_PROBE2(vfs, namei, lookup, return, error, NULL); return (error); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 072a8ad..685eaa5 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -2299,9 +2299,9 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, return (error); error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); if (error == 0) { - SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); + SDT_PROBE2(vfs, , stat, mode, path, sb.st_mode); if (S_ISREG(sb.st_mode)) - SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); + SDT_PROBE2(vfs, , stat, reg, path, pathseg); if (__predict_false(hook != NULL)) hook(nd.ni_vp, &sb); } diff --git a/sys/mips/include/pcpu.h b/sys/mips/include/pcpu.h index 89b6525..f4be33d 100644 --- a/sys/mips/include/pcpu.h +++ b/sys/mips/include/pcpu.h @@ -31,6 +31,7 @@ #ifndef _MACHINE_PCPU_H_ #define _MACHINE_PCPU_H_ +#include <machine/cpufunc.h> #include <machine/pte.h> #define PCPU_MD_COMMON_FIELDS \ diff --git a/sys/modules/netgraph/Makefile b/sys/modules/netgraph/Makefile index dc44ac7..03873e4 100644 --- a/sys/modules/netgraph/Makefile +++ b/sys/modules/netgraph/Makefile @@ -62,4 +62,6 @@ _bluetooth= bluetooth _mppc= mppc .endif +SUBDIR_PARALLEL= + .include <bsd.subdir.mk> diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 48eb904..3dc3a81 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -617,9 +617,15 @@ tcp_timer_rexmt(void * xtp) int isipv6; #endif + /* + * Idea here is that at each stage of mtu probe (usually, 1448 + * -> 1188 -> 524) should be given 2 chances to recover before + * further clamping down. 'tp->t_rxtshift % 2 == 0' should + * take care of that. + */ if (((tp->t_flags2 & (TF2_PLPMTU_PMTUD|TF2_PLPMTU_MAXSEGSNT)) == (TF2_PLPMTU_PMTUD|TF2_PLPMTU_MAXSEGSNT)) && - (tp->t_rxtshift <= 2)) { + (tp->t_rxtshift >= 2 && tp->t_rxtshift % 2 == 0)) { /* * Enter Path MTU Black-hole Detection mechanism: * - Disable Path MTU Discovery (IP "DF" bit). @@ -687,9 +693,11 @@ tcp_timer_rexmt(void * xtp) * with a lowered MTU, maybe this isn't a blackhole and * we restore the previous MSS and blackhole detection * flags. + * The limit '6' is determined by giving each probe + * stage (1448, 1188, 524) 2 chances to recover. */ if ((tp->t_flags2 & TF2_PLPMTU_BLACKHOLE) && - (tp->t_rxtshift > 4)) { + (tp->t_rxtshift > 6)) { tp->t_flags2 |= TF2_PLPMTU_PMTUD; tp->t_flags2 &= ~TF2_PLPMTU_BLACKHOLE; optlen = tp->t_maxopd - tp->t_maxseg; diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c index d2bd378..228b2aa 100644 --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -73,7 +73,7 @@ static struct svc_callout *svc_find(SVCPOOL *pool, rpcprog_t, rpcvers_t, char *); static void svc_new_thread(SVCGROUP *grp); static void xprt_unregister_locked(SVCXPRT *xprt); -static void svc_change_space_used(SVCPOOL *pool, int delta); +static void svc_change_space_used(SVCPOOL *pool, long delta); static bool_t svc_request_space_available(SVCPOOL *pool); /* *************** SVCXPRT related stuff **************** */ @@ -113,13 +113,14 @@ svcpool_create(const char *name, struct sysctl_oid_list *sysctl_base) } /* - * Don't use more than a quarter of mbuf clusters or more than - * 45Mb buffering requests. + * Don't use more than a quarter of mbuf clusters. Nota bene: + * nmbclusters is an int, but nmbclusters*MCLBYTES may overflow + * on LP64 architectures, so cast to u_long to avoid undefined + * behavior. (ILP32 architectures cannot have nmbclusters + * large enough to overflow for other reasons.) */ - pool->sp_space_high = nmbclusters * MCLBYTES / 4; - if (pool->sp_space_high > 45 << 20) - pool->sp_space_high = 45 << 20; - pool->sp_space_low = 2 * pool->sp_space_high / 3; + pool->sp_space_high = (u_long)nmbclusters * MCLBYTES / 4; + pool->sp_space_low = (pool->sp_space_high / 3) * 2; sysctl_ctx_init(&pool->sp_sysctl); if (sysctl_base) { @@ -139,24 +140,24 @@ svcpool_create(const char *name, struct sysctl_oid_list *sysctl_base) "groups", CTLFLAG_RD, &pool->sp_groupcount, 0, "Number of thread groups"); - SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, + SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, "request_space_used", CTLFLAG_RD, - &pool->sp_space_used, 0, + &pool->sp_space_used, "Space in parsed but not handled requests."); - SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, + SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, "request_space_used_highest", CTLFLAG_RD, - &pool->sp_space_used_highest, 0, + &pool->sp_space_used_highest, "Highest space used since reboot."); - SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, + SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, "request_space_high", CTLFLAG_RW, - &pool->sp_space_high, 0, + &pool->sp_space_high, "Maximum space in parsed but not handled requests."); - SYSCTL_ADD_UINT(&pool->sp_sysctl, sysctl_base, OID_AUTO, + SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO, "request_space_low", CTLFLAG_RW, - &pool->sp_space_low, 0, + &pool->sp_space_low, "Low water mark for request space."); SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO, @@ -1064,11 +1065,11 @@ svc_assign_waiting_sockets(SVCPOOL *pool) } static void -svc_change_space_used(SVCPOOL *pool, int delta) +svc_change_space_used(SVCPOOL *pool, long delta) { - unsigned int value; + unsigned long value; - value = atomic_fetchadd_int(&pool->sp_space_used, delta) + delta; + value = atomic_fetchadd_long(&pool->sp_space_used, delta) + delta; if (delta > 0) { if (value >= pool->sp_space_high && !pool->sp_space_throttled) { pool->sp_space_throttled = TRUE; @@ -1102,7 +1103,7 @@ svc_run_internal(SVCGROUP *grp, bool_t ismaster) enum xprt_stat stat; struct svc_req *rqstp; struct proc *p; - size_t sz; + long sz; int error; st = mem_alloc(sizeof(*st)); @@ -1259,17 +1260,16 @@ svc_run_internal(SVCGROUP *grp, bool_t ismaster) /* * Execute what we have queued. */ - sz = 0; mtx_lock(&st->st_lock); while ((rqstp = STAILQ_FIRST(&st->st_reqs)) != NULL) { STAILQ_REMOVE_HEAD(&st->st_reqs, rq_link); mtx_unlock(&st->st_lock); - sz += rqstp->rq_size; + sz = (long)rqstp->rq_size; svc_executereq(rqstp); + svc_change_space_used(pool, -sz); mtx_lock(&st->st_lock); } mtx_unlock(&st->st_lock); - svc_change_space_used(pool, -sz); mtx_lock(&grp->sg_lock); } diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h index 1c7bbce..80285ec 100644 --- a/sys/rpc/svc.h +++ b/sys/rpc/svc.h @@ -371,10 +371,10 @@ typedef struct __rpc_svcpool { * amount of memory used by RPC requests which are queued * waiting for execution. */ - unsigned int sp_space_low; - unsigned int sp_space_high; - unsigned int sp_space_used; - unsigned int sp_space_used_highest; + unsigned long sp_space_low; + unsigned long sp_space_high; + unsigned long sp_space_used; + unsigned long sp_space_used_highest; bool_t sp_space_throttled; int sp_space_throttle_count; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index b9606f8..3b188ca 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -170,6 +170,7 @@ struct procdesc; struct racct; struct sbuf; struct sleepqueue; +struct syscall_args; struct td_sched; struct thread; struct trapframe; @@ -320,6 +321,8 @@ struct thread { struct vm_page **td_ma; /* (k) uio pages held */ int td_ma_cnt; /* (k) size of *td_ma */ void *td_su; /* (k) FFS SU private */ + u_int td_dbg_sc_code; /* (c) Syscall code to debugger. */ + u_int td_dbg_sc_narg; /* (c) Syscall arg count to debugger.*/ }; struct mtx *thread_lock_block(struct thread *); @@ -934,7 +937,6 @@ void userret(struct thread *, struct trapframe *); void cpu_exit(struct thread *); void exit1(struct thread *, int) __dead2; -struct syscall_args; int cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa); void cpu_fork(struct thread *, struct proc *, struct thread *, int); void cpu_set_fork_handler(struct thread *, void (*)(void *), void *); diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index e770a06..de4e7a7 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -113,6 +113,8 @@ struct ptrace_lwpinfo { struct __siginfo pl_siginfo; /* siginfo for signal */ char pl_tdname[MAXCOMLEN + 1]; /* LWP name */ int pl_child_pid; /* New child pid */ + u_int pl_syscall_code; + u_int pl_syscall_narg; }; /* Argument structure for PT_VM_ENTRY. */ diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h index ca820f6..5dd0b67 100644 --- a/sys/sys/sdt.h +++ b/sys/sys/sdt.h @@ -398,7 +398,7 @@ struct sdt_probe { struct sdt_provider *prov; /* Ptr to the provider structure. */ TAILQ_ENTRY(sdt_probe) probe_entry; /* SDT probe list entry. */ - TAILQ_HEAD(argtype_list_head, sdt_argtype) argtype_list; + TAILQ_HEAD(, sdt_argtype) argtype_list; const char *mod; const char *func; const char *name; diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk index 04f9046..9e88181 100644 --- a/sys/tools/vnode_if.awk +++ b/sys/tools/vnode_if.awk @@ -361,7 +361,7 @@ while ((getline < srcfile) > 0) { printc("\t vop->"name" == NULL && vop->vop_bypass == NULL)") printc("\t\tvop = vop->vop_default;") printc("\tVNASSERT(vop != NULL, a->a_" args[0]", (\"No "name"(%p, %p)\", a->a_" args[0]", a));") - printc("\tSDT_PROBE(vfs, vop, " name ", entry, a->a_" args[0] ", a, 0, 0, 0);\n"); + printc("\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);\n"); for (i = 0; i < numargs; ++i) add_debug_code(name, args[i], "Entry", "\t"); printc("\tKTR_START" ctrstr); @@ -372,7 +372,7 @@ while ((getline < srcfile) > 0) { printc("\telse") printc("\t\trc = vop->vop_bypass(&a->a_gen);") printc("\tVFS_EPILOGUE(a->a_" args[0]"->v_mount);") - printc("\tSDT_PROBE(vfs, vop, " name ", return, a->a_" args[0] ", a, rc, 0, 0);\n"); + printc("\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);\n"); printc("\tif (rc == 0) {"); for (i = 0; i < numargs; ++i) add_debug_code(name, args[i], "OK", "\t\t"); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index ed80b1b..2cc738d 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -286,11 +286,21 @@ vm_pageout_fallback_object_lock(vm_page_t m, vm_page_t *next) vm_page_lock(m); vm_pagequeue_lock(pq); - /* Page queue might have changed. */ + /* + * The page's object might have changed, and/or the page might + * have moved from its original position in the queue. If the + * page's object has changed, then the caller should abandon + * processing the page because the wrong object lock was + * acquired. Use the marker's plinks.q, not the page's, to + * determine if the page has been moved. The state of the + * page's plinks.q can be indeterminate; whereas, the marker's + * plinks.q must be valid. + */ *next = TAILQ_NEXT(&marker, plinks.q); - unchanged = (m->queue == queue && - m->object == object && - &marker == TAILQ_NEXT(m, plinks.q)); + unchanged = m->object == object && + m == TAILQ_PREV(&marker, pglist, plinks.q); + KASSERT(!unchanged || m->queue == queue, + ("page %p queue %d %d", m, queue, m->queue)); TAILQ_REMOVE(&pq->pq_pl, &marker, plinks.q); return (unchanged); } @@ -327,7 +337,9 @@ vm_pageout_page_lock(vm_page_t m, vm_page_t *next) /* Page queue might have changed. */ *next = TAILQ_NEXT(&marker, plinks.q); - unchanged = (m->queue == queue && &marker == TAILQ_NEXT(m, plinks.q)); + unchanged = m == TAILQ_PREV(&marker, pglist, plinks.q); + KASSERT(!unchanged || m->queue == queue, + ("page %p queue %d %d", m, queue, m->queue)); TAILQ_REMOVE(&pq->pq_pl, &marker, plinks.q); return (unchanged); } diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c index 1804595..a576a48 100644 --- a/sys/x86/x86/identcpu.c +++ b/sys/x86/x86/identcpu.c @@ -1887,6 +1887,18 @@ print_INTEL_TLB(u_int data) case 0x68: printf("1st-level data cache: 32 KB, 4 way set associative, sectored cache, 64 byte line size\n"); break; + case 0x6a: + printf("uTLB: 4KByte pages, 8-way set associative, 64 entries\n"); + break; + case 0x6b: + printf("DTLB: 4KByte pages, 8-way set associative, 256 entries\n"); + break; + case 0x6c: + printf("DTLB: 2M/4M pages, 8-way set associative, 126 entries\n"); + break; + case 0x6d: + printf("DTLB: 1 GByte pages, fully associative, 16 entries\n"); + break; case 0x70: printf("Trace cache: 12K-uops, 8-way set associative\n"); break; |