From bb6a0f10730aac2c1b9c631b261cb507ff467bc6 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 1 Sep 2013 14:15:31 +0000 Subject: Add the device ID for a new flavor of FTDI serial adapter (model 232EX). --- sys/dev/usb/serial/uftdi.c | 1 + sys/dev/usb/usbdevs | 1 + 2 files changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index bc971ec..439cd8f 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -243,6 +243,7 @@ static const STRUCT_USB_HOST_ID uftdi_devs[] = { UFTDI_DEV(FALCOM, TWIST, UFTDI_TYPE_8U232AM), UFTDI_DEV(FIC, NEO1973_DEBUG, UFTDI_TYPE_AUTO | UFTDI_FLAG_JTAG), UFTDI_DEV(FIC, NEO1973_DEBUG, UFTDI_TYPE_AUTO | UFTDI_FLAG_JTAG), + UFTDI_DEV(FTDI, 232EX, UFTDI_TYPE_AUTO), UFTDI_DEV(FTDI, 232H, UFTDI_TYPE_AUTO), UFTDI_DEV(FTDI, 232RL, UFTDI_TYPE_AUTO), UFTDI_DEV(FTDI, 4N_GALAXY_DE_1, UFTDI_TYPE_AUTO), diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 498d424..3074530 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1776,6 +1776,7 @@ product FTDI SERIAL_8U232AM4 0x6004 8U232AM Serial product FTDI SERIAL_232RL 0x6006 FT232RL Serial product FTDI SERIAL_2232C 0x6010 FT2232C Dual port Serial product FTDI 232H 0x6014 FTDI compatible adapter +product FTDI 232EX 0x6015 FTDI compatible adapter product FTDI SERIAL_2232D 0x9e90 FT2232D Dual port Serial product FTDI SERIAL_4232H 0x6011 FT4232H Quad port Serial product FTDI BEAGLEBONE 0xa6d0 BeagleBone -- cgit v1.1 From f9897c6dd3d2e00bc25d5857c3c6b2be50c7efea Mon Sep 17 00:00:00 2001 From: alc Date: Sun, 1 Sep 2013 17:06:14 +0000 Subject: pmap_protect() on MIPS does not need to acquire the pvh global lock. --- sys/mips/mips/pmap.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sys') diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index ebb6935..d1bf5ea 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -1914,7 +1914,6 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) if (prot & VM_PROT_WRITE) return; - rw_wlock(&pvh_global_lock); PMAP_LOCK(pmap); for (; sva < eva; sva = va_next) { pdpe = pmap_segmap(pmap, sva); @@ -1980,7 +1979,6 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) if (va != va_next) pmap_invalidate_range(pmap, va, sva); } - rw_wunlock(&pvh_global_lock); PMAP_UNLOCK(pmap); } -- cgit v1.1 From 7351998cf8dfb6696100874613c8237166a17c86 Mon Sep 17 00:00:00 2001 From: mav Date: Sun, 1 Sep 2013 17:37:19 +0000 Subject: Add debug trace points for freeze/release device queue. --- sys/cam/cam_debug.h | 11 ++++++++++ sys/cam/cam_periph.c | 3 +++ sys/cam/cam_xpt.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/cam/cam_xpt.h | 4 ++++ 4 files changed, 75 insertions(+) (limited to 'sys') diff --git a/sys/cam/cam_debug.h b/sys/cam/cam_debug.h index e072ec1..ecfeb3a 100644 --- a/sys/cam/cam_debug.h +++ b/sys/cam/cam_debug.h @@ -99,6 +99,17 @@ extern u_int32_t cam_debug_delay; DELAY(cam_debug_delay); \ } +#define CAM_DEBUG_DEV(dev, flag, printfargs) \ + if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags) \ + && (cam_dpath != NULL) \ + && (xpt_path_comp_dev(cam_dpath, dev) >= 0) \ + && (xpt_path_comp_dev(cam_dpath, dev) < 2)) { \ + xpt_print_device(dev); \ + printf printfargs; \ + if (cam_debug_delay != 0) \ + DELAY(cam_debug_delay); \ + } + #define CAM_DEBUG_PRINT(flag, printfargs) \ if (((flag) & (CAM_DEBUG_COMPILE) & cam_dflags)) { \ printf("cam_debug: "); \ diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index d6f7746..b230c6c 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -1115,6 +1115,7 @@ cam_freeze_devq(struct cam_path *path) { struct ccb_hdr ccb_h; + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("cam_freeze_devq\n")); xpt_setup_ccb(&ccb_h, path, /*priority*/1); ccb_h.func_code = XPT_NOOP; ccb_h.flags = CAM_DEV_QFREEZE; @@ -1128,6 +1129,8 @@ cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, { struct ccb_relsim crs; + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("cam_release_devq(%u, %u, %u, %d)\n", + relsim_flags, openings, arg, getcount_only)); xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL); crs.ccb_h.func_code = XPT_REL_SIMQ; crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0; diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index da0b4da..e50b0ad 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -3561,6 +3561,40 @@ xpt_path_comp(struct cam_path *path1, struct cam_path *path2) return (retval); } +int +xpt_path_comp_dev(struct cam_path *path, struct cam_ed *dev) +{ + int retval = 0; + + if (path->bus != dev->target->bus) { + if (path->bus->path_id == CAM_BUS_WILDCARD) + retval = 1; + else if (dev->target->bus->path_id == CAM_BUS_WILDCARD) + retval = 2; + else + return (-1); + } + if (path->target != dev->target) { + if (path->target->target_id == CAM_TARGET_WILDCARD) { + if (retval == 0) + retval = 1; + } else if (dev->target->target_id == CAM_TARGET_WILDCARD) + retval = 2; + else + return (-1); + } + if (path->device != dev) { + if (path->device->lun_id == CAM_LUN_WILDCARD) { + if (retval == 0) + retval = 1; + } else if (dev->lun_id == CAM_LUN_WILDCARD) + retval = 2; + else + return (-1); + } + return (retval); +} + void xpt_print_path(struct cam_path *path) { @@ -3594,6 +3628,21 @@ xpt_print_path(struct cam_path *path) } void +xpt_print_device(struct cam_ed *device) +{ + + if (device == NULL) + printf("(nopath): "); + else { + printf("(noperiph:%s%d:%d:%d:%d): ", device->sim->sim_name, + device->sim->unit_number, + device->sim->bus_id, + device->target->target_id, + device->lun_id); + } +} + +void xpt_print(struct cam_path *path, const char *fmt, ...) { va_list ap; @@ -4114,6 +4163,8 @@ xpt_freeze_devq(struct cam_path *path, u_int count) struct cam_ed *dev = path->device; mtx_assert(path->bus->sim->mtx, MA_OWNED); + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_freeze_devq() %u->%u\n", + dev->ccbq.queue.qfrozen_cnt, dev->ccbq.queue.qfrozen_cnt + count)); dev->ccbq.queue.qfrozen_cnt += count; /* Remove frozen device from sendq. */ if (device_is_queued(dev)) { @@ -4138,6 +4189,7 @@ xpt_release_devq_timeout(void *arg) struct cam_ed *device; device = (struct cam_ed *)arg; + CAM_DEBUG_DEV(device, CAM_DEBUG_TRACE, ("xpt_release_devq_timeout\n")); xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE); } @@ -4146,6 +4198,8 @@ xpt_release_devq(struct cam_path *path, u_int count, int run_queue) { mtx_assert(path->bus->sim->mtx, MA_OWNED); + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_devq(%d, %d)\n", + count, run_queue)); xpt_release_devq_device(path->device, count, run_queue); } @@ -4153,6 +4207,9 @@ void xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue) { + CAM_DEBUG_DEV(dev, CAM_DEBUG_TRACE, + ("xpt_release_devq_device(%d, %d) %u->%u\n", count, run_queue, + dev->ccbq.queue.qfrozen_cnt, dev->ccbq.queue.qfrozen_cnt - count)); if (count > dev->ccbq.queue.qfrozen_cnt) { #ifdef INVARIANTS printf("xpt_release_devq(): requested %u > present %u\n", diff --git a/sys/cam/cam_xpt.h b/sys/cam/cam_xpt.h index 492fa3a..97933b9 100644 --- a/sys/cam/cam_xpt.h +++ b/sys/cam/cam_xpt.h @@ -35,6 +35,7 @@ /* Forward Declarations */ union ccb; struct cam_periph; +struct cam_ed; struct cam_sim; /* @@ -89,7 +90,10 @@ void xpt_path_counts(struct cam_path *path, uint32_t *bus_ref, uint32_t *device_ref); int xpt_path_comp(struct cam_path *path1, struct cam_path *path2); +int xpt_path_comp_dev(struct cam_path *path, + struct cam_ed *dev); void xpt_print_path(struct cam_path *path); +void xpt_print_device(struct cam_ed *device); void xpt_print(struct cam_path *path, const char *fmt, ...); int xpt_path_string(struct cam_path *path, char *str, size_t str_len); -- cgit v1.1 From 112102f8f6823fc3c0802cf6d5da73d112fa9693 Mon Sep 17 00:00:00 2001 From: eadler Date: Sun, 1 Sep 2013 19:27:32 +0000 Subject: Add support for the BCM20702A0 chipset, ASUS USB-BT400. PR: kern/181728 Submitted by: rakuco --- sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c index 2009cca..edbd32c 100644 --- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c +++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c @@ -494,6 +494,7 @@ static const STRUCT_USB_HOST_ID ubt_devs[] = /* Broadcom BCM20702A0 */ { USB_VPI(USB_VENDOR_ASUS, 0x17b5, 0) }, + { USB_VPI(USB_VENDOR_ASUS, 0x17cb, 0) }, { USB_VPI(USB_VENDOR_LITEON, 0x2003, 0) }, { USB_VPI(USB_VENDOR_FOXCONN, 0xe042, 0) }, { USB_VPI(USB_VENDOR_DELL, 0x8197, 0) }, -- cgit v1.1 From d8615bd83a5530f8770f104327704aeeee9b4092 Mon Sep 17 00:00:00 2001 From: rpaulo Date: Sun, 1 Sep 2013 20:15:35 +0000 Subject: Initial support for the Digi ConnectCore(c) i.MX53 / Wi-i.MX53 boards. There are many drivers missing, but we can reach single user mode now. Hardware graciously donated by Douglas Beattie. --- sys/arm/conf/DIGI-CCWMX53 | 175 +++++++++ sys/arm/freescale/imx/files.imx53 | 51 +++ sys/arm/freescale/imx/imx51_ccm.c | 3 +- sys/arm/freescale/imx/imx51_gpio.c | 3 +- sys/arm/freescale/imx/imx51_iomux.c | 3 +- sys/arm/freescale/imx/imx51_machdep.c | 2 +- sys/arm/freescale/imx/imx53_machdep.c | 141 +++++++ sys/arm/freescale/imx/imx_gpt.c | 3 +- sys/arm/freescale/imx/imx_wdog.c | 3 +- sys/arm/freescale/imx/std.imx53 | 15 + sys/boot/fdt/dts/digi-ccwmx53.dts | 123 ++++++ sys/boot/fdt/dts/imx53x.dtsi | 680 ++++++++++++++++++++++++++++++++++ 12 files changed, 1196 insertions(+), 6 deletions(-) create mode 100644 sys/arm/conf/DIGI-CCWMX53 create mode 100644 sys/arm/freescale/imx/files.imx53 create mode 100644 sys/arm/freescale/imx/imx53_machdep.c create mode 100644 sys/arm/freescale/imx/std.imx53 create mode 100644 sys/boot/fdt/dts/digi-ccwmx53.dts create mode 100644 sys/boot/fdt/dts/imx53x.dtsi (limited to 'sys') diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53 new file mode 100644 index 0000000..5aec9fe --- /dev/null +++ b/sys/arm/conf/DIGI-CCWMX53 @@ -0,0 +1,175 @@ +# Kernel configuration for Digi ConnectCore Wi-i.MX53 boards +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +ident DIGI-CCWMX53 + +include "../freescale/imx/std.imx53" + +makeoptions WITHOUT_MODULES="ahc" + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +#options DEBUG + +options SCHED_4BSD # 4BSD scheduler +#options PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +options INET6 # IPv6 communications protocols +#options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +#options MD_ROOT # MD is a potential root device +options NFSCL # New Network Filesystem Client +#options NFSD # New Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +#options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # TMP Memory Filesystem +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_LABEL # Provides labelization +#options COMPAT_FREEBSD5 # Compatible with FreeBSD5 +#options COMPAT_FREEBSD6 # Compatible with FreeBSD6 +#options COMPAT_FREEBSD7 # Compatible with FreeBSD7 +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options INCLUDE_CONFIG_FILE # Include this file in kernel +options VFP # vfp/neon + +# required for netbooting +#options BOOTP +#options BOOTP_COMPAT +#options BOOTP_NFSROOT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ue0 + +#options ROOTDEVNAME=\"ufs:ada0s2a\" + + +# kernel/memory size reduction +#options MUTEX_NOINLINE +#options NO_FFS_SNAPSHOT +#options NO_SWAPPING +#options NO_SYSCTL_DESCR +#options RWLOCK_NOINLINE + +# Debugging support. Always need this: +options KDB # Enable kernel debugger support. +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic. +# For full debugger support use this instead: +options DDB # Support DDB. +#options GDB # Support remote GDB. +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +#device vlan # 802.1Q VLAN support +#device tun # Packet tunnel. +#device md # Memory "disks" +#device gif # IPv6 and IPv4 tunneling +#device faith # IPv6-to-IPv4 relaying (translation) +#device firmware # firmware assist module + +# Serial (COM) ports +#device uart # Multi-uart driver +options ALT_BREAK_TO_DEBUGGER + +device ata +device atapci # Only for helper functions +device imxata +options ATA_STATIC_ID # Static device numbering + +device iomux # IO Multiplexor + +device gpio +device gpioled + +device fsliic +device iic +device iicbus + +# SCSI peripherals +device scbus # SCSI bus (required for SCSI) +device da # Direct Access (disks) +device cd # CD +device pass # Passthrough device (direct SCSI access) + +# USB support +#options USB_DEBUG # enable debug msgs +#device ehci # OHCI USB interface +#device usb # USB Bus (required) +#device umass # Disks/Mass storage - Requires scbus and da +#device uhid # "Human Interface Devices" +#device ukbd # Allow keyboard like HIDs to control console +#device ums + +# USB Ethernet, requires miibus +#device miibus +#device aue # ADMtek USB Ethernet +#device axe # ASIX Electronics USB Ethernet +#device cdce # Generic USB over Ethernet +#device cue # CATC USB Ethernet +#device kue # Kawasaki LSI USB Ethernet +#device rue # RealTek RTL8150 USB Ethernet +#device udav # Davicom DM9601E USB + +# USB Wireless +#device rum # Ralink Technology RT2501USB wireless NICs + +# Watchdog timer. +# WARNING: can't be disabled!!! +device imxwdt # Watchdog + +# Wireless NIC cards +device wlan # 802.11 support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm + +# Flattened Device Tree +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=digi-ccwmx53.dts + +# NOTE: serial console will be disabled if syscons enabled +# Uncomment following lines for framebuffer/syscons support +#device sc +#device kbdmux +#options SC_DFLT_FONT # compile font in +#makeoptions SC_DFLT_FONT=cp437 diff --git a/sys/arm/freescale/imx/files.imx53 b/sys/arm/freescale/imx/files.imx53 new file mode 100644 index 0000000..5d709ed --- /dev/null +++ b/sys/arm/freescale/imx/files.imx53 @@ -0,0 +1,51 @@ +# $FreeBSD$ +arm/arm/bus_space_asm_generic.S standard +arm/arm/bus_space_generic.c standard +arm/arm/cpufunc_asm_armv5.S standard +arm/arm/cpufunc_asm_arm11.S standard +arm/arm/cpufunc_asm_armv7.S standard +arm/arm/irq_dispatch.S standard +kern/kern_clocksource.c standard + +# Init +arm/freescale/imx/imx53_machdep.c standard +arm/freescale/imx/common.c standard +arm/freescale/imx/bus_space.c standard + +# Dummy serial console +arm/freescale/imx/console.c standard + +# TrustZone Interrupt Controller +arm/freescale/imx/tzic.c standard + +# IOMUX - external pins multiplexor +arm/freescale/imx/imx51_iomux.c optional iomux + +# GPIO +arm/freescale/imx/imx51_gpio.c optional gpio + +# Generic Periodic Timer +arm/freescale/imx/imx_gpt.c standard + +# Clock Configuration Manager +arm/freescale/imx/imx51_ccm.c standard + +# i.MX5xx PATA controller +dev/ata/chipsets/ata-fsl.c optional imxata + +# UART driver +#dev/uart/uart_dev_imx.c optional uart + +# USB join controller (1 OTG, 3 EHCI) +dev/usb/controller/ehci_imx.c optional ehci + +# Watchdog +arm/freescale/imx/imx_wdog.c optional imxwdt + +# i2c +arm/freescale/imx/i2c.c optional fsliic +dev/ofw/ofw_iicbus.c optional fsliic + +# IPU - Image Processing Unit (frame buffer also) +arm/freescale/imx/imx51_ipuv3.c optional sc + diff --git a/sys/arm/freescale/imx/imx51_ccm.c b/sys/arm/freescale/imx/imx51_ccm.c index 529dd74..e8b4699 100644 --- a/sys/arm/freescale/imx/imx51_ccm.c +++ b/sys/arm/freescale/imx/imx51_ccm.c @@ -140,7 +140,8 @@ static int imxccm_match(device_t dev) { - if (!ofw_bus_is_compatible(dev, "fsl,imx51-ccm")) + if (!ofw_bus_is_compatible(dev, "fsl,imx51-ccm") && + !ofw_bus_is_compatible(dev, "fsl,imx53-ccm")) return (ENXIO); device_set_desc(dev, "Freescale Clock Control Module"); diff --git a/sys/arm/freescale/imx/imx51_gpio.c b/sys/arm/freescale/imx/imx51_gpio.c index ecccf8e..f9890a8 100644 --- a/sys/arm/freescale/imx/imx51_gpio.c +++ b/sys/arm/freescale/imx/imx51_gpio.c @@ -370,7 +370,8 @@ static int imx51_gpio_probe(device_t dev) { - if (ofw_bus_is_compatible(dev, "fsl,imx51-gpio")) { + if (ofw_bus_is_compatible(dev, "fsl,imx51-gpio") || + ofw_bus_is_compatible(dev, "fsl,imx53-gpio")) { device_set_desc(dev, "i.MX515 GPIO Controller"); return (BUS_PROBE_DEFAULT); } diff --git a/sys/arm/freescale/imx/imx51_iomux.c b/sys/arm/freescale/imx/imx51_iomux.c index a37776e..5096f2c 100644 --- a/sys/arm/freescale/imx/imx51_iomux.c +++ b/sys/arm/freescale/imx/imx51_iomux.c @@ -106,7 +106,8 @@ static int iomux_probe(device_t dev) { - if (!ofw_bus_is_compatible(dev, "fsl,imx51-iomux")) + if (!ofw_bus_is_compatible(dev, "fsl,imx51-iomux") && + !ofw_bus_is_compatible(dev, "fsl,imx53-iomux")) return (ENXIO); device_set_desc(dev, "Freescale i.MX51 IO pins multiplexor"); diff --git a/sys/arm/freescale/imx/imx51_machdep.c b/sys/arm/freescale/imx/imx51_machdep.c index 640fe6f..291c8c6 100644 --- a/sys/arm/freescale/imx/imx51_machdep.c +++ b/sys/arm/freescale/imx/imx51_machdep.c @@ -107,7 +107,7 @@ platform_devmap_init(void) * Map segment where UART1 and UART2 located. */ fdt_devmap[0].pd_va = IMX51_DEV_VIRT_BASE + 0x03f00000; - fdt_devmap[0].pd_pa = 0x73f00000; + fdt_devmap[0].pd_pa = 0x53f00000; fdt_devmap[0].pd_size = 0x00100000; fdt_devmap[0].pd_prot = VM_PROT_READ | VM_PROT_WRITE; fdt_devmap[0].pd_cache = PTE_NOCACHE; diff --git a/sys/arm/freescale/imx/imx53_machdep.c b/sys/arm/freescale/imx/imx53_machdep.c new file mode 100644 index 0000000..0c0a1a6 --- /dev/null +++ b/sys/arm/freescale/imx/imx53_machdep.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1994-1998 Mark Brinicombe. + * Copyright (c) 1994 Brini. + * Copyright (c) 2012, 2013 The FreeBSD Foundation + * All rights reserved. + * + * This code is derived from software written for Brini by Mark Brinicombe + * Portions of this software were developed by Oleksandr Rybalko + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Brini. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_platform.h" + +#include +__FBSDID("$FreeBSD$"); + +#define _ARM32_BUS_DMA_PRIVATE +#include +#include +#include +#include + +#include +#include + +#include +#include /* For trapframe_t, used in */ +#include +#include + +#include + +#define IMX53_DEV_VIRT_BASE 0xe0000000 + +vm_offset_t +initarm_lastaddr(void) +{ + + boothowto |= RB_VERBOSE|RB_MULTIPLE; + bootverbose = 1; + + if (fdt_immr_addr(IMX53_DEV_VIRT_BASE) != 0) + while (1); + + /* Platform-specific initialisation */ + return (fdt_immr_va - ARM_NOCACHE_KVA_SIZE); +} + +/* + * Set initial values of GPIO output ports + */ +void +initarm_gpio_init(void) +{ + +} + +void +initarm_late_init(void) +{ + +} + +#define FDT_DEVMAP_MAX 2 +static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = { + { 0, 0, 0, 0, 0, }, + { 0, 0, 0, 0, 0, } +}; + +/* + * Construct pmap_devmap[] with DT-derived config data. + */ +int +platform_devmap_init(void) +{ + + /* + * Map segment where UART1 and UART2 located. + */ + fdt_devmap[0].pd_va = IMX53_DEV_VIRT_BASE + 0x03f00000; + fdt_devmap[0].pd_pa = 0x53f00000; + fdt_devmap[0].pd_size = 0x00100000; + fdt_devmap[0].pd_prot = VM_PROT_READ | VM_PROT_WRITE; + fdt_devmap[0].pd_cache = PTE_NOCACHE; + + pmap_devmap_bootstrap_table = &fdt_devmap[0]; + + return (0); +} + +struct arm32_dma_range * +bus_dma_get_range(void) +{ + + return (NULL); +} + +int +bus_dma_get_range_nb(void) +{ + + return (0); +} + +void +cpu_reset(void) +{ + + printf("Reset ...\n"); + /* Clear n_reset flag */ + *((volatile u_int16_t *)(IMX53_DEV_VIRT_BASE + 0x03f98000)) = + (u_int16_t)0; + while (1); +} diff --git a/sys/arm/freescale/imx/imx_gpt.c b/sys/arm/freescale/imx/imx_gpt.c index e37ea6b..de726d0 100644 --- a/sys/arm/freescale/imx/imx_gpt.c +++ b/sys/arm/freescale/imx/imx_gpt.c @@ -112,7 +112,8 @@ static int imx_gpt_probe(device_t dev) { - if (!ofw_bus_is_compatible(dev, "fsl,imx51-gpt")) + if (!ofw_bus_is_compatible(dev, "fsl,imx51-gpt") && + !ofw_bus_is_compatible(dev, "fsl,imx53-gpt")) return (ENXIO); device_set_desc(dev, "Freescale i.MX GPT timer"); diff --git a/sys/arm/freescale/imx/imx_wdog.c b/sys/arm/freescale/imx/imx_wdog.c index 86fc256..02c454e 100644 --- a/sys/arm/freescale/imx/imx_wdog.c +++ b/sys/arm/freescale/imx/imx_wdog.c @@ -130,7 +130,8 @@ static int imx_wdog_probe(device_t dev) { - if (!ofw_bus_is_compatible(dev, "fsl,imx51-wdt")) + if (!ofw_bus_is_compatible(dev, "fsl,imx51-wdt") && + !ofw_bus_is_compatible(dev, "fsl,imx53-wdt")) return (ENXIO); device_set_desc(dev, "Freescale i.MX5xx Watchdog Timer"); diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53 new file mode 100644 index 0000000..a7bdba2 --- /dev/null +++ b/sys/arm/freescale/imx/std.imx53 @@ -0,0 +1,15 @@ +# $FreeBSD$ +machine arm armv6 +cpu CPU_CORTEXA +makeoptions ARM_LITTLE_ENDIAN +options ARM_L2_PIPT + +options KERNVIRTADDR=0xc0100000 +makeoptions KERNVIRTADDR=0xc0100000 +options KERNPHYSADDR=0x70100000 +makeoptions KERNPHYSADDR=0x70100000 +options PHYSADDR=0x70000000 +options STARTUP_PAGETABLE_ADDR=0x71000000 + +files "../freescale/imx/files.imx53" + diff --git a/sys/boot/fdt/dts/digi-ccwmx53.dts b/sys/boot/fdt/dts/digi-ccwmx53.dts new file mode 100644 index 0000000..e71262a --- /dev/null +++ b/sys/boot/fdt/dts/digi-ccwmx53.dts @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2013 Rui Paulo + * All rights reserved. + * + * This software was developed by Semihalf under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Digi ConnectCore Wi-i.MX53 + * + * $FreeBSD$ + */ + +/dts-v1/; +/include/ "imx53x.dtsi" + +/ { + model = "Digi ConnectCore Wi-i.MX53"; + compatible = "digi,imx53-ccwm53"; + + memory { + /* RAM 512M */ + reg = <0x70000000 0x20000000>; + }; + + localbus@18000000 { + ipu3@18000000 { + status = "okay"; + }; + }; + + soc@50000000 { + aips@50000000 { + spba@50000000 { + esdhc@50004000 { + clock-frequency = <216000000>; + status = "okay"; + }; + esdhc@50008000 { + clock-frequency = <216000000>; + status = "okay"; + }; + SSI2: ssi@50014000 { + status = "okay"; + }; + }; + timer@53fa0000 { + status = "okay"; + }; + + /* UART1, console */ + UART1: serial@53fbc000 { + status = "okay"; + clock-frequency = <3000000>; /* XXX */ + }; + + clock@53fd4000 { + status = "okay"; + }; + gpio@53f84000 { + status = "okay"; + }; + gpio@53f88000 { + status = "okay"; + }; + gpio@53f8c000 { + status = "okay"; + }; + gpio@53f90000 { + status = "okay"; + }; + wdog@53f98000 { + status = "okay"; + }; + }; + aips@60000000 { + i2c@63fc4000 { + status = "okay"; + }; + i2c@63fc8000 { + status = "okay"; + }; + audmux@63fd4000 { + status = "okay"; + }; + ide@63fe0000 { + status = "okay"; + }; + }; + }; + + aliases { + UART1 = &UART1; + SSI2 = &SSI2; + }; + + chosen { + bootargs = "-v"; + stdin = "UART1"; + stdout = "UART1"; + }; +}; diff --git a/sys/boot/fdt/dts/imx53x.dtsi b/sys/boot/fdt/dts/imx53x.dtsi new file mode 100644 index 0000000..f8675ee --- /dev/null +++ b/sys/boot/fdt/dts/imx53x.dtsi @@ -0,0 +1,680 @@ +/* + * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2013 Rui Paulo + * All rights reserved. + * + * This software was developed by Semihalf under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Freescale i.MX535 Device Tree Source. + * + * $FreeBSD$ + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + soc = &SOC; + }; + + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "ARM,MCIMX535"; + reg = <0x0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x8000>; + i-cache-size = <0x8000>; + l2-cache-line-size = <32>; + l2-cache-line = <0x40000>; + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + }; + + localbus@0fffc000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + /* This reflects CPU decode windows setup. */ + ranges; + + tzic: tz-interrupt-controller@0fffc000 { + compatible = "fsl,imx53-tzic", "fsl,tzic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x0fffc000 0x00004000>; + }; + /* + * 40000000 40000FFF 4K Debug ROM + * 40001000 40001FFF 4K ETB + * 40002000 40002FFF 4K ETM + * 40003000 40003FFF 4K TPIU + * 40004000 40004FFF 4K CTI0 + * 40005000 40005FFF 4K CTI1 + * 40006000 40006FFF 4K CTI2 + * 40007000 40007FFF 4K CTI3 + * 40008000 40008FFF 4K ARM Debug Unit + * + * 0FFFC000 0FFFCFFF 0x4000 TZIC + */ + }; + + SOC: soc@50000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&tzic>; + ranges = <0x50000000 0x14000000>; + + aips@50000000 { /* AIPS1 */ + compatible = "fsl,aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&tzic>; + ranges; + + /* Required by many devices, so better to stay first */ + /* 53FD4000 0x4000 CCM */ + clock@53fd4000 { + compatible = "fsl,imx53-ccm"; + /* 63F80000 0x4000 DPLLIP1 */ + /* 63F84000 0x4000 DPLLIP2 */ + /* 63F88000 0x4000 DPLLIP3 */ + reg = <0x53fd4000 0x4000 + 0x63F80000 0x4000 + 0x63F84000 0x4000 + 0x63F88000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <71 72>; + status = "disabled"; + }; + + /* + * GPIO modules moved up - to have it attached for + * drivers which rely on GPIO + */ + /* 53F84000 0x4000 GPIO1 */ + gpio1: gpio@53f84000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53f84000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <50 51 42 43 44 45 46 47 48 49>; + /* TODO: use <> also */ + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53F88000 0x4000 GPIO2 */ + gpio2: gpio@53f88000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53f88000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <52 53>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53F8C000 0x4000 GPIO3 */ + gpio3: gpio@53f8c000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53f8c000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <54 55>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53F90000 0x4000 GPIO4 */ + gpio4: gpio@53f90000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53f90000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <56 57>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53FDC000 0x4000 GPIO5 */ + gpio5: gpio@53fdc000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53fdc000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <103 104>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53FE0000 0x4000 GPIO6 */ + gpio6: gpio@53fe0000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53fe0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <105 106>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + /* 53FE4000 0x4000 GPIO5 */ + gpio7: gpio@53fe4000 { + compatible = "fsl,imx53-gpio"; + reg = <0x53fe4000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <107 108>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + spba@50000000 { + compatible = "fsl,spba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&tzic>; + ranges; + + /* 50004000 0x4000 ESDHC 1 */ + esdhc@50004000 { + compatible = "fsl,imx53-esdhc"; + reg = <0x50004000 0x4000>; + interrupt-parent = <&tzic>; interrupts = <1>; + status = "disabled"; + }; + + /* 50008000 0x4000 ESDHC 2 */ + esdhc@50008000 { + compatible = "fsl,imx53-esdhc"; + reg = <0x50008000 0x4000>; + interrupt-parent = <&tzic>; interrupts = <2>; + status = "disabled"; + }; + + /* 5000C000 0x4000 UART 3 */ + uart3: serial@5000c000 { + compatible = "fsl,imx53-uart", "fsl,imx-uart"; + reg = <0x5000c000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <33>; + status = "disabled"; + }; + + /* 50010000 0x4000 eCSPI1 */ + ecspi@50010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx53-ecspi"; + reg = <0x50010000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <36>; + status = "disabled"; + }; + + /* 50014000 0x4000 SSI2 irq30 */ + SSI2: ssi@50014000 { + compatible = "fsl,imx53-ssi"; + reg = <0x50014000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <30>; + status = "disabled"; + }; + + /* 50020000 0x4000 ESDHC 3 */ + esdhc@50020000 { + compatible = "fsl,imx53-esdhc"; + reg = <0x50020000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <3>; + status = "disabled"; + }; + + /* 50024000 0x4000 ESDHC 4 */ + esdhc@50024000 { + compatible = "fsl,imx53-esdhc"; + reg = <0x50024000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <4>; + status = "disabled"; + }; + + /* 50028000 0x4000 SPDIF */ + /* 91 SPDIF */ + + /* 50030000 0x4000 PATA (PORT UDMA) irq70 */ + + /* 50034000 0x4000 SLM */ + /* 50038000 0x4000 HSI2C */ + /* 64 HS-I2C */ + /* 5003C000 0x4000 SPBA */ + }; + + /* 73F80000 0x4000 USBOH3 */ + /* irq14 USBOH3 USB Host 1 */ + /* irq16 USBOH3 USB Host 2 */ + /* irq17 USBOH3 USB Host 3 */ + /* irq18 USBOH3 USB OTG */ + usb1: usb@53F80000 { + compatible = "fsl,usb-4core"; + reg = <0x53f80000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <18 14 16 17>; + }; + + /* 53F98000 0x4000 WDOG1 */ + wdog@53f98000 { + compatible = "fsl,imx53-wdt"; + reg = <0x53f98000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <58>; + status = "disabled"; + }; + + /* 53F9C000 0x4000 WDOG2 (TZ) */ + wdog@53f9c000 { + compatible = "fsl,imx53-wdt"; + reg = <0x53f9c000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <59>; + status = "disabled"; + }; + + /* 53F94000 0x4000 KPP */ + keyboard@53f94000 { + compatible = "fsl,imx53-kpp"; + reg = <0x53f94000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <60>; + status = "disabled"; + }; + + /* 53FA0000 0x4000 GPT */ + timer@53fa0000 { + compatible = "fsl,imx53-gpt"; + reg = <0x53fa0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <39>; + status = "disabled"; + }; + + /* 53FA4000 0x4000 SRTC */ + + rtc@53fa4000 { + compatible = "fsl,imx53-srtc"; + reg = <0x53fa4000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <24 25>; + status = "disabled"; + }; + + /* 53FA8000 0x4000 IOMUXC */ + iomux@53fa8000 { + compatible = "fsl,imx53-iomux"; + reg = <0x53fa8000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <7>; + }; + + /* 53FAC000 0x4000 EPIT1 */ + epit1: timer@53fac000 { + compatible = "fsl,imx53-epit"; + reg = <0x53fac000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <40>; + status = "disabled"; + }; + + /* 53FB0000 0x4000 EPIT2 */ + epit2: timer@53fb0000 { + compatible = "fsl,imx53-epit"; + reg = <0x53fb0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <41>; + status = "disabled"; + }; + + /* 53FB4000 0x4000 PWM1 */ + pwm@53fb4000 { + compatible = "fsl,imx53-pwm"; + reg = <0x53fb4000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <61>; + status = "disabled"; + }; + + /* 53FB8000 0x4000 PWM2 */ + pwm@53fb8000 { + compatible = "fsl,imx53-pwm"; + reg = <0x53fb8000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <94>; + status = "disabled"; + }; + + /* 53FBC000 0x4000 UART 1 */ + uart1: serial@53fbc000 { + compatible = "fsl,imx53-uart", "fsl,imx-uart"; + reg = <0x53fbc000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <31>; + status = "disabled"; + }; + + /* 53FC0000 0x4000 UART 2 */ + uart2: serial@53fc0000 { + compatible = "fsl,imx53-uart", "fsl,imx-uart"; + reg = <0x53fc0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <32>; + status = "disabled"; + }; + + /* 53FC0000 0x4000 UART 4 */ + uart4: serial@53ff0000 { + compatible = "fsl,imx53-uart", "fsl,imx-uart"; + reg = <0x53ff0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <13>; + status = "disabled"; + }; + + + + /* 53FC4000 0x4000 USBOH3 */ + /* NOTYET + usb@53fc4000 { + compatible = "fsl,imx53-otg"; + reg = <0x53fc4000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <>; + status = "disabled"; + }; + */ + /* 53FD0000 0x4000 SRC */ + reset@53fd0000 { + compatible = "fsl,imx53-src"; + reg = <0x53fd0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <75>; + status = "disabled"; + }; + /* 53FD8000 0x4000 GPC */ + power@53fd8000 { + compatible = "fsl,imx53-gpc"; + reg = <0x53fd8000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <73 74>; + status = "disabled"; + }; + + /* 53FE8000 0x4000 PATA (PORT PIO) */ + /* 70 PATA Parallel ATA host controller interrupt */ + ide@53fe8000 { + compatible = "fsl,imx53-ata"; + reg = <0x83fe0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <70>; + status = "disabled"; + }; + + }; + + aips@60000000 { /* AIPS2 */ + compatible = "fsl,aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&tzic>; + ranges; + + /* 53FC0000 0x4000 UART 5 */ + uart5: serial@63f90000 { + compatible = "fsl,imx53-uart", "fsl,imx-uart"; + reg = <0x63f90000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <32>; + status = "disabled"; + }; + + /* 63F94000 0x4000 AHBMAX */ + /* 63F98000 0x4000 IIM */ + /* + * 69 IIM Interrupt request to the processor. + * Indicates to the processor that program or + * explicit. + */ + /* 63F9C000 0x4000 CSU */ + /* + * 27 CSU Interrupt Request 1. Indicates to the + * processor that one or more alarm inputs were. + */ + + /* 63FA0000 0x4000 TIGERP_PLATFORM_NE_32K_256K */ + /* irq76 Neon Monitor Interrupt */ + /* irq77 Performance Unit Interrupt */ + /* irq78 CTI IRQ */ + /* irq79 Debug Interrupt, Cross-Trigger Interface 1 */ + /* irq80 Debug Interrupt, Cross-Trigger Interface 1 */ + /* irq89 Debug Interrupt, Cross-Trigger Interface 2 */ + /* irq98 Debug Interrupt, Cross-Trigger Interface 3 */ + + /* 63FA4000 0x4000 OWIRE irq88 */ + /* 63FA8000 0x4000 FIRI irq93 */ + /* 63FAC000 0x4000 eCSPI2 */ + ecspi@63fac000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx53-ecspi"; + reg = <0x63fac000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <37>; + status = "disabled"; + }; + + /* 63FB0000 0x4000 SDMA */ + sdma@63fb0000 { + compatible = "fsl,imx53-sdma"; + reg = <0x63fb0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <6>; + }; + + /* 63FB4000 0x4000 SCC */ + /* 21 SCC Security Monitor High Priority Interrupt. */ + /* 22 SCC Secure (TrustZone) Interrupt. */ + /* 23 SCC Regular (Non-Secure) Interrupt. */ + + /* 63FB8000 0x4000 ROMCP */ + /* 63FBC000 0x4000 RTIC */ + /* + * 26 RTIC RTIC (Trust Zone) Interrupt Request. + * Indicates that the RTIC has completed hashing the + */ + + /* 63FC0000 0x4000 CSPI */ + cspi@63fc0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx53-cspi"; + reg = <0x63fc0000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <38>; + status = "disabled"; + }; + + /* 63FC4000 0x4000 I2C2 */ + i2c@63fc4000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx53-i2c", "fsl,imx1-i2c", "fsl,imx-i2c"; + reg = <0x63fc4000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <63>; + status = "disabled"; + }; + + /* 63FC8000 0x4000 I2C1 */ + i2c@63fc8000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx53-i2c", "fsl,imx1-i2c", "fsl,imx-i2c"; + reg = <0x63fc8000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <62>; + status = "disabled"; + }; + + /* 63FCC000 0x4000 SSI1 */ + /* 29 SSI1 SSI-1 Interrupt Request */ + SSI1: ssi@63fcc000 { + compatible = "fsl,imx53-ssi"; + reg = <0x63fcc000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <29>; + status = "disabled"; + }; + + /* 63FD0000 0x4000 AUDMUX */ + audmux@63fd4000 { + compatible = "fsl,imx53-audmux"; + reg = <0x63fd4000 0x4000>; + status = "disabled"; + }; + + /* 63FD8000 0x4000 EXTMC */ + /* 8 EXTMC (NFC) */ + /* 15 EXTMC */ + /* 97 EXTMC Boot sequence completed interrupt */ + /* + * 101 EMI Indicates all pages have been transferred + * to NFC during an auto program operation. + */ + + /* 83FE4000 0x4000 SIM */ + /* 67 SIM intr composed of oef, xte, sdi1, and sdi0 */ + /* 68 SIM intr composed of tc, etc, tfe, and rdrf */ + + /* 63FD_C000 0x4000 apb2ip_pl301_2x2 */ + /* 63FE_0000 0x4000 apb2ip_pl301_4x1 */ + /* 63FE4000 0x4000 MLB */ + /* 63FE8000 0x4000 SSI3 */ + /* 96 SSI3 SSI-3 Interrupt Request */ + SSI3: ssi@63fe8000 { + compatible = "fsl,imx51-ssi"; + reg = <0x63fe8000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <96>; + status = "disabled"; + }; + + /* 63FEC000 0x4000 FEC */ + ethernet@63fec000 { + compatible = "fsl,imx53-fec"; + reg = <0x63fec000 0x4000>; + interrupt-parent = <&tzic>; + interrupts = <87>; + status = "disabled"; + }; + + /* 63FF0000 0x4000 TVE */ + /* 92 TVE */ + /* 63FF4000 0x4000 VPU */ + /* 9 VPU */ + /* 100 VPU Idle interrupt from VPU */ + + /* 63FF8000 0x4000 SAHARA */ + /* 19 SAHARA SAHARA host 0 (TrustZone) Intr */ + /* 20 SAHARA SAHARA host 1 (non-TrustZone) Intr */ + }; + }; + + localbus@18000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges; + + vga: ipu3@18000000 { + compatible = "fsl,ipu3"; + reg = < + 0x18000000 0x08000 /* CM */ + 0x18008000 0x08000 /* IDMAC */ + 0x18018000 0x08000 /* DP */ + 0x18020000 0x08000 /* IC */ + 0x18028000 0x08000 /* IRT */ + 0x18030000 0x08000 /* CSI0 */ + 0x18038000 0x08000 /* CSI1 */ + 0x18040000 0x08000 /* DI0 */ + 0x18048000 0x08000 /* DI1 */ + 0x18050000 0x08000 /* SMFC */ + 0x18058000 0x08000 /* DC */ + 0x18060000 0x08000 /* DMFC */ + 0x18068000 0x08000 /* VDI */ + 0x19000000 0x20000 /* CPMEM */ + 0x19020000 0x20000 /* LUT */ + 0x19040000 0x20000 /* SRM */ + 0x19060000 0x20000 /* TPM */ + 0x19080000 0x20000 /* DCTMPL */ + >; + interrupt-parent = <&tzic>; + interrupts = < + 10 /* IPUEX Error */ + 11 /* IPUEX Sync */ + >; + status = "disabled"; + }; + }; +}; + +/* + +TODO: Not mapped interrupts + +5 DAP +84 GPU2D (OpenVG) general interrupt +85 GPU2D (OpenVG) busy signal (for S/W power gating feasibility) +12 GPU3D +102 GPU3D Idle interrupt from GPU3D (for S/W power gating) +90 SJC +*/ -- cgit v1.1 From ff37479c6f590240c5fcd62289a558e8e1a81635 Mon Sep 17 00:00:00 2001 From: eadler Date: Sun, 1 Sep 2013 20:22:52 +0000 Subject: Fix build with gcc Reported by: Michael Butler Reviewed by: jilles --- sys/dev/virtio/network/if_vtnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index f757394..5ab4b970b 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -1531,7 +1531,7 @@ vtnet_rxq_csum_by_parse(struct vtnet_rxq *rxq, struct mbuf *m, */ #if 0 if_printf(sc->vtnet_ifp, "cksum offload of unsupported " - "protocol eth_type=%#x proto=%d csum_start=%d + "protocol eth_type=%#x proto=%d csum_start=%d " "csum_offset=%d\n", __func__, eth_type, proto, hdr->csum_start, hdr->csum_offset); #endif -- cgit v1.1 From 0920b58072ea647c12fef5562d389a93bb58e184 Mon Sep 17 00:00:00 2001 From: davide Date: Sun, 1 Sep 2013 21:44:43 +0000 Subject: Complete r250105. Do not zero fields if M_ZERO flag is specified to malloc(9). Reported by: pluknet, glebius --- sys/dev/hwpmc/hwpmc_mod.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sys') diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 86242d9..8e5eac8 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -2026,11 +2026,7 @@ pmc_allocate_owner_descriptor(struct proc *p) /* allocate space for N pointers and one descriptor struct */ po = malloc(sizeof(struct pmc_owner), M_PMC, M_WAITOK|M_ZERO); - po->po_sscount = po->po_error = po->po_flags = po->po_logprocmaps = 0; - po->po_file = NULL; po->po_owner = p; - po->po_kthread = NULL; - LIST_INIT(&po->po_pmcs); LIST_INSERT_HEAD(poh, po, po_next); /* insert into hash table */ TAILQ_INIT(&po->po_logbuffers); @@ -2156,8 +2152,6 @@ pmc_allocate_pmc_descriptor(void) struct pmc *pmc; pmc = malloc(sizeof(struct pmc), M_PMC, M_WAITOK|M_ZERO); - pmc->pm_owner = NULL; - LIST_INIT(&pmc->pm_targets); PMCDBG(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc); -- cgit v1.1 From 09ec5c277c487bd53321f3f207be7a596ea08f65 Mon Sep 17 00:00:00 2001 From: davide Date: Sun, 1 Sep 2013 22:30:24 +0000 Subject: Use single underscore for all parameters name and local variables in bintime_* related functions. This commit completes what was already done by theraven@ for bintime_shift, and just uses a single underscore instead of two (which is a style bug according to Bruce). See r251855 for reference. Reported by: theraven Discussed with: bde Reviewed by: bde --- sys/sys/time.h | 159 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 80 insertions(+), 79 deletions(-) (limited to 'sys') diff --git a/sys/sys/time.h b/sys/sys/time.h index d260cc7..82a7db1 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -56,64 +56,64 @@ struct bintime { }; static __inline void -bintime_addx(struct bintime *bt, uint64_t x) +bintime_addx(struct bintime *_bt, uint64_t _x) { - uint64_t u; + uint64_t _u; - u = bt->frac; - bt->frac += x; - if (u > bt->frac) - bt->sec++; + _u = _bt->frac; + _bt->frac += _x; + if (_u > _bt->frac) + _bt->sec++; } static __inline void -bintime_add(struct bintime *bt, const struct bintime *bt2) +bintime_add(struct bintime *_bt, const struct bintime *_bt2) { - uint64_t u; + uint64_t _u; - u = bt->frac; - bt->frac += bt2->frac; - if (u > bt->frac) - bt->sec++; - bt->sec += bt2->sec; + _u = _bt->frac; + _bt->frac += _bt2->frac; + if (_u > _bt->frac) + _bt->sec++; + _bt->sec += _bt2->sec; } static __inline void -bintime_sub(struct bintime *bt, const struct bintime *bt2) +bintime_sub(struct bintime *_bt, const struct bintime *_bt2) { - uint64_t u; + uint64_t _u; - u = bt->frac; - bt->frac -= bt2->frac; - if (u < bt->frac) - bt->sec--; - bt->sec -= bt2->sec; + _u = _bt->frac; + _bt->frac -= _bt2->frac; + if (_u < _bt->frac) + _bt->sec--; + _bt->sec -= _bt2->sec; } static __inline void -bintime_mul(struct bintime *bt, u_int x) +bintime_mul(struct bintime *_bt, u_int _x) { - uint64_t p1, p2; + uint64_t _p1, _p2; - p1 = (bt->frac & 0xffffffffull) * x; - p2 = (bt->frac >> 32) * x + (p1 >> 32); - bt->sec *= x; - bt->sec += (p2 >> 32); - bt->frac = (p2 << 32) | (p1 & 0xffffffffull); + _p1 = (_bt->frac & 0xffffffffull) * _x; + _p2 = (_bt->frac >> 32) * _x + (_p1 >> 32); + _bt->sec *= _x; + _bt->sec += (_p2 >> 32); + _bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull); } static __inline void -bintime_shift(struct bintime *__bt, int __exp) +bintime_shift(struct bintime *_bt, int _exp) { - if (__exp > 0) { - __bt->sec <<= __exp; - __bt->sec |= __bt->frac >> (64 - __exp); - __bt->frac <<= __exp; - } else if (__exp < 0) { - __bt->frac >>= -__exp; - __bt->frac |= (uint64_t)__bt->sec << (64 + __exp); - __bt->sec >>= -__exp; + if (_exp > 0) { + _bt->sec <<= _exp; + _bt->sec |= _bt->frac >> (64 - _exp); + _bt->frac <<= _exp; + } else if (_exp < 0) { + _bt->frac >>= -_exp; + _bt->frac |= (uint64_t)_bt->sec << (64 + _exp); + _bt->sec >>= -_exp; } } @@ -131,27 +131,27 @@ bintime_shift(struct bintime *__bt, int __exp) #define SBT_1NS (SBT_1S / 1000000000) static __inline int -sbintime_getsec(sbintime_t sbt) +sbintime_getsec(sbintime_t _sbt) { - return (sbt >> 32); + return (_sbt >> 32); } static __inline sbintime_t -bttosbt(const struct bintime bt) +bttosbt(const struct bintime _bt) { - return (((sbintime_t)bt.sec << 32) + (bt.frac >> 32)); + return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32)); } static __inline struct bintime -sbttobt(sbintime_t sbt) +sbttobt(sbintime_t _sbt) { - struct bintime bt; + struct bintime _bt; - bt.sec = sbt >> 32; - bt.frac = sbt << 32; - return (bt); + _bt.sec = _sbt >> 32; + _bt.frac = _sbt << 32; + return (_bt); } /*- @@ -169,73 +169,74 @@ sbttobt(sbintime_t sbt) */ static __inline void -bintime2timespec(const struct bintime *bt, struct timespec *ts) +bintime2timespec(const struct bintime *_bt, struct timespec *_ts) { - ts->tv_sec = bt->sec; - ts->tv_nsec = ((uint64_t)1000000000 * (uint32_t)(bt->frac >> 32)) >> 32; + _ts->tv_sec = _bt->sec; + _ts->tv_nsec = ((uint64_t)1000000000 * + (uint32_t)(_bt->frac >> 32)) >> 32; } static __inline void -timespec2bintime(const struct timespec *ts, struct bintime *bt) +timespec2bintime(const struct timespec *_ts, struct bintime *_bt) { - bt->sec = ts->tv_sec; + _bt->sec = _ts->tv_sec; /* 18446744073 = int(2^64 / 1000000000) */ - bt->frac = ts->tv_nsec * (uint64_t)18446744073LL; + _bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL; } static __inline void -bintime2timeval(const struct bintime *bt, struct timeval *tv) +bintime2timeval(const struct bintime *_bt, struct timeval *_tv) { - tv->tv_sec = bt->sec; - tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(bt->frac >> 32)) >> 32; + _tv->tv_sec = _bt->sec; + _tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32; } static __inline void -timeval2bintime(const struct timeval *tv, struct bintime *bt) +timeval2bintime(const struct timeval *_tv, struct bintime *_bt) { - bt->sec = tv->tv_sec; + _bt->sec = _tv->tv_sec; /* 18446744073709 = int(2^64 / 1000000) */ - bt->frac = tv->tv_usec * (uint64_t)18446744073709LL; + _bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL; } static __inline struct timespec -sbttots(sbintime_t sbt) +sbttots(sbintime_t _sbt) { - struct timespec ts; + struct timespec _ts; - ts.tv_sec = sbt >> 32; - ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)sbt) >> 32; - return (ts); + _ts.tv_sec = _sbt >> 32; + _ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32; + return (_ts); } static __inline sbintime_t -tstosbt(struct timespec ts) +tstosbt(struct timespec _ts) { - return (((sbintime_t)ts.tv_sec << 32) + - (ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32)); + return (((sbintime_t)_ts.tv_sec << 32) + + (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32)); } static __inline struct timeval -sbttotv(sbintime_t sbt) +sbttotv(sbintime_t _sbt) { - struct timeval tv; + struct timeval _tv; - tv.tv_sec = sbt >> 32; - tv.tv_usec = ((uint64_t)1000000 * (uint32_t)sbt) >> 32; - return (tv); + _tv.tv_sec = _sbt >> 32; + _tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32; + return (_tv); } static __inline sbintime_t -tvtosbt(struct timeval tv) +tvtosbt(struct timeval _tv) { - return (((sbintime_t)tv.tv_sec << 32) + - (tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32)); + return (((sbintime_t)_tv.tv_sec << 32) + + (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32)); } #endif /* __BSD_VISIBLE */ @@ -411,10 +412,10 @@ void microuptime(struct timeval *tvp); static __inline sbintime_t sbinuptime(void) { - struct bintime bt; + struct bintime _bt; - binuptime(&bt); - return (bttosbt(bt)); + binuptime(&_bt); + return (bttosbt(_bt)); } void bintime(struct bintime *bt); @@ -428,10 +429,10 @@ void getmicrouptime(struct timeval *tvp); static __inline sbintime_t getsbinuptime(void) { - struct bintime bt; + struct bintime _bt; - getbinuptime(&bt); - return (bttosbt(bt)); + getbinuptime(&_bt); + return (bttosbt(_bt)); } void getbintime(struct bintime *bt); -- cgit v1.1 From 8d06f831a7fd6d823c0aff22030a780f8b8fd05e Mon Sep 17 00:00:00 2001 From: rmacklem Date: Sun, 1 Sep 2013 23:02:59 +0000 Subject: Forced dismounts of NFS mounts can fail when thread(s) are stuck waiting for an RPC reply from the server while holding the mount point busy (mnt_lockref incremented). This happens because dounmount() msleep()s waiting for mnt_lockref to become 0, before calling VFS_UNMOUNT(). This patch adds a new VFS operation called VFS_PURGE(), which the NFS client implements as purging RPCs in progress. Making this call before checking mnt_lockref fixes the problem, by ensuring that the VOP_xxx() calls will fail and unbusy the mount point. Reported by: sbruno Reviewed by: kib MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clvfsops.c | 15 +++++++++++++++ sys/kern/vfs_mount.c | 10 +++++++++- sys/sys/mount.h | 10 ++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 863c418..4a180c5 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -120,6 +120,7 @@ static vfs_root_t nfs_root; static vfs_statfs_t nfs_statfs; static vfs_sync_t nfs_sync; static vfs_sysctl_t nfs_sysctl; +static vfs_purge_t nfs_purge; /* * nfs vfs operations. @@ -134,6 +135,7 @@ static struct vfsops nfs_vfsops = { .vfs_uninit = ncl_uninit, .vfs_unmount = nfs_unmount, .vfs_sysctl = nfs_sysctl, + .vfs_purge = nfs_purge, }; VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY); @@ -1676,6 +1678,19 @@ nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req) } /* + * Purge any RPCs in progress, so that they will all return errors. + * This allows dounmount() to continue as far as VFS_UNMOUNT() for a + * forced dismount. + */ +static void +nfs_purge(struct mount *mp) +{ + struct nfsmount *nmp = VFSTONFS(mp); + + newnfs_nmcancelreqs(nmp); +} + +/* * Extract the information needed by the nlm from the nfs vnode. */ static void diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 493bb98..8f92e10 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1269,8 +1269,16 @@ dounmount(mp, flags, td) } mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_NOINSMNTQ; /* Allow filesystems to detect that a forced unmount is in progress. */ - if (flags & MNT_FORCE) + if (flags & MNT_FORCE) { mp->mnt_kern_flag |= MNTK_UNMOUNTF; + MNT_IUNLOCK(mp); + /* + * Must be done after setting MNTK_UNMOUNTF and before + * waiting for mnt_lockref to become 0. + */ + VFS_PURGE(mp); + MNT_ILOCK(mp); + } error = 0; if (mp->mnt_lockref) { mp->mnt_kern_flag |= MNTK_DRAINING; diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 1a835b7..8f94451 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -609,6 +609,7 @@ typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op, struct sysctl_req *req); typedef void vfs_susp_clean_t(struct mount *mp); typedef void vfs_notify_lowervp_t(struct mount *mp, struct vnode *lowervp); +typedef void vfs_purge_t(struct mount *mp); struct vfsops { vfs_mount_t *vfs_mount; @@ -628,6 +629,7 @@ struct vfsops { vfs_susp_clean_t *vfs_susp_clean; vfs_notify_lowervp_t *vfs_reclaim_lowervp; vfs_notify_lowervp_t *vfs_unlink_lowervp; + vfs_purge_t *vfs_purge; vfs_mount_t *vfs_spare[6]; /* spares for ABI compat */ }; @@ -757,6 +759,14 @@ vfs_statfs_t __vfs_statfs; } \ } while (0) +#define VFS_PURGE(MP) do { \ + if (*(MP)->mnt_op->vfs_purge != NULL) { \ + VFS_PROLOGUE(MP); \ + (*(MP)->mnt_op->vfs_purge)(MP); \ + VFS_EPILOGUE(MP); \ + } \ +} while (0) + #define VFS_KNOTE_LOCKED(vp, hint) do \ { \ if (((vp)->v_vflag & VV_NOKNOTE) == 0) \ -- cgit v1.1 From 3e4464bbe3ad0bffe28f58f47e8994d9ac6bc860 Mon Sep 17 00:00:00 2001 From: davide Date: Sun, 1 Sep 2013 23:34:53 +0000 Subject: Fix socket buffer timeouts precision using the new sbintime_t KPI instead of relying on the tvtohz() workaround. The latter has been introduced lately by jhb@ (r254699) in order to have a fix that can be backported to STABLE. Reported by: Vitja Makarov Reviewed by: jhb (earlier version) --- sys/kern/uipc_debug.c | 2 +- sys/kern/uipc_sockbuf.c | 4 ++-- sys/kern/uipc_socket.c | 7 +++---- sys/sys/sockbuf.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c index 57f4017..128c64b 100644 --- a/sys/kern/uipc_debug.c +++ b/sys/kern/uipc_debug.c @@ -411,7 +411,7 @@ db_print_sockbuf(struct sockbuf *sb, const char *sockbufname, int indent) db_print_indent(indent); db_printf("sb_ctl: %u ", sb->sb_ctl); db_printf("sb_lowat: %d ", sb->sb_lowat); - db_printf("sb_timeo: %d\n", sb->sb_timeo); + db_printf("sb_timeo: %jd\n", sb->sb_timeo); db_print_indent(indent); db_printf("sb_flags: 0x%x (", sb->sb_flags); diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index a09dbc6..9fa8ae0 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -127,9 +127,9 @@ sbwait(struct sockbuf *sb) SOCKBUF_LOCK_ASSERT(sb); sb->sb_flags |= SB_WAIT; - return (msleep(&sb->sb_cc, &sb->sb_mtx, + return (msleep_sbt(&sb->sb_cc, &sb->sb_mtx, (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sbwait", - sb->sb_timeo)); + sb->sb_timeo, 0, 0)); } int diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 75fd04b..639d865 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -2541,7 +2541,7 @@ sosetopt(struct socket *so, struct sockopt *sopt) int error, optval; struct linger l; struct timeval tv; - u_long val; + sbintime_t val; uint32_t val32; #ifdef MAC struct mac extmac; @@ -2703,7 +2703,7 @@ sosetopt(struct socket *so, struct sockopt *sopt) error = EDOM; goto bad; } - val = tvtohz(&tv); + val = tvtosbt(tv); switch (sopt->sopt_name) { case SO_SNDTIMEO: @@ -2857,8 +2857,7 @@ integer: optval = (sopt->sopt_name == SO_SNDTIMEO ? so->so_snd.sb_timeo : so->so_rcv.sb_timeo); - tv.tv_sec = optval / hz; - tv.tv_usec = (optval % hz) * tick; + tv = sbttotv(optval); #ifdef COMPAT_FREEBSD32 if (SV_CURPROC_FLAG(SV_ILP32)) { struct timeval32 tv32; diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h index bfccd74..402a8f0 100644 --- a/sys/sys/sockbuf.h +++ b/sys/sys/sockbuf.h @@ -97,7 +97,7 @@ struct sockbuf { u_int sb_mbmax; /* (c/d) max chars of mbufs to use */ u_int sb_ctl; /* (c/d) non-data chars in buffer */ int sb_lowat; /* (c/d) low water mark */ - int sb_timeo; /* (c/d) timeout for read/write */ + sbintime_t sb_timeo; /* (c/d) timeout for read/write */ short sb_flags; /* (c/d) flags, see below */ int (*sb_upcall)(struct socket *, void *, int); /* (c/d) */ void *sb_upcallarg; /* (c/d) */ -- cgit v1.1 From 55177c016f41c0fa9187ddec1534559ecefea8bb Mon Sep 17 00:00:00 2001 From: gibbs Date: Sun, 1 Sep 2013 23:49:36 +0000 Subject: Conform to style(9). No functional changes. sys/x86/xen/hvm.c: Do not rely on implicit conversion to boolean in expressions (e.g. use "if (rc != 0)" instead of "if (rc)". Line continuations for functions are indented an additional 4 spaces. Insert an empty line if the function has no local variables. Prefer separate initializtion statements to initialzing local variables in their declaration. Braces that are not necessary may be left out. MFC after: 2 weeks --- sys/x86/xen/hvm.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index 0730d94..c689b47 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -92,7 +92,7 @@ xen_hvm_init_hypercall_stubs(void) int i; base = xen_hvm_cpuid_base(); - if (!base) + if (base == 0) return (ENXIO); if (hypercall_stubs == NULL) { @@ -151,7 +151,7 @@ xen_hvm_set_callback(device_t dev) xhp.domid = DOMID_SELF; xhp.index = HVM_PARAM_CALLBACK_IRQ; - if (xen_feature(XENFEAT_hvm_callback_vector)) { + if (xen_feature(XENFEAT_hvm_callback_vector) != 0) { int error; xhp.value = HVM_CALLBACK_VECTOR(IDT_EVTCHN); @@ -161,8 +161,7 @@ xen_hvm_set_callback(device_t dev) return; } printf("Xen HVM callback vector registration failed (%d). " - "Falling back to emulated device interrupt\n", - error); + "Falling back to emulated device interrupt\n", error); } xen_vector_callback_enabled = 0; if (dev == NULL) { @@ -185,7 +184,7 @@ xen_hvm_set_callback(device_t dev) xhp.value = HVM_CALLBACK_PCI_INTX(slot, pin); } - if (HYPERVISOR_hvm_op(HVMOP_set_param, &xhp)) + if (HYPERVISOR_hvm_op(HVMOP_set_param, &xhp) != 0) panic("Can't set evtchn callback"); } @@ -216,6 +215,7 @@ xen_hvm_suspend(void) void xen_hvm_resume(void) { + xen_hvm_init_hypercall_stubs(); xen_hvm_init_shared_info_page(); } @@ -223,6 +223,7 @@ xen_hvm_resume(void) static void xen_hvm_init(void *dummy __unused) { + if (xen_hvm_init_hypercall_stubs() != 0) return; @@ -235,21 +236,20 @@ xen_hvm_init(void *dummy __unused) void xen_hvm_init_cpu(void) { - int cpu = PCPU_GET(acpi_id); - struct vcpu_info *vcpu_info; struct vcpu_register_vcpu_info info; - int rc; + struct vcpu_info *vcpu_info; + int cpu, rc; + cpu = PCPU_GET(acpi_id); vcpu_info = DPCPU_PTR(vcpu_local_info); info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT; info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info)); rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); - if (rc) { + if (rc != 0) DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); - } else { + else DPCPU_SET(vcpu_info, vcpu_info); - } } SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_init, NULL); -- cgit v1.1 From 8159278dbd8e0197c9ca41a8e8a49b78c13ef17f Mon Sep 17 00:00:00 2001 From: glebius Date: Mon, 2 Sep 2013 10:14:25 +0000 Subject: Merge 1.12 of pf_lb.c from OpenBSD, with some changes. Original commit: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit date: 2010/02/04 14:10:12; author: sthen; state: Exp; lines: +24 -19; pf_get_sport() picks a random port from the port range specified in a nat rule. It should check to see if it's in-use (i.e. matches an existing PF state), if it is, it cycles sequentially through other ports until it finds a free one. However the check was being done with the state keys the wrong way round so it was never actually finding the state to be in-use. - switch the keys to correct this, avoiding random state collisions with nat. Fixes PR 6300 and problems reported by robert@ and viq. - check pf_get_sport() return code in pf_test(); if port allocation fails the packet should be dropped rather than sent out untranslated. Help/ok claudio@. Some additional changes to 1.12: - We also need to bzero() the key to zero padding, otherwise key won't match. - Collapse two if blocks into one with ||, since both conditions lead to the same processing. - Only naddr changes in the cycle, so move initialization of other fields above the cycle. - s/u_intXX_t/uintXX_t/g PR: kern/181690 Submitted by: Olivier Cochard-Labbé Sponsored by: Nginx, Inc. --- sys/netpfil/pf/pf_lb.c | 55 ++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'sys') diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c index c82a121..f870bf4 100644 --- a/sys/netpfil/pf/pf_lb.c +++ b/sys/netpfil/pf/pf_lb.c @@ -58,10 +58,9 @@ static struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *, int, int, struct pfi_kif *, struct pf_addr *, u_int16_t, struct pf_addr *, uint16_t, int, struct pf_anchor_stackframe *); -static int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, - struct pf_addr *, struct pf_addr *, u_int16_t, - struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t, - struct pf_src_node **); +static int pf_get_sport(sa_family_t, uint8_t, struct pf_rule *, + struct pf_addr *, uint16_t, struct pf_addr *, uint16_t, struct pf_addr *, + uint16_t *, uint16_t, uint16_t, struct pf_src_node **); #define mix(a,b,c) \ do { \ @@ -210,13 +209,13 @@ pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off, static int pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, - struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, - struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, - struct pf_src_node **sn) + struct pf_addr *saddr, uint16_t sport, struct pf_addr *daddr, + uint16_t dport, struct pf_addr *naddr, uint16_t *nport, uint16_t low, + uint16_t high, struct pf_src_node **sn) { struct pf_state_key_cmp key; struct pf_addr init_addr; - u_int16_t cut; + uint16_t cut; bzero(&init_addr, sizeof(init_addr)); if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn)) @@ -227,34 +226,38 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, high = 65535; } + bzero(&key, sizeof(key)); + key.af = af; + key.proto = proto; + key.port[0] = dport; + PF_ACPY(&key.addr[0], daddr, key.af); + do { - key.af = af; - key.proto = proto; - PF_ACPY(&key.addr[1], daddr, key.af); - PF_ACPY(&key.addr[0], naddr, key.af); - key.port[1] = dport; + PF_ACPY(&key.addr[1], naddr, key.af); /* * port search; start random, step; * similar 2 portloop in in_pcbbind */ if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP || - proto == IPPROTO_ICMP)) { - key.port[0] = dport; - if (pf_find_state_all(&key, PF_IN, NULL) == NULL) - return (0); - } else if (low == 0 && high == 0) { - key.port[0] = *nport; - if (pf_find_state_all(&key, PF_IN, NULL) == NULL) + proto == IPPROTO_ICMP) || (low == 0 && high == 0)) { + /* + * XXX bug: icmp states don't use the id on both sides. + * (traceroute -I through nat) + */ + key.port[1] = sport; + if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { + *nport = sport; return (0); + } } else if (low == high) { - key.port[0] = htons(low); + key.port[1] = htons(low); if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { *nport = htons(low); return (0); } } else { - u_int16_t tmp; + uint16_t tmp; if (low > high) { tmp = low; @@ -265,7 +268,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, cut = htonl(arc4random()) % (1 + high - low) + low; /* low <= cut <= high */ for (tmp = cut; tmp <= high; ++(tmp)) { - key.port[0] = htons(tmp); + key.port[1] = htons(tmp); if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { *nport = htons(tmp); @@ -273,7 +276,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, } } for (tmp = cut - 1; tmp >= low; --(tmp)) { - key.port[0] = htons(tmp); + key.port[1] = htons(tmp); if (pf_find_state_all(&key, PF_IN, NULL) == NULL) { *nport = htons(tmp); @@ -551,8 +554,8 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction, switch (r->action) { case PF_NAT: - if (pf_get_sport(pd->af, pd->proto, r, saddr, daddr, dport, - naddr, nport, r->rpool.proxy_port[0], + if (pf_get_sport(pd->af, pd->proto, r, saddr, sport, daddr, + dport, naddr, nport, r->rpool.proxy_port[0], r->rpool.proxy_port[1], sn)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation (%u-%u) failed\n", -- cgit v1.1 From 8324fc34800d49750576a82222607f14c9136ebc Mon Sep 17 00:00:00 2001 From: mav Date: Mon, 2 Sep 2013 10:44:54 +0000 Subject: Make ELI destruction (including orphanization) less aggressive, making it always wait for provider close. Old algorithm was reported to cause NULL dereference panic on attempt to close provider after softc destruction. If not global workaroung in GEOM, that could even cause destruction with requests still in flight. --- sys/geom/eli/g_eli.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'sys') diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 6819fcc..18e3cc4 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -621,21 +621,19 @@ end: * to close it when this situation occur. */ static void -g_eli_last_close(struct g_eli_softc *sc) +g_eli_last_close(void *arg, int flags __unused) { struct g_geom *gp; - struct g_provider *pp; - char ppname[64]; + char gpname[64]; int error; g_topology_assert(); - gp = sc->sc_geom; - pp = LIST_FIRST(&gp->provider); - strlcpy(ppname, pp->name, sizeof(ppname)); - error = g_eli_destroy(sc, TRUE); + gp = arg; + strlcpy(gpname, gp->name, sizeof(gpname)); + error = g_eli_destroy(gp->softc, TRUE); KASSERT(error == 0, ("Cannot detach %s on last close (error=%d).", - ppname, error)); - G_ELI_DEBUG(0, "Detached %s on last close.", ppname); + gpname, error)); + G_ELI_DEBUG(0, "Detached %s on last close.", gpname); } int @@ -665,7 +663,7 @@ g_eli_access(struct g_provider *pp, int dr, int dw, int de) */ if ((sc->sc_flags & G_ELI_FLAG_RW_DETACH) || (sc->sc_flags & G_ELI_FLAG_WOPEN)) { - g_eli_last_close(sc); + g_post_event(g_eli_last_close, gp, M_WAITOK, NULL); } return (0); } @@ -916,6 +914,10 @@ g_eli_destroy(struct g_eli_softc *sc, boolean_t force) if (force) { G_ELI_DEBUG(1, "Device %s is still open, so it " "cannot be definitely removed.", pp->name); + sc->sc_flags |= G_ELI_FLAG_RW_DETACH; + gp->access = g_eli_access; + g_wither_provider(pp, ENXIO); + return (EBUSY); } else { G_ELI_DEBUG(1, "Device %s is still open (r%dw%de%d).", pp->name, -- cgit v1.1 From 16cb93231c2ffd2887dd604f561e14085f30dcbd Mon Sep 17 00:00:00 2001 From: rpaulo Date: Mon, 2 Sep 2013 17:07:46 +0000 Subject: Revert accidental commit. --- sys/arm/freescale/imx/imx51_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/arm/freescale/imx/imx51_machdep.c b/sys/arm/freescale/imx/imx51_machdep.c index 291c8c6..640fe6f 100644 --- a/sys/arm/freescale/imx/imx51_machdep.c +++ b/sys/arm/freescale/imx/imx51_machdep.c @@ -107,7 +107,7 @@ platform_devmap_init(void) * Map segment where UART1 and UART2 located. */ fdt_devmap[0].pd_va = IMX51_DEV_VIRT_BASE + 0x03f00000; - fdt_devmap[0].pd_pa = 0x53f00000; + fdt_devmap[0].pd_pa = 0x73f00000; fdt_devmap[0].pd_size = 0x00100000; fdt_devmap[0].pd_prot = VM_PROT_READ | VM_PROT_WRITE; fdt_devmap[0].pd_cache = PTE_NOCACHE; -- cgit v1.1 From 8f00835b6506e9ac2956e621e2f6e9c5ccd7c906 Mon Sep 17 00:00:00 2001 From: eadler Date: Mon, 2 Sep 2013 18:25:18 +0000 Subject: synaptics and trackpoint support are stable enough to be on by default. Eventually both options should be removed. Reviewed by: dumbbell --- sys/dev/atkbdc/psm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 541624f..365b815 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -375,10 +375,10 @@ static devclass_t psm_devclass; static int tap_enabled = -1; TUNABLE_INT("hw.psm.tap_enabled", &tap_enabled); -static int synaptics_support = 0; +static int synaptics_support = 1; TUNABLE_INT("hw.psm.synaptics_support", &synaptics_support); -static int trackpoint_support = 0; +static int trackpoint_support = 1; TUNABLE_INT("hw.psm.trackpoint_support", &trackpoint_support); static int verbose = PSM_DEBUG; -- cgit v1.1 From bc5fd7560b59fdb8569673b4c54ba5910c96327c Mon Sep 17 00:00:00 2001 From: dumbbell Date: Mon, 2 Sep 2013 19:15:20 +0000 Subject: psm: Add support for middle and extended buttons on Synaptics touchpads PR: kern/170834 Submitted by: Brandon Gooch Tested by: Artyom Mirgorodskiy MFC after: 1 month --- sys/dev/atkbdc/psm.c | 131 +++++++++++++++++++++++++++++++++++---------------- sys/sys/mouse.h | 5 +- 2 files changed, 95 insertions(+), 41 deletions(-) (limited to 'sys') diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 365b815..5a1fd37 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -2601,14 +2601,14 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, static int guest_buttons; int w, x0, y0; - /* TouchPad PS/2 absolute mode message format + /* TouchPad PS/2 absolute mode message format with capFourButtons: * * Bits: 7 6 5 4 3 2 1 0 (LSB) * ------------------------------------------------ * ipacket[0]: 1 0 W3 W2 0 W1 R L * ipacket[1]: Yb Ya Y9 Y8 Xb Xa X9 X8 * ipacket[2]: Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 - * ipacket[3]: 1 1 Yc Xc 0 W0 D U + * ipacket[3]: 1 1 Yc Xc 0 W0 D^R U^L * ipacket[4]: X7 X6 X5 X4 X3 X2 X1 X0 * ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 * @@ -2622,6 +2622,21 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, * Y: y position * Z: pressure * + * Without capFourButtons but with nExtendeButtons and/or capMiddle + * + * Bits: 7 6 5 4 3 2 1 0 (LSB) + * ------------------------------------------------------ + * ipacket[3]: 1 1 Yc Xc 0 W0 E^R M^L + * ipacket[4]: X7 X6 X5 X4 X3|b7 X2|b5 X1|b3 X0|b1 + * ipacket[5]: Y7 Y6 Y5 Y4 Y3|b8 Y2|b6 Y1|b4 Y0|b2 + * + * Legend: + * M: Middle physical mouse button + * E: Extended mouse buttons reported instead of low bits of X and Y + * b1-b8: Extended mouse buttons + * Only ((nExtendedButtons + 1) >> 1) bits are used in packet + * 4 and 5, for reading X and Y value they should be zeroed. + * * Absolute reportable limits: 0 - 6143. * Typical bezel limits: 1472 - 5472. * Typical edge marings: 1632 - 5312. @@ -2675,8 +2690,10 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, w = 4; } - /* Handle packets from the guest device */ - /* XXX Documentation? */ + /* + * Handle packets from the guest device. See: + * Synaptics PS/2 TouchPad Interfacing Guide, Section 5.1 + */ if (w == 3 && sc->synhw.capPassthrough) { *x = ((pb->ipacket[1] & 0x10) ? pb->ipacket[4] - 256 : pb->ipacket[4]); @@ -2704,36 +2721,49 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, touchpad_buttons |= MOUSE_BUTTON3DOWN; if (sc->synhw.capExtended && sc->synhw.capFourButtons) { - if ((pb->ipacket[3] & 0x01) && (pb->ipacket[0] & 0x01) == 0) + if ((pb->ipacket[3] ^ pb->ipacket[0]) & 0x01) touchpad_buttons |= MOUSE_BUTTON4DOWN; - if ((pb->ipacket[3] & 0x02) && (pb->ipacket[0] & 0x02) == 0) + if ((pb->ipacket[3] ^ pb->ipacket[0]) & 0x02) touchpad_buttons |= MOUSE_BUTTON5DOWN; - } - - /* - * In newer pads - bit 0x02 in the third byte of - * the packet indicates that we have an extended - * button press. - */ - /* XXX Documentation? */ - if (pb->ipacket[3] & 0x02) { - /* - * if directional_scrolls is not 1, we treat any of - * the scrolling directions as middle-click. - */ - if (sc->syninfo.directional_scrolls) { - if (pb->ipacket[4] & 0x01) - touchpad_buttons |= MOUSE_BUTTON4DOWN; - if (pb->ipacket[5] & 0x01) - touchpad_buttons |= MOUSE_BUTTON5DOWN; - if (pb->ipacket[4] & 0x02) - touchpad_buttons |= MOUSE_BUTTON6DOWN; - if (pb->ipacket[5] & 0x02) - touchpad_buttons |= MOUSE_BUTTON7DOWN; - } else { - if ((pb->ipacket[4] & 0x0F) || - (pb->ipacket[5] & 0x0F)) + } else if (sc->synhw.capExtended && sc->synhw.capMiddle) { + /* Middle Button */ + if ((pb->ipacket[0] ^ pb->ipacket[3]) & 0x01) + touchpad_buttons |= MOUSE_BUTTON2DOWN; + } else if (sc->synhw.capExtended && (sc->synhw.nExtendedButtons > 0)) { + /* Extended Buttons */ + if ((pb->ipacket[0] ^ pb->ipacket[3]) & 0x02) { + if (sc->syninfo.directional_scrolls) { + if (pb->ipacket[4] & 0x01) + touchpad_buttons |= MOUSE_BUTTON4DOWN; + if (pb->ipacket[5] & 0x01) + touchpad_buttons |= MOUSE_BUTTON5DOWN; + if (pb->ipacket[4] & 0x02) + touchpad_buttons |= MOUSE_BUTTON6DOWN; + if (pb->ipacket[5] & 0x02) + touchpad_buttons |= MOUSE_BUTTON7DOWN; + } else { touchpad_buttons |= MOUSE_BUTTON2DOWN; + } + + /* + * Zero out bits used by extended buttons to avoid + * misinterpretation of the data absolute position. + * + * The bits represented by + * + * (nExtendedButtons + 1) >> 1 + * + * will be masked out in both bytes. + * The mask for n bits is computed with the formula + * + * (1 << n) - 1 + */ + int maskedbits = 0; + int mask = 0; + maskedbits = (sc->synhw.nExtendedButtons + 1) >> 1; + mask = (1 << maskedbits) - 1; + pb->ipacket[4] &= ~(mask); + pb->ipacket[5] &= ~(mask); } } @@ -4440,15 +4470,20 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc) buttons = 0; synhw.capExtended = (status[0] & 0x80) != 0; if (synhw.capExtended) { - synhw.capPassthrough = (status[2] & 0x80) != 0; - synhw.capSleep = (status[2] & 0x10) != 0; - synhw.capFourButtons = (status[2] & 0x08) != 0; - synhw.capMultiFinger = (status[2] & 0x02) != 0; - synhw.capPalmDetect = (status[2] & 0x01) != 0; + synhw.nExtendedQueries = (status[0] & 0x70) != 0; + synhw.capMiddle = (status[0] & 0x04) != 0; + synhw.capPassthrough = (status[2] & 0x80) != 0; + synhw.capSleep = (status[2] & 0x10) != 0; + synhw.capFourButtons = (status[2] & 0x08) != 0; + synhw.capMultiFinger = (status[2] & 0x02) != 0; + synhw.capPalmDetect = (status[2] & 0x01) != 0; if (verbose >= 2) { printf(" Extended capabilities:\n"); printf(" capExtended: %d\n", synhw.capExtended); + printf(" capMiddle: %d\n", synhw.capMiddle); + printf(" nExtendedQueries: %d\n", + synhw.nExtendedQueries); printf(" capPassthrough: %d\n", synhw.capPassthrough); printf(" capSleep: %d\n", synhw.capSleep); printf(" capFourButtons: %d\n", synhw.capFourButtons); @@ -4457,16 +4492,27 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc) } /* - * If we have bits set in status[0] & 0x70, then we can load + * If nExtendedQueries is 1 or greater, then the TouchPad + * supports this number of extended queries. We can load * more information about buttons using query 0x09. */ - if ((status[0] & 0x70) != 0) { + if (synhw.capExtended && synhw.nExtendedQueries) { if (mouse_ext_command(kbdc, 0x09) == 0) return (FALSE); if (get_mouse_status(kbdc, status, 0, 3) != 3) return (FALSE); - buttons = (status[1] & 0xf0) >> 4; + synhw.nExtendedButtons = (status[1] & 0xf0) >> 4; + /* + * Add the number of extended buttons to the total + * button support count, including the middle button + * if capMiddle support bit is set. + */ + buttons = synhw.nExtendedButtons + synhw.capMiddle; } else + /* + * If the capFourButtons support bit is set, + * add a fourth button to the total button count. + */ buttons = synhw.capFourButtons ? 1 : 0; } if (verbose >= 2) { @@ -4477,6 +4523,12 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc) } /* + * Add the default number of 3 buttons to the total + * count of supported buttons reported above. + */ + buttons += 3; + + /* * Read the mode byte. * * XXX: Note the Synaptics documentation also defines the first @@ -4503,7 +4555,6 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc) /* "Commit" the Set Mode Byte command sent above. */ set_mouse_sampling_rate(kbdc, 20); - buttons += 3; VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons)); if (sc != NULL) { diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h index e0b70ff..40c64d9 100644 --- a/sys/sys/mouse.h +++ b/sys/sys/mouse.h @@ -101,12 +101,15 @@ typedef struct synapticshw { int capPen; int infoSimplC; int infoGeometry; + int nExtendedButtons; int capExtended; + int nExtendedQueries; + int capMiddle; + int capPassthrough; int capSleep; int capFourButtons; int capMultiFinger; int capPalmDetect; - int capPassthrough; } synapticshw_t; /* iftype */ -- cgit v1.1 From b4cbe1bfc4320320e6983f434cac3fc05a15a4a2 Mon Sep 17 00:00:00 2001 From: dumbbell Date: Mon, 2 Sep 2013 19:49:18 +0000 Subject: sys/mouse.h: Move members introduced in r255153 to end of struct synapticshw I didn't know this structure was public and didn't pay enough attention... --- sys/sys/mouse.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h index 40c64d9..e03bc40 100644 --- a/sys/sys/mouse.h +++ b/sys/sys/mouse.h @@ -101,15 +101,15 @@ typedef struct synapticshw { int capPen; int infoSimplC; int infoGeometry; - int nExtendedButtons; int capExtended; - int nExtendedQueries; - int capMiddle; - int capPassthrough; int capSleep; int capFourButtons; int capMultiFinger; int capPalmDetect; + int capPassthrough; + int capMiddle; + int nExtendedButtons; + int nExtendedQueries; } synapticshw_t; /* iftype */ -- cgit v1.1 From 770a4ce79bdc3984cbfaf823903b7a4bcbe2b5f6 Mon Sep 17 00:00:00 2001 From: gibbs Date: Mon, 2 Sep 2013 22:22:56 +0000 Subject: Better conformance to style(9) and organizational cleanup. No functional changes. sys/i386/xen/mp_machdep.c: Remove extra newlines. Group externs, forward delarations, local types, and pcpu data. Wrap at 80 columns. Use parens in return statements. Tab indent members of array initializers. MFC after: 2 weeks --- sys/i386/xen/mp_machdep.c | 91 ++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 40 deletions(-) (limited to 'sys') diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index c070172..7ac1dbb 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -85,20 +85,46 @@ __FBSDID("$FreeBSD$"); #include #include - - #include #include #include #include #include +/*---------------------------- Extern Declarations ---------------------------*/ +extern struct pcpu __pcpu[]; + +extern void Xhypervisor_callback(void); +extern void failsafe_callback(void); +extern void pmap_lazyfix_action(void); + +/*--------------------------- Forward Declarations ---------------------------*/ +static void assign_cpu_ids(void); +static void set_interrupt_apic_ids(void); +static int start_all_aps(void); +static int start_ap(int apic_id); +static void release_aps(void *dummy); + +/*-------------------------------- Local Types -------------------------------*/ +typedef void call_data_func_t(uintptr_t , uintptr_t); + +/* + * Store data from cpu_add() until later in the boot when we actually setup + * the APs. + */ +struct cpu_info { + int cpu_present:1; + int cpu_bsp:1; + int cpu_disabled:1; +}; + +/*-------------------------------- Global Data -------------------------------*/ +static u_int hyperthreading_cpus; +static cpuset_t hyperthreading_cpus_mask; int mp_naps; /* # of Applications processors */ int boot_cpu_id = -1; /* designated BSP */ -extern struct pcpu __pcpu[]; - static int bootAP; static union descriptor *bootAPgdt; @@ -112,8 +138,6 @@ vm_offset_t smp_tlb_addr1; vm_offset_t smp_tlb_addr2; volatile int smp_tlb_wait; -typedef void call_data_func_t(uintptr_t , uintptr_t); - static u_int logical_cpus; static volatile cpuset_t ipi_nmi_pending; @@ -127,11 +151,7 @@ static volatile int aps_ready = 0; * Store data from cpu_add() until later in the boot when we actually setup * the APs. */ -struct cpu_info { - int cpu_present:1; - int cpu_bsp:1; - int cpu_disabled:1; -} static cpu_info[MAX_APIC_ID + 1]; +static struct cpu_info cpu_info[MAX_APIC_ID + 1]; int cpu_apic_ids[MAXCPU]; int apic_cpuids[MAX_APIC_ID + 1]; @@ -141,22 +161,11 @@ static volatile u_int cpu_ipi_pending[MAXCPU]; static int cpu_logical; static int cpu_cores; -static void assign_cpu_ids(void); -static void set_interrupt_apic_ids(void); -int start_all_aps(void); -static int start_ap(int apic_id); -static void release_aps(void *dummy); - -static u_int hyperthreading_cpus; -static cpuset_t hyperthreading_cpus_mask; - -extern void Xhypervisor_callback(void); -extern void failsafe_callback(void); -extern void pmap_lazyfix_action(void); - +/*------------------------------- Per-CPU Data -------------------------------*/ DPCPU_DEFINE(xen_intr_handle_t, ipi_port[NR_IPIS]); DPCPU_DEFINE(struct vcpu_info *, vcpu_info); +/*------------------------------ Implementation ------------------------------*/ struct cpu_group * cpu_topo(void) { @@ -353,14 +362,14 @@ iv_lazypmap(uintptr_t a, uintptr_t b) /* * These start from "IPI offset" APIC_IPI_INTS */ -static call_data_func_t *ipi_vectors[6] = +static call_data_func_t *ipi_vectors[] = { - iv_rendezvous, - iv_invltlb, - iv_invlpg, - iv_invlrng, - iv_invlcache, - iv_lazypmap, + iv_rendezvous, + iv_invltlb, + iv_invlpg, + iv_invlrng, + iv_invlcache, + iv_lazypmap, }; /* @@ -414,7 +423,8 @@ smp_call_function_interrupt(void *unused) atomic_t *finished = &call_data->finished; /* We only handle function IPIs, not bitmap IPIs */ - if (call_data->func_id < APIC_IPI_INTS || call_data->func_id > IPI_BITMAP_VECTOR) + if (call_data->func_id < APIC_IPI_INTS || + call_data->func_id > IPI_BITMAP_VECTOR) panic("invalid function id %u", call_data->func_id); func = ipi_vectors[call_data->func_id - APIC_IPI_INTS]; @@ -494,14 +504,14 @@ xen_smp_cpu_init(unsigned int cpu) printf("[XEN] IPI cpu=%d port=%d vector=CALL_FUNCTION_VECTOR (%d)\n", cpu, xen_intr_port(irq_handle), CALL_FUNCTION_VECTOR); - return 0; + return (0); fail: xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[RESCHEDULE_VECTOR])); DPCPU_ID_SET(cpu, ipi_port[RESCHEDULE_VECTOR], NULL); xen_intr_unbind(DPCPU_ID_GET(cpu, ipi_port[CALL_FUNCTION_VECTOR])); DPCPU_ID_SET(cpu, ipi_port[CALL_FUNCTION_VECTOR], NULL); - return rc; + return (rc); } static void @@ -795,7 +805,7 @@ start_all_aps(void) pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1); /* number of APs actually started */ - return mp_naps; + return (mp_naps); } extern uint8_t *pcpu_boot_stack; @@ -900,7 +910,8 @@ cpu_initialize_context(unsigned int cpu) smp_trap_init(ctxt.trap_ctxt); ctxt.ldt_ents = 0; - ctxt.gdt_frames[0] = (uint32_t)((uint64_t)vtomach(bootAPgdt) >> PAGE_SHIFT); + ctxt.gdt_frames[0] = + (uint32_t)((uint64_t)vtomach(bootAPgdt) >> PAGE_SHIFT); ctxt.gdt_ents = 512; #ifdef __i386__ @@ -960,10 +971,10 @@ start_ap(int apic_id) /* Wait up to 5 seconds for it to start. */ for (ms = 0; ms < 5000; ms++) { if (mp_naps > cpus) - return 1; /* return SUCCESS */ + return (1); /* return SUCCESS */ DELAY(1000); } - return 0; /* return FAILURE */ + return (0); /* return FAILURE */ } static void @@ -1026,7 +1037,8 @@ smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) } static void -smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) +smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, vm_offset_t addr1, + vm_offset_t addr2) { int cpu, ncpu, othercpus; struct _call_data data; @@ -1262,4 +1274,3 @@ release_aps(void *dummy __unused) SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); SYSINIT(start_ipis, SI_SUB_SMP, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL); SYSINIT(start_cpu, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_setup_cpus, NULL); - -- cgit v1.1 From 7d2fcf19325313868b67d9952d27f94df3f54a5e Mon Sep 17 00:00:00 2001 From: tuexen Date: Mon, 2 Sep 2013 22:48:41 +0000 Subject: All changes affect only SCTP-AUTH: * Remove non working code related to SHA224. * Remove support for non-standardised HMAC-IDs using SHA384 and SHA512. * Prefer SHA256 over SHA1. * Minor cleanup. MFC after: 2 weeks --- sys/netinet/sctp_auth.c | 94 +++++++---------------------------------------- sys/netinet/sctp_auth.h | 14 ++----- sys/netinet/sctp_os_bsd.h | 26 ++++++------- sys/netinet/sctp_uio.h | 4 -- 4 files changed, 29 insertions(+), 109 deletions(-) (limited to 'sys') diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 42e2636..0048856 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -703,15 +703,7 @@ sctp_auth_add_hmacid(sctp_hmaclist_t * list, uint16_t hmac_id) return (-1); } if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) && -#ifdef HAVE_SHA224 - (hmac_id != SCTP_AUTH_HMAC_ID_SHA224) && -#endif -#ifdef HAVE_SHA2 - (hmac_id != SCTP_AUTH_HMAC_ID_SHA256) && - (hmac_id != SCTP_AUTH_HMAC_ID_SHA384) && - (hmac_id != SCTP_AUTH_HMAC_ID_SHA512) && -#endif - 1) { + (hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) { return (-1); } /* Now is it already in the list */ @@ -754,8 +746,9 @@ sctp_default_supported_hmaclist(void) new_list = sctp_alloc_hmaclist(2); if (new_list == NULL) return (NULL); - (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1); + /* We prefer SHA256, so list it first */ (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256); + (void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1); return (new_list); } @@ -811,19 +804,13 @@ int sctp_verify_hmac_param(struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs) { uint32_t i; - uint16_t hmac_id; - uint32_t sha1_supported = 0; for (i = 0; i < num_hmacs; i++) { - hmac_id = ntohs(hmacs->hmac_ids[i]); - if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1) - sha1_supported = 1; + if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) { + return (0); + } } - /* all HMAC id's are supported */ - if (sha1_supported == 0) - return (-1); - else - return (0); + return (-1); } sctp_authinfo_t * @@ -877,18 +864,8 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo) switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: return (SCTP_AUTH_DIGEST_LEN_SHA1); -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: - return (SCTP_AUTH_DIGEST_LEN_SHA224); -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: return (SCTP_AUTH_DIGEST_LEN_SHA256); - case SCTP_AUTH_HMAC_ID_SHA384: - return (SCTP_AUTH_DIGEST_LEN_SHA384); - case SCTP_AUTH_HMAC_ID_SHA512: - return (SCTP_AUTH_DIGEST_LEN_SHA512); -#endif default: /* unknown HMAC algorithm: can't do anything */ return (0); @@ -900,17 +877,9 @@ sctp_get_hmac_block_len(uint16_t hmac_algo) { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: -#endif return (64); -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: return (64); - case SCTP_AUTH_HMAC_ID_SHA384: - case SCTP_AUTH_HMAC_ID_SHA512: - return (128); -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -923,23 +892,11 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t * ctx) { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Init(&ctx->sha1); - break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: + SCTP_SHA1_INIT(&ctx->sha1); break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Init(&ctx->sha256); - break; - case SCTP_AUTH_HMAC_ID_SHA384: - SHA384_Init(&ctx->sha384); + SCTP_SHA256_INIT(&ctx->sha256); break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Init(&ctx->sha512); - break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -953,23 +910,11 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t * ctx, { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Update(&ctx->sha1, text, textlen); + SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen); break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: - break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Update(&ctx->sha256, text, textlen); - break; - case SCTP_AUTH_HMAC_ID_SHA384: - SHA384_Update(&ctx->sha384, text, textlen); + SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen); break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Update(&ctx->sha512, text, textlen); - break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ @@ -983,24 +928,11 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t * ctx, { switch (hmac_algo) { case SCTP_AUTH_HMAC_ID_SHA1: - SHA1_Final(digest, &ctx->sha1); + SCTP_SHA1_FINAL(digest, &ctx->sha1); break; -#ifdef HAVE_SHA224 - case SCTP_AUTH_HMAC_ID_SHA224: - break; -#endif -#ifdef HAVE_SHA2 case SCTP_AUTH_HMAC_ID_SHA256: - SHA256_Final(digest, &ctx->sha256); + SCTP_SHA256_FINAL(digest, &ctx->sha256); break; - case SCTP_AUTH_HMAC_ID_SHA384: - /* SHA384 is truncated SHA512 */ - SHA384_Final(digest, &ctx->sha384); - break; - case SCTP_AUTH_HMAC_ID_SHA512: - SHA512_Final(digest, &ctx->sha512); - break; -#endif case SCTP_AUTH_HMAC_ID_RSVD: default: /* unknown HMAC algorithm: can't do anything */ diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h index eac89f6..154bc13 100644 --- a/sys/netinet/sctp_auth.h +++ b/sys/netinet/sctp_auth.h @@ -36,14 +36,12 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_AUTH_H_ #define _NETINET_SCTP_AUTH_H_ +#include /* digest lengths */ #define SCTP_AUTH_DIGEST_LEN_SHA1 20 -#define SCTP_AUTH_DIGEST_LEN_SHA224 28 #define SCTP_AUTH_DIGEST_LEN_SHA256 32 -#define SCTP_AUTH_DIGEST_LEN_SHA384 48 -#define SCTP_AUTH_DIGEST_LEN_SHA512 64 -#define SCTP_AUTH_DIGEST_LEN_MAX 64 +#define SCTP_AUTH_DIGEST_LEN_MAX SCTP_AUTH_DIGEST_LEN_SHA256 /* random sizes */ #define SCTP_AUTH_RANDOM_SIZE_DEFAULT 32 @@ -52,12 +50,8 @@ __FBSDID("$FreeBSD$"); /* union of all supported HMAC algorithm contexts */ typedef union sctp_hash_context { - SHA1_CTX sha1; -#ifdef HAVE_SHA2 - SHA256_CTX sha256; - SHA384_CTX sha384; - SHA512_CTX sha512; -#endif + SCTP_SHA1_CTX sha1; + SCTP_SHA256_CTX sha256; } sctp_hash_context_t; typedef struct sctp_key { diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 252ea93..2159bbc 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -104,6 +104,9 @@ __FBSDID("$FreeBSD$"); #include +#include +#include + #ifndef in6pcb #define in6pcb inpcb #endif @@ -468,23 +471,18 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, /* * SCTP AUTH */ -#define HAVE_SHA2 - #define SCTP_READ_RANDOM(buf, len) read_random(buf, len) -#ifdef USE_SCTP_SHA1 -#include -#else -#include /* map standard crypto API names */ -#define SHA1_Init SHA1Init -#define SHA1_Update SHA1Update -#define SHA1_Final(x,y) SHA1Final((caddr_t)x, y) -#endif - -#if defined(HAVE_SHA2) -#include -#endif +#define SCTP_SHA1_CTX SHA1_CTX +#define SCTP_SHA1_INIT SHA1Init +#define SCTP_SHA1_UPDATE SHA1Update +#define SCTP_SHA1_FINAL(x,y) SHA1Final((caddr_t)x, y) + +#define SCTP_SHA256_CTX SHA256_CTX +#define SCTP_SHA256_INIT SHA256_Init +#define SCTP_SHA256_UPDATE SHA256_Update +#define SCTP_SHA256_FINAL(x,y) SHA256_Final((caddr_t)x, y) #endif diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index d482c61..1295391 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -662,10 +662,6 @@ struct sctp_hmacalgo { #define SCTP_AUTH_HMAC_ID_RSVD 0x0000 #define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */ #define SCTP_AUTH_HMAC_ID_SHA256 0x0003 -#define SCTP_AUTH_HMAC_ID_SHA224 0x0004 -#define SCTP_AUTH_HMAC_ID_SHA384 0x0005 -#define SCTP_AUTH_HMAC_ID_SHA512 0x0006 - /* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */ struct sctp_authkeyid { -- cgit v1.1 From 5a8454fde7ad8eb79d59d5a9a686541ab11f29f6 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Mon, 2 Sep 2013 23:22:05 +0000 Subject: Whitespace cleanup. --- sys/cddl/dev/dtrace/powerpc/dtrace_subr.c | 96 +++++++++++++++---------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'sys') diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c index d22f207..d58cf92 100644 --- a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c @@ -213,8 +213,8 @@ dtrace_gethrtime_init(void *arg) CPU_SET(pc->pc_cpuid, &map); smp_rendezvous_cpus(map, NULL, - dtrace_gethrtime_init_cpu, - smp_no_rendevous_barrier, (void *)(uintptr_t) i); + dtrace_gethrtime_init_cpu, + smp_no_rendevous_barrier, (void *)(uintptr_t) i); timebase_skew[i] = tgt_cpu_tsc - hst_cpu_tsc; } @@ -247,7 +247,7 @@ dtrace_gethrtime() lo = timebase; hi = timebase >> 32; return (((lo * nsec_scale) >> SCALE_SHIFT) + - ((hi * nsec_scale) << (32 - SCALE_SHIFT))); + ((hi * nsec_scale) << (32 - SCALE_SHIFT))); } uint64_t @@ -280,34 +280,34 @@ dtrace_trap(struct trapframe *frame, u_int type) * All the rest will be handled in the usual way. */ switch (type) { - /* Page fault. */ - case EXC_DSI: - case EXC_DSE: - /* Flag a bad address. */ - cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; - cpu_core[curcpu].cpuc_dtrace_illval = frame->cpu.aim.dar; - - /* - * Offset the instruction pointer to the instruction - * following the one causing the fault. - */ - frame->srr0 += sizeof(int); - return (1); - case EXC_ISI: - case EXC_ISE: - /* Flag a bad address. */ - cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; - cpu_core[curcpu].cpuc_dtrace_illval = frame->srr0; - - /* - * Offset the instruction pointer to the instruction - * following the one causing the fault. - */ - frame->srr0 += sizeof(int); - return (1); - default: - /* Handle all other traps in the usual way. */ - break; + /* Page fault. */ + case EXC_DSI: + case EXC_DSE: + /* Flag a bad address. */ + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; + cpu_core[curcpu].cpuc_dtrace_illval = frame->cpu.aim.dar; + + /* + * Offset the instruction pointer to the instruction + * following the one causing the fault. + */ + frame->srr0 += sizeof(int); + return (1); + case EXC_ISI: + case EXC_ISE: + /* Flag a bad address. */ + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR; + cpu_core[curcpu].cpuc_dtrace_illval = frame->srr0; + + /* + * Offset the instruction pointer to the instruction + * following the one causing the fault. + */ + frame->srr0 += sizeof(int); + return (1); + default: + /* Handle all other traps in the usual way. */ + break; } } @@ -321,29 +321,29 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, { dtrace_probe(dtrace_probeid_error, (uint64_t)(uintptr_t)state, - (uintptr_t)epid, - (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs); + (uintptr_t)epid, + (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs); } static int dtrace_invop_start(struct trapframe *frame) { switch (dtrace_invop(frame->srr0, (uintptr_t *)frame, frame->fixreg[3])) { - case DTRACE_INVOP_JUMP: - break; - case DTRACE_INVOP_BCTR: - frame->srr0 = frame->ctr; - break; - case DTRACE_INVOP_BLR: - frame->srr0 = frame->lr; - break; - case DTRACE_INVOP_MFLR_R0: - frame->fixreg[0] = frame->lr; - frame->srr0 = frame->srr0 + 4; - break; - default: - return (-1); - break; + case DTRACE_INVOP_JUMP: + break; + case DTRACE_INVOP_BCTR: + frame->srr0 = frame->ctr; + break; + case DTRACE_INVOP_BLR: + frame->srr0 = frame->lr; + break; + case DTRACE_INVOP_MFLR_R0: + frame->fixreg[0] = frame->lr; + frame->srr0 = frame->srr0 + 4; + break; + default: + return (-1); + break; } return (0); -- cgit v1.1 From d6366593f2ee55a600f6df2bb72fab4bf8cc6d6a Mon Sep 17 00:00:00 2001 From: tuexen Date: Mon, 2 Sep 2013 23:27:53 +0000 Subject: Use uint16_t instead of in_port_t for consistency with the SCTP code. MFC after: 1 week --- sys/netinet/sctp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 50e1ed9..ddd9175 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3561,7 +3561,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er static struct sctp_tcb * sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p, - in_port_t port, + uint16_t port, struct mbuf *control, struct sctp_nets **net_p, int *error) -- cgit v1.1 From 241d6ad5a0c8a52a564eacc5aa40d69099a3339e Mon Sep 17 00:00:00 2001 From: jhibbits Date: Tue, 3 Sep 2013 00:34:18 +0000 Subject: Refactor PowerPC hwpmc(4) driver into generic and specific. More refactoring will likely be done as more drivers are added, since AIM-compatible processors have similar PMC configuration logic. --- sys/dev/hwpmc/hwpmc_mpc7xxx.c | 748 ++++++++++++++++++++++++++++++++++++++++ sys/dev/hwpmc/hwpmc_powerpc.c | 758 +++-------------------------------------- sys/dev/hwpmc/hwpmc_powerpc.h | 60 ++++ sys/modules/hwpmc/Makefile | 2 +- sys/powerpc/include/pmc_mdep.h | 3 +- 5 files changed, 855 insertions(+), 716 deletions(-) create mode 100644 sys/dev/hwpmc/hwpmc_mpc7xxx.c create mode 100644 sys/dev/hwpmc/hwpmc_powerpc.h (limited to 'sys') diff --git a/sys/dev/hwpmc/hwpmc_mpc7xxx.c b/sys/dev/hwpmc/hwpmc_mpc7xxx.c new file mode 100644 index 0000000..93b5c74 --- /dev/null +++ b/sys/dev/hwpmc/hwpmc_mpc7xxx.c @@ -0,0 +1,748 @@ +/*- + * Copyright (c) 2011 Justin Hibbits + * Copyright (c) 2005, Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include + +#include "hwpmc_powerpc.h" + +#define POWERPC_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \ + PMC_CAP_SYSTEM | PMC_CAP_EDGE | \ + PMC_CAP_THRESHOLD | PMC_CAP_READ | \ + PMC_CAP_WRITE | PMC_CAP_INVERT | \ + PMC_CAP_QUALIFIER) + +#define PPC_SET_PMC1SEL(r, x) ((r & ~(SPR_MMCR0_PMC1SEL(0x3f))) | SPR_MMCR0_PMC1SEL(x)) +#define PPC_SET_PMC2SEL(r, x) ((r & ~(SPR_MMCR0_PMC2SEL(0x3f))) | SPR_MMCR0_PMC2SEL(x)) +#define PPC_SET_PMC3SEL(r, x) ((r & ~(SPR_MMCR1_PMC3SEL(0x1f))) | SPR_MMCR1_PMC3SEL(x)) +#define PPC_SET_PMC4SEL(r, x) ((r & ~(SPR_MMCR1_PMC4SEL(0x1f))) | SPR_MMCR1_PMC4SEL(x)) +#define PPC_SET_PMC5SEL(r, x) ((r & ~(SPR_MMCR1_PMC5SEL(0x1f))) | SPR_MMCR1_PMC5SEL(x)) +#define PPC_SET_PMC6SEL(r, x) ((r & ~(SPR_MMCR1_PMC6SEL(0x3f))) | SPR_MMCR1_PMC6SEL(x)) + +/* Change this when we support more than just the 7450. */ +#define MPC7XXX_MAX_PMCS 6 + +#define MPC7XXX_PMC_HAS_OVERFLOWED(x) (mpc7xxx_pmcn_read(x) & (0x1 << 31)) + +/* + * Things to improve on this: + * - It stops (clears to 0) the PMC and resets it at every context switch + * currently. + */ + +/* + * This should work for every 32-bit PowerPC implementation I know of (G3 and G4 + * specifically). + */ + +struct powerpc_event_code_map { + enum pmc_event pe_ev; /* enum value */ + uint8_t pe_counter_mask; /* Which counter this can be counted in. */ + uint8_t pe_code; /* numeric code */ +}; + +#define PPC_PMC_MASK1 0 +#define PPC_PMC_MASK2 1 +#define PPC_PMC_MASK3 2 +#define PPC_PMC_MASK4 3 +#define PPC_PMC_MASK5 4 +#define PPC_PMC_MASK6 5 +#define PPC_PMC_MASK_ALL 0x3f +#define PMC_POWERPC_EVENT(id, mask, number) \ + { .pe_ev = PMC_EV_PPC7450_##id, .pe_counter_mask = mask, .pe_code = number } + +static struct powerpc_event_code_map powerpc_event_codes[] = { + PMC_POWERPC_EVENT(CYCLE,PPC_PMC_MASK_ALL, 1), + PMC_POWERPC_EVENT(INSTR_COMPLETED, 0x0f, 2), + PMC_POWERPC_EVENT(TLB_BIT_TRANSITIONS, 0x0f, 3), + PMC_POWERPC_EVENT(INSTR_DISPATCHED, 0x0f, 4), + PMC_POWERPC_EVENT(PMON_EXCEPT, 0x0f, 5), + PMC_POWERPC_EVENT(PMON_SIG, 0x0f, 7), + PMC_POWERPC_EVENT(VPU_INSTR_COMPLETED, 0x03, 8), + PMC_POWERPC_EVENT(VFPU_INSTR_COMPLETED, 0x03, 9), + PMC_POWERPC_EVENT(VIU1_INSTR_COMPLETED, 0x03, 10), + PMC_POWERPC_EVENT(VIU2_INSTR_COMPLETED, 0x03, 11), + PMC_POWERPC_EVENT(MTVSCR_INSTR_COMPLETED, 0x03, 12), + PMC_POWERPC_EVENT(MTVRSAVE_INSTR_COMPLETED, 0x03, 13), + PMC_POWERPC_EVENT(VPU_INSTR_WAIT_CYCLES, 0x03, 14), + PMC_POWERPC_EVENT(VFPU_INSTR_WAIT_CYCLES, 0x03, 15), + PMC_POWERPC_EVENT(VIU1_INSTR_WAIT_CYCLES, 0x03, 16), + PMC_POWERPC_EVENT(VIU2_INSTR_WAIT_CYCLES, 0x03, 17), + PMC_POWERPC_EVENT(MFVSCR_SYNC_CYCLES, 0x03, 18), + PMC_POWERPC_EVENT(VSCR_SAT_SET, 0x03, 19), + PMC_POWERPC_EVENT(STORE_INSTR_COMPLETED, 0x03, 20), + PMC_POWERPC_EVENT(L1_INSTR_CACHE_MISSES, 0x03, 21), + PMC_POWERPC_EVENT(L1_DATA_SNOOPS, 0x03, 22), + PMC_POWERPC_EVENT(UNRESOLVED_BRANCHES, 0x01, 23), + PMC_POWERPC_EVENT(SPEC_BUFFER_CYCLES, 0x01, 24), + PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_CYCLES, 0x01, 25), + PMC_POWERPC_EVENT(TRUE_BRANCH_TARGET_HITS, 0x01, 26), + PMC_POWERPC_EVENT(BRANCH_LINK_STAC_PREDICTED, 0x01, 27), + PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_DISPATCHES, 0x01, 28), + PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_DISPATCHED, 0x01, 29), + PMC_POWERPC_EVENT(THRESHOLD_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 30), + PMC_POWERPC_EVENT(THRESHOLD_VEC_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 31), + PMC_POWERPC_EVENT(CYCLES_NO_COMPLETED_INSTRS, 0x01, 32), + PMC_POWERPC_EVENT(IU2_INSTR_COMPLETED, 0x01, 33), + PMC_POWERPC_EVENT(BRANCHES_COMPLETED, 0x01, 34), + PMC_POWERPC_EVENT(EIEIO_INSTR_COMPLETED, 0x01, 35), + PMC_POWERPC_EVENT(MTSPR_INSTR_COMPLETED, 0x01, 36), + PMC_POWERPC_EVENT(SC_INSTR_COMPLETED, 0x01, 37), + PMC_POWERPC_EVENT(LS_LM_COMPLETED, 0x01, 38), + PMC_POWERPC_EVENT(ITLB_HW_TABLE_SEARCH_CYCLES, 0x01, 39), + PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x01, 40), + PMC_POWERPC_EVENT(L1_INSTR_CACHE_ACCESSES, 0x01, 41), + PMC_POWERPC_EVENT(INSTR_BKPT_MATCHES, 0x01, 42), + PMC_POWERPC_EVENT(L1_DATA_CACHE_LOAD_MISS_CYCLES_OVER_THRESHOLD, 0x01, 43), + PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_ON_MODIFIED, 0x01, 44), + PMC_POWERPC_EVENT(LOAD_MISS_ALIAS, 0x01, 45), + PMC_POWERPC_EVENT(LOAD_MISS_ALIAS_ON_TOUCH, 0x01, 46), + PMC_POWERPC_EVENT(TOUCH_ALIAS, 0x01, 47), + PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT_QUEUE, 0x01, 48), + PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT, 0x01, 49), + PMC_POWERPC_EVENT(L1_DATA_SNOOP_HITS, 0x01, 50), + PMC_POWERPC_EVENT(WRITE_THROUGH_STORES, 0x01, 51), + PMC_POWERPC_EVENT(CACHE_INHIBITED_STORES, 0x01, 52), + PMC_POWERPC_EVENT(L1_DATA_LOAD_HIT, 0x01, 53), + PMC_POWERPC_EVENT(L1_DATA_TOUCH_HIT, 0x01, 54), + PMC_POWERPC_EVENT(L1_DATA_STORE_HIT, 0x01, 55), + PMC_POWERPC_EVENT(L1_DATA_TOTAL_HITS, 0x01, 56), + PMC_POWERPC_EVENT(DST_INSTR_DISPATCHED, 0x01, 57), + PMC_POWERPC_EVENT(REFRESHED_DSTS, 0x01, 58), + PMC_POWERPC_EVENT(SUCCESSFUL_DST_TABLE_SEARCHES, 0x01, 59), + PMC_POWERPC_EVENT(DSS_INSTR_COMPLETED, 0x01, 60), + PMC_POWERPC_EVENT(DST_STREAM_0_CACHE_LINE_FETCHES, 0x01, 61), + PMC_POWERPC_EVENT(VTQ_SUSPENDS_DUE_TO_CTX_CHANGE, 0x01, 62), + PMC_POWERPC_EVENT(VTQ_LINE_FETCH_HIT, 0x01, 63), + PMC_POWERPC_EVENT(VEC_LOAD_INSTR_COMPLETED, 0x01, 64), + PMC_POWERPC_EVENT(FP_STORE_INSTR_COMPLETED_IN_LSU, 0x01, 65), + PMC_POWERPC_EVENT(FPU_RENORMALIZATION, 0x01, 66), + PMC_POWERPC_EVENT(FPU_DENORMALIZATION, 0x01, 67), + PMC_POWERPC_EVENT(FP_STORE_CAUSES_STALL_IN_LSU, 0x01, 68), + PMC_POWERPC_EVENT(LD_ST_TRUE_ALIAS_STALL, 0x01, 70), + PMC_POWERPC_EVENT(LSU_INDEXED_ALIAS_STALL, 0x01, 71), + PMC_POWERPC_EVENT(LSU_ALIAS_VS_FSQ_WB0_WB1, 0x01, 72), + PMC_POWERPC_EVENT(LSU_ALIAS_VS_CSQ, 0x01, 73), + PMC_POWERPC_EVENT(LSU_LOAD_HIT_LINE_ALIAS_VS_CSQ0, 0x01, 74), + PMC_POWERPC_EVENT(LSU_LOAD_MISS_LINE_ALIAS_VS_CSQ0, 0x01, 75), + PMC_POWERPC_EVENT(LSU_TOUCH_LINE_ALIAS_VS_FSQ_WB0_WB1, 0x01, 76), + PMC_POWERPC_EVENT(LSU_TOUCH_ALIAS_VS_CSQ, 0x01, 77), + PMC_POWERPC_EVENT(LSU_LMQ_FULL_STALL, 0x01, 78), + PMC_POWERPC_EVENT(FP_LOAD_INSTR_COMPLETED_IN_LSU, 0x01, 79), + PMC_POWERPC_EVENT(FP_LOAD_SINGLE_INSTR_COMPLETED_IN_LSU, 0x01, 80), + PMC_POWERPC_EVENT(FP_LOAD_DOUBLE_COMPLETED_IN_LSU, 0x01, 81), + PMC_POWERPC_EVENT(LSU_RA_LATCH_STALL, 0x01, 82), + PMC_POWERPC_EVENT(LSU_LOAD_VS_STORE_QUEUE_ALIAS_STALL, 0x01, 83), + PMC_POWERPC_EVENT(LSU_LMQ_INDEX_ALIAS, 0x01, 84), + PMC_POWERPC_EVENT(LSU_STORE_QUEUE_INDEX_ALIAS, 0x01, 85), + PMC_POWERPC_EVENT(LSU_CSQ_FORWARDING, 0x01, 86), + PMC_POWERPC_EVENT(LSU_MISALIGNED_LOAD_FINISH, 0x01, 87), + PMC_POWERPC_EVENT(LSU_MISALIGN_STORE_COMPLETED, 0x01, 88), + PMC_POWERPC_EVENT(LSU_MISALIGN_STALL, 0x01, 89), + PMC_POWERPC_EVENT(FP_ONE_QUARTER_FPSCR_RENAMES_BUSY, 0x01, 90), + PMC_POWERPC_EVENT(FP_ONE_HALF_FPSCR_RENAMES_BUSY, 0x01, 91), + PMC_POWERPC_EVENT(FP_THREE_QUARTERS_FPSCR_RENAMES_BUSY, 0x01, 92), + PMC_POWERPC_EVENT(FP_ALL_FPSCR_RENAMES_BUSY, 0x01, 93), + PMC_POWERPC_EVENT(FP_DENORMALIZED_RESULT, 0x01, 94), + PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISSES, 0x02, 23), + PMC_POWERPC_EVENT(DISPATCHES_TO_FPR_ISSUE_QUEUE, 0x02, 24), + PMC_POWERPC_EVENT(LSU_INSTR_COMPLETED, 0x02, 25), + PMC_POWERPC_EVENT(LOAD_INSTR_COMPLETED, 0x02, 26), + PMC_POWERPC_EVENT(SS_SM_INSTR_COMPLETED, 0x02, 27), + PMC_POWERPC_EVENT(TLBIE_INSTR_COMPLETED, 0x02, 28), + PMC_POWERPC_EVENT(LWARX_INSTR_COMPLETED, 0x02, 29), + PMC_POWERPC_EVENT(MFSPR_INSTR_COMPLETED, 0x02, 30), + PMC_POWERPC_EVENT(REFETCH_SERIALIZATION, 0x02, 31), + PMC_POWERPC_EVENT(COMPLETION_QUEUE_ENTRIES_OVER_THRESHOLD, 0x02, 32), + PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x02, 33), + PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x02, 34), + PMC_POWERPC_EVENT(ITLB_NON_SPECULATIVE_MISSES, 0x02, 35), + PMC_POWERPC_EVENT(CYCLES_WAITING_FROM_L1_INSTR_CACHE_MISS, 0x02, 36), + PMC_POWERPC_EVENT(L1_DATA_LOAD_ACCESS_MISS, 0x02, 37), + PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS, 0x02, 38), + PMC_POWERPC_EVENT(L1_DATA_STORE_MISS, 0x02, 39), + PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS_CYCLES, 0x02, 40), + PMC_POWERPC_EVENT(L1_DATA_CYCLES_USED, 0x02, 41), + PMC_POWERPC_EVENT(DST_STREAM_1_CACHE_LINE_FETCHES, 0x02, 42), + PMC_POWERPC_EVENT(VTQ_STREAM_CANCELED_PREMATURELY, 0x02, 43), + PMC_POWERPC_EVENT(VTQ_RESUMES_DUE_TO_CTX_CHANGE, 0x02, 44), + PMC_POWERPC_EVENT(VTQ_LINE_FETCH_MISS, 0x02, 45), + PMC_POWERPC_EVENT(VTQ_LINE_FETCH, 0x02, 46), + PMC_POWERPC_EVENT(TLBIE_SNOOPS, 0x02, 47), + PMC_POWERPC_EVENT(L1_INSTR_CACHE_RELOADS, 0x02, 48), + PMC_POWERPC_EVENT(L1_DATA_CACHE_RELOADS, 0x02, 49), + PMC_POWERPC_EVENT(L1_DATA_CACHE_CASTOUTS_TO_L2, 0x02, 50), + PMC_POWERPC_EVENT(STORE_MERGE_GATHER, 0x02, 51), + PMC_POWERPC_EVENT(CACHEABLE_STORE_MERGE_TO_32_BYTES, 0x02, 52), + PMC_POWERPC_EVENT(DATA_BKPT_MATCHES, 0x02, 53), + PMC_POWERPC_EVENT(FALL_THROUGH_BRANCHES_PROCESSED, 0x02, 54), + PMC_POWERPC_EVENT(FIRST_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x02, 55), + PMC_POWERPC_EVENT(SECOND_SPECULATION_BUFFER_ACTIVE, 0x02, 56), + PMC_POWERPC_EVENT(BPU_STALL_ON_LR_DEPENDENCY, 0x02, 57), + PMC_POWERPC_EVENT(BTIC_MISS, 0x02, 58), + PMC_POWERPC_EVENT(BRANCH_LINK_STACK_CORRECTLY_RESOLVED, 0x02, 59), + PMC_POWERPC_EVENT(FPR_ISSUE_STALLED, 0x02, 60), + PMC_POWERPC_EVENT(SWITCHES_BETWEEN_PRIV_USER, 0x02, 61), + PMC_POWERPC_EVENT(LSU_COMPLETES_FP_STORE_SINGLE, 0x02, 62), + PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x04, 8), + PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x04, 9), + PMC_POWERPC_EVENT(VR_ISSUE_QUEUE_DISPATCHES, 0x04, 10), + PMC_POWERPC_EVENT(VR_STALLS, 0x04, 11), + PMC_POWERPC_EVENT(GPR_RENAME_BUFFER_ENTRIES_OVER_THRESHOLD, 0x04, 12), + PMC_POWERPC_EVENT(FPR_ISSUE_QUEUE_ENTRIES, 0x04, 13), + PMC_POWERPC_EVENT(FPU_INSTR_COMPLETED, 0x04, 14), + PMC_POWERPC_EVENT(STWCX_INSTR_COMPLETED, 0x04, 15), + PMC_POWERPC_EVENT(LS_LM_INSTR_PIECES, 0x04, 16), + PMC_POWERPC_EVENT(ITLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x04, 17), + PMC_POWERPC_EVENT(DTLB_MISSES, 0x04, 18), + PMC_POWERPC_EVENT(CANCELLED_L1_INSTR_CACHE_MISSES, 0x04, 19), + PMC_POWERPC_EVENT(L1_DATA_CACHE_OP_HIT, 0x04, 20), + PMC_POWERPC_EVENT(L1_DATA_LOAD_MISS_CYCLES, 0x04, 21), + PMC_POWERPC_EVENT(L1_DATA_PUSHES, 0x04, 22), + PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISS, 0x04, 23), + PMC_POWERPC_EVENT(VT2_FETCHES, 0x04, 24), + PMC_POWERPC_EVENT(TAKEN_BRANCHES_PROCESSED, 0x04, 25), + PMC_POWERPC_EVENT(BRANCH_FLUSHES, 0x04, 26), + PMC_POWERPC_EVENT(SECOND_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x04, 27), + PMC_POWERPC_EVENT(THIRD_SPECULATION_BUFFER_ACTIVE, 0x04, 28), + PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_ON_CTR_DEPENDENCY, 0x04, 29), + PMC_POWERPC_EVENT(FAST_BTIC_HIT, 0x04, 30), + PMC_POWERPC_EVENT(BRANCH_LINK_STACK_MISPREDICTED, 0x04, 31), + PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_COMPLETED, 0x08, 14), + PMC_POWERPC_EVENT(CYCLES_NO_INSTR_DISPATCHED, 0x08, 15), + PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_ENTRIES_OVER_THRESHOLD, 0x08, 16), + PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_STALLED, 0x08, 17), + PMC_POWERPC_EVENT(IU1_INSTR_COMPLETED, 0x08, 18), + PMC_POWERPC_EVENT(DSSALL_INSTR_COMPLETED, 0x08, 19), + PMC_POWERPC_EVENT(TLBSYNC_INSTR_COMPLETED, 0x08, 20), + PMC_POWERPC_EVENT(SYNC_INSTR_COMPLETED, 0x08, 21), + PMC_POWERPC_EVENT(SS_SM_INSTR_PIECES, 0x08, 22), + PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES, 0x08, 23), + PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x08, 24), + PMC_POWERPC_EVENT(SUCCESSFUL_STWCX, 0x08, 25), + PMC_POWERPC_EVENT(DST_STREAM_3_CACHE_LINE_FETCHES, 0x08, 26), + PMC_POWERPC_EVENT(THIRD_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x08, 27), + PMC_POWERPC_EVENT(MISPREDICTED_BRANCHES, 0x08, 28), + PMC_POWERPC_EVENT(FOLDED_BRANCHES, 0x08, 29), + PMC_POWERPC_EVENT(FP_STORE_DOUBLE_COMPLETES_IN_LSU, 0x08, 30), + PMC_POWERPC_EVENT(L2_CACHE_HITS, 0x30, 2), + PMC_POWERPC_EVENT(L3_CACHE_HITS, 0x30, 3), + PMC_POWERPC_EVENT(L2_INSTR_CACHE_MISSES, 0x30, 4), + PMC_POWERPC_EVENT(L3_INSTR_CACHE_MISSES, 0x30, 5), + PMC_POWERPC_EVENT(L2_DATA_CACHE_MISSES, 0x30, 6), + PMC_POWERPC_EVENT(L3_DATA_CACHE_MISSES, 0x30, 7), + PMC_POWERPC_EVENT(L2_LOAD_HITS, 0x10, 8), + PMC_POWERPC_EVENT(L2_STORE_HITS, 0x10, 9), + PMC_POWERPC_EVENT(L3_LOAD_HITS, 0x10, 10), + PMC_POWERPC_EVENT(L3_STORE_HITS, 0x10, 11), + PMC_POWERPC_EVENT(L2_TOUCH_HITS, 0x30, 13), + PMC_POWERPC_EVENT(L3_TOUCH_HITS, 0x30, 14), + PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x30, 15), + PMC_POWERPC_EVENT(SNOOP_MODIFIED, 0x10, 16), + PMC_POWERPC_EVENT(SNOOP_VALID, 0x10, 17), + PMC_POWERPC_EVENT(INTERVENTION, 0x30, 18), + PMC_POWERPC_EVENT(L2_CACHE_MISSES, 0x10, 19), + PMC_POWERPC_EVENT(L3_CACHE_MISSES, 0x10, 20), + PMC_POWERPC_EVENT(L2_CACHE_CASTOUTS, 0x20, 8), + PMC_POWERPC_EVENT(L3_CACHE_CASTOUTS, 0x20, 9), + PMC_POWERPC_EVENT(L2SQ_FULL_CYCLES, 0x20, 10), + PMC_POWERPC_EVENT(L3SQ_FULL_CYCLES, 0x20, 11), + PMC_POWERPC_EVENT(RAQ_FULL_CYCLES, 0x20, 16), + PMC_POWERPC_EVENT(WAQ_FULL_CYCLES, 0x20, 17), + PMC_POWERPC_EVENT(L1_EXTERNAL_INTERVENTIONS, 0x20, 19), + PMC_POWERPC_EVENT(L2_EXTERNAL_INTERVENTIONS, 0x20, 20), + PMC_POWERPC_EVENT(L3_EXTERNAL_INTERVENTIONS, 0x20, 21), + PMC_POWERPC_EVENT(EXTERNAL_INTERVENTIONS, 0x20, 22), + PMC_POWERPC_EVENT(EXTERNAL_PUSHES, 0x20, 23), + PMC_POWERPC_EVENT(EXTERNAL_SNOOP_RETRY, 0x20, 24), + PMC_POWERPC_EVENT(DTQ_FULL_CYCLES, 0x20, 25), + PMC_POWERPC_EVENT(BUS_RETRY, 0x20, 26), + PMC_POWERPC_EVENT(L2_VALID_REQUEST, 0x20, 27), + PMC_POWERPC_EVENT(BORDQ_FULL, 0x20, 28), + PMC_POWERPC_EVENT(BUS_TAS_FOR_READS, 0x20, 42), + PMC_POWERPC_EVENT(BUS_TAS_FOR_WRITES, 0x20, 43), + PMC_POWERPC_EVENT(BUS_READS_NOT_RETRIED, 0x20, 44), + PMC_POWERPC_EVENT(BUS_WRITES_NOT_RETRIED, 0x20, 45), + PMC_POWERPC_EVENT(BUS_READS_WRITES_NOT_RETRIED, 0x20, 46), + PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_L1_RETRY, 0x20, 47), + PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_PREVIOUS_ADJACENT, 0x20, 48), + PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_COLLISION, 0x20, 49), + PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_INTERVENTION_ORDERING, 0x20, 50), + PMC_POWERPC_EVENT(SNOOP_REQUESTS, 0x20, 51), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_REQUEST, 0x20, 52), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD, 0x20, 53), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_STORE, 0x20, 54), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_INSTR_FETCH, 0x20, 55), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD_STORE_INSTR_FETCH, 0x20, 56), + PMC_POWERPC_EVENT(PREFETCH_ENGINE_FULL, 0x20, 57) +}; + +const size_t powerpc_event_codes_size = + sizeof(powerpc_event_codes) / sizeof(powerpc_event_codes[0]); + +static pmc_value_t +mpc7xxx_pmcn_read(unsigned int pmc) +{ + switch (pmc) { + case 0: + return mfspr(SPR_PMC1); + break; + case 1: + return mfspr(SPR_PMC2); + break; + case 2: + return mfspr(SPR_PMC3); + break; + case 3: + return mfspr(SPR_PMC4); + break; + case 4: + return mfspr(SPR_PMC5); + break; + case 5: + return mfspr(SPR_PMC6); + default: + panic("Invalid PMC number: %d\n", pmc); + } +} + +static void +mpc7xxx_pmcn_write(unsigned int pmc, uint32_t val) +{ + switch (pmc) { + case 0: + mtspr(SPR_PMC1, val); + break; + case 1: + mtspr(SPR_PMC2, val); + break; + case 2: + mtspr(SPR_PMC3, val); + break; + case 3: + mtspr(SPR_PMC4, val); + break; + case 4: + mtspr(SPR_PMC5, val); + break; + case 5: + mtspr(SPR_PMC6, val); + break; + default: + panic("Invalid PMC number: %d\n", pmc); + } +} + +static int +mpc7xxx_read_pmc(int cpu, int ri, pmc_value_t *v) +{ + struct pmc *pm; + pmc_value_t tmp; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < MPC7XXX_MAX_PMCS, + ("[powerpc,%d] illegal row index %d", __LINE__, ri)); + + pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; + KASSERT(pm, + ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, + ri)); + + tmp = mpc7xxx_pmcn_read(ri); + PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); + if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); + else + *v = tmp; + + return 0; +} + +static int +mpc7xxx_write_pmc(int cpu, int ri, pmc_value_t v) +{ + struct pmc *pm; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < MPC7XXX_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; + + if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) + v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); + + PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); + + mpc7xxx_pmcn_write(ri, v); + + return 0; +} + +static int +mpc7xxx_config_pmc(int cpu, int ri, struct pmc *pm) +{ + struct pmc_hw *phw; + + PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < MPC7XXX_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + + KASSERT(pm == NULL || phw->phw_pmc == NULL, + ("[powerpc,%d] pm=%p phw->pm=%p hwpmc not unconfigured", + __LINE__, pm, phw->phw_pmc)); + + phw->phw_pmc = pm; + + return 0; +} + +static int +mpc7xxx_start_pmc(int cpu, int ri) +{ + uint32_t config; + struct pmc *pm; + struct pmc_hw *phw; + register_t pmc_mmcr; + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + pm = phw->phw_pmc; + config = pm->pm_md.pm_powerpc.pm_powerpc_evsel & ~POWERPC_PMC_ENABLE; + + /* Enable the PMC. */ + switch (ri) { + case 0: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC1SEL(pmc_mmcr, config); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 1: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC2SEL(pmc_mmcr, config); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 2: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC3SEL(pmc_mmcr, config); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + case 3: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC4SEL(pmc_mmcr, config); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 4: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC5SEL(pmc_mmcr, config); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + case 5: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC6SEL(pmc_mmcr, config); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + default: + break; + } + + /* The mask is inverted (enable is 1) compared to the flags in MMCR0, which + * are Freeze flags. + */ + config = ~pm->pm_md.pm_powerpc.pm_powerpc_evsel & POWERPC_PMC_ENABLE; + + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr &= ~SPR_MMCR0_FC; + pmc_mmcr |= config; + mtspr(SPR_MMCR0, pmc_mmcr); + + return 0; +} + +static int +mpc7xxx_stop_pmc(int cpu, int ri) +{ + struct pmc *pm; + struct pmc_hw *phw; + register_t pmc_mmcr; + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + pm = phw->phw_pmc; + + /* + * Disable the PMCs. + */ + switch (ri) { + case 0: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC1SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 1: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC2SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 2: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC3SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + case 3: + pmc_mmcr = mfspr(SPR_MMCR0); + pmc_mmcr = PPC_SET_PMC4SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR0, pmc_mmcr); + break; + case 4: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC5SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + case 5: + pmc_mmcr = mfspr(SPR_MMCR1); + pmc_mmcr = PPC_SET_PMC6SEL(pmc_mmcr, 0); + mtspr(SPR_MMCR1, pmc_mmcr); + break; + default: + break; + } + return 0; +} + +static int +mpc7xxx_pcpu_init(struct pmc_mdep *md, int cpu) +{ + int first_ri, i; + struct pmc_cpu *pc; + struct powerpc_cpu *pac; + struct pmc_hw *phw; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); + PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); + + powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC, + M_WAITOK|M_ZERO); + pac->pc_ppcpmcs = malloc(sizeof(struct pmc_hw) * MPC7XXX_MAX_PMCS, + M_PMC, M_WAITOK|M_ZERO); + pc = pmc_pcpu[cpu]; + first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450].pcd_ri; + KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__)); + + for (i = 0, phw = pac->pc_ppcpmcs; i < MPC7XXX_MAX_PMCS; i++, phw++) { + phw->phw_state = PMC_PHW_FLAG_IS_ENABLED | + PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i); + phw->phw_pmc = NULL; + pc->pc_hwpmcs[i + first_ri] = phw; + } + + /* Clear the MMCRs, and set FC, to disable all PMCs. */ + mtspr(SPR_MMCR0, SPR_MMCR0_FC | SPR_MMCR0_PMXE | SPR_MMCR0_PMC1CE | SPR_MMCR0_PMCNCE); + mtspr(SPR_MMCR1, 0); + + return 0; +} + +static int +mpc7xxx_pcpu_fini(struct pmc_mdep *md, int cpu) +{ + uint32_t mmcr0 = mfspr(SPR_MMCR0); + + mmcr0 |= SPR_MMCR0_FC; + mtspr(SPR_MMCR0, mmcr0); + free(powerpc_pcpu[cpu]->pc_ppcpmcs, M_PMC); + free(powerpc_pcpu[cpu], M_PMC); + return 0; +} + +static int +mpc7xxx_allocate_pmc(int cpu, int ri, struct pmc *pm, + const struct pmc_op_pmcallocate *a) +{ + enum pmc_event pe; + uint32_t caps, config, counter; + int i; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < MPC7XXX_MAX_PMCS, + ("[powerpc,%d] illegal row index %d", __LINE__, ri)); + + caps = a->pm_caps; + + pe = a->pm_ev; + for (i = 0; i < powerpc_event_codes_size; i++) { + if (powerpc_event_codes[i].pe_ev == pe) { + config = powerpc_event_codes[i].pe_code; + counter = powerpc_event_codes[i].pe_counter_mask; + break; + } + } + if (i == powerpc_event_codes_size) + return (EINVAL); + + if ((counter & (1 << ri)) == 0) + return (EINVAL); + + if (caps & PMC_CAP_SYSTEM) + config |= POWERPC_PMC_KERNEL_ENABLE; + if (caps & PMC_CAP_USER) + config |= POWERPC_PMC_USER_ENABLE; + if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) + config |= POWERPC_PMC_ENABLE; + + pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; + + PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); + + return 0; +} + +static int +mpc7xxx_release_pmc(int cpu, int ri, struct pmc *pmc) +{ + struct pmc_hw *phw; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); + KASSERT(ri >= 0 && ri < MPC7XXX_MAX_PMCS, + ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); + + phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; + KASSERT(phw->phw_pmc == NULL, + ("[powerpc,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); + + return 0; +} + +static int +mpc7xxx_intr(int cpu, struct trapframe *tf) +{ + int i, error, retval; + uint32_t config; + struct pmc *pm; + struct powerpc_cpu *pac; + pmc_value_t v; + + KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), + ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); + + PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + TRAPF_USERMODE(tf)); + + retval = 0; + + pac = powerpc_pcpu[cpu]; + + config = mfspr(SPR_MMCR0); + mtspr(SPR_MMCR0, config | SPR_MMCR0_FC); + + /* + * look for all PMCs that have interrupted: + * - look for a running, sampling PMC which has overflowed + * and which has a valid 'struct pmc' association + * + * If found, we call a helper to process the interrupt. + */ + + for (i = 0; i < MPC7XXX_MAX_PMCS; i++) { + if ((pm = pac->pc_ppcpmcs[i].phw_pmc) == NULL || + !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { + continue; + } + + if (!MPC7XXX_PMC_HAS_OVERFLOWED(i)) + continue; + + retval = 1; /* Found an interrupting PMC. */ + + if (pm->pm_state != PMC_STATE_RUNNING) + continue; + + /* Stop the PMC, reload count. */ + v = pm->pm_sc.pm_reloadcount; + mpc7xxx_pmcn_write(i, v); + + /* Restart the counter if logging succeeded. */ + error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, + TRAPF_USERMODE(tf)); + if (error != 0) + mpc7xxx_stop_pmc(cpu, i); + atomic_add_int(retval ? &pmc_stats.pm_intr_processed : + &pmc_stats.pm_intr_ignored, 1); + + } + + /* Re-enable PERF exceptions. */ + mtspr(SPR_MMCR0, config | SPR_MMCR0_PMXE); + + return (retval); +} + +int +pmc_mpc7xxx_initialize(struct pmc_mdep *pmc_mdep) +{ + struct pmc_classdep *pcd; + + pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450]; + pcd->pcd_caps = POWERPC_PMC_CAPS; + pcd->pcd_class = PMC_CLASS_PPC7450; + pcd->pcd_num = MPC7XXX_MAX_PMCS; + pcd->pcd_ri = pmc_mdep->pmd_npmc; + pcd->pcd_width = 32; /* All PMCs, even in ppc970, are 32-bit */ + + pcd->pcd_allocate_pmc = mpc7xxx_allocate_pmc; + pcd->pcd_config_pmc = mpc7xxx_config_pmc; + pcd->pcd_pcpu_fini = mpc7xxx_pcpu_fini; + pcd->pcd_pcpu_init = mpc7xxx_pcpu_init; + pcd->pcd_read_pmc = mpc7xxx_read_pmc; + pcd->pcd_release_pmc = mpc7xxx_release_pmc; + pcd->pcd_start_pmc = mpc7xxx_start_pmc; + pcd->pcd_stop_pmc = mpc7xxx_stop_pmc; + pcd->pcd_write_pmc = mpc7xxx_write_pmc; + + pmc_mdep->pmd_npmc += MPC7XXX_MAX_PMCS; + pmc_mdep->pmd_intr = mpc7xxx_intr; + + return 0; +} diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c index a54ee62..a6453ec 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.c +++ b/sys/dev/hwpmc/hwpmc_powerpc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011 Justin Hibbits + * Copyright (c) 2011,2013 Justin Hibbits * Copyright (c) 2005, Joseph Koshy * All rights reserved. * @@ -37,676 +37,50 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include /* For VM_MIN_KERNEL_ADDRESS/VM_MAX_KERNEL_ADDRESS */ -#define POWERPC_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \ - PMC_CAP_SYSTEM | PMC_CAP_EDGE | \ - PMC_CAP_THRESHOLD | PMC_CAP_READ | \ - PMC_CAP_WRITE | PMC_CAP_INVERT | \ - PMC_CAP_QUALIFIER) +#include "hwpmc_powerpc.h" -#define PPC_SET_PMC1SEL(r, x) ((r & ~(SPR_MMCR0_PMC1SEL(0x3f))) | SPR_MMCR0_PMC1SEL(x)) -#define PPC_SET_PMC2SEL(r, x) ((r & ~(SPR_MMCR0_PMC2SEL(0x3f))) | SPR_MMCR0_PMC2SEL(x)) -#define PPC_SET_PMC3SEL(r, x) ((r & ~(SPR_MMCR1_PMC3SEL(0x1f))) | SPR_MMCR1_PMC3SEL(x)) -#define PPC_SET_PMC4SEL(r, x) ((r & ~(SPR_MMCR1_PMC4SEL(0x1f))) | SPR_MMCR1_PMC4SEL(x)) -#define PPC_SET_PMC5SEL(r, x) ((r & ~(SPR_MMCR1_PMC5SEL(0x1f))) | SPR_MMCR1_PMC5SEL(x)) -#define PPC_SET_PMC6SEL(r, x) ((r & ~(SPR_MMCR1_PMC6SEL(0x3f))) | SPR_MMCR1_PMC6SEL(x)) - -/* Change this when we support more than just the 7450. */ -#define PPC_MAX_PMCS 6 - -#define POWERPC_PMC_KERNEL_ENABLE (0x1 << 30) -#define POWERPC_PMC_USER_ENABLE (0x1 << 31) - -#define POWERPC_PMC_ENABLE (POWERPC_PMC_KERNEL_ENABLE | POWERPC_PMC_USER_ENABLE) -#define POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(V) (0x80000000-(V)) -#define POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(P) ((P)-0x80000000) -#define POWERPC_PMC_HAS_OVERFLOWED(x) (powerpc_pmcn_read(x) & (0x1 << 31)) - - -/* - * This should work for every 32-bit PowerPC implementation I know of (G3 and G4 - * specifically). PoewrPC 970 will take more work. - */ +#define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \ + ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS) /* * Per-processor information. */ -struct powerpc_cpu { - struct pmc_hw *pc_ppcpmcs; -}; - -static struct powerpc_cpu **powerpc_pcpu; - -struct powerpc_event_code_map { - enum pmc_event pe_ev; /* enum value */ - uint8_t pe_counter_mask; /* Which counter this can be counted in. */ - uint8_t pe_code; /* numeric code */ -}; - -#define PPC_PMC_MASK1 0 -#define PPC_PMC_MASK2 1 -#define PPC_PMC_MASK3 2 -#define PPC_PMC_MASK4 3 -#define PPC_PMC_MASK5 4 -#define PPC_PMC_MASK6 5 -#define PPC_PMC_MASK_ALL 0x3f - -#define PMC_POWERPC_EVENT(id, mask, number) \ - { .pe_ev = PMC_EV_PPC7450_##id, .pe_counter_mask = mask, .pe_code = number } - -static struct powerpc_event_code_map powerpc_event_codes[] = { - PMC_POWERPC_EVENT(CYCLE,PPC_PMC_MASK_ALL, 1), - PMC_POWERPC_EVENT(INSTR_COMPLETED, 0x0f, 2), - PMC_POWERPC_EVENT(TLB_BIT_TRANSITIONS, 0x0f, 3), - PMC_POWERPC_EVENT(INSTR_DISPATCHED, 0x0f, 4), - PMC_POWERPC_EVENT(PMON_EXCEPT, 0x0f, 5), - PMC_POWERPC_EVENT(PMON_SIG, 0x0f, 7), - PMC_POWERPC_EVENT(VPU_INSTR_COMPLETED, 0x03, 8), - PMC_POWERPC_EVENT(VFPU_INSTR_COMPLETED, 0x03, 9), - PMC_POWERPC_EVENT(VIU1_INSTR_COMPLETED, 0x03, 10), - PMC_POWERPC_EVENT(VIU2_INSTR_COMPLETED, 0x03, 11), - PMC_POWERPC_EVENT(MTVSCR_INSTR_COMPLETED, 0x03, 12), - PMC_POWERPC_EVENT(MTVRSAVE_INSTR_COMPLETED, 0x03, 13), - PMC_POWERPC_EVENT(VPU_INSTR_WAIT_CYCLES, 0x03, 14), - PMC_POWERPC_EVENT(VFPU_INSTR_WAIT_CYCLES, 0x03, 15), - PMC_POWERPC_EVENT(VIU1_INSTR_WAIT_CYCLES, 0x03, 16), - PMC_POWERPC_EVENT(VIU2_INSTR_WAIT_CYCLES, 0x03, 17), - PMC_POWERPC_EVENT(MFVSCR_SYNC_CYCLES, 0x03, 18), - PMC_POWERPC_EVENT(VSCR_SAT_SET, 0x03, 19), - PMC_POWERPC_EVENT(STORE_INSTR_COMPLETED, 0x03, 20), - PMC_POWERPC_EVENT(L1_INSTR_CACHE_MISSES, 0x03, 21), - PMC_POWERPC_EVENT(L1_DATA_SNOOPS, 0x03, 22), - PMC_POWERPC_EVENT(UNRESOLVED_BRANCHES, 0x01, 23), - PMC_POWERPC_EVENT(SPEC_BUFFER_CYCLES, 0x01, 24), - PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_CYCLES, 0x01, 25), - PMC_POWERPC_EVENT(TRUE_BRANCH_TARGET_HITS, 0x01, 26), - PMC_POWERPC_EVENT(BRANCH_LINK_STAC_PREDICTED, 0x01, 27), - PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_DISPATCHES, 0x01, 28), - PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_DISPATCHED, 0x01, 29), - PMC_POWERPC_EVENT(THRESHOLD_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 30), - PMC_POWERPC_EVENT(THRESHOLD_VEC_INSTR_QUEUE_ENTRIES_CYCLES, 0x01, 31), - PMC_POWERPC_EVENT(CYCLES_NO_COMPLETED_INSTRS, 0x01, 32), - PMC_POWERPC_EVENT(IU2_INSTR_COMPLETED, 0x01, 33), - PMC_POWERPC_EVENT(BRANCHES_COMPLETED, 0x01, 34), - PMC_POWERPC_EVENT(EIEIO_INSTR_COMPLETED, 0x01, 35), - PMC_POWERPC_EVENT(MTSPR_INSTR_COMPLETED, 0x01, 36), - PMC_POWERPC_EVENT(SC_INSTR_COMPLETED, 0x01, 37), - PMC_POWERPC_EVENT(LS_LM_COMPLETED, 0x01, 38), - PMC_POWERPC_EVENT(ITLB_HW_TABLE_SEARCH_CYCLES, 0x01, 39), - PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x01, 40), - PMC_POWERPC_EVENT(L1_INSTR_CACHE_ACCESSES, 0x01, 41), - PMC_POWERPC_EVENT(INSTR_BKPT_MATCHES, 0x01, 42), - PMC_POWERPC_EVENT(L1_DATA_CACHE_LOAD_MISS_CYCLES_OVER_THRESHOLD, 0x01, 43), - PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_ON_MODIFIED, 0x01, 44), - PMC_POWERPC_EVENT(LOAD_MISS_ALIAS, 0x01, 45), - PMC_POWERPC_EVENT(LOAD_MISS_ALIAS_ON_TOUCH, 0x01, 46), - PMC_POWERPC_EVENT(TOUCH_ALIAS, 0x01, 47), - PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT_QUEUE, 0x01, 48), - PMC_POWERPC_EVENT(L1_DATA_SNOOP_HIT_CASTOUT, 0x01, 49), - PMC_POWERPC_EVENT(L1_DATA_SNOOP_HITS, 0x01, 50), - PMC_POWERPC_EVENT(WRITE_THROUGH_STORES, 0x01, 51), - PMC_POWERPC_EVENT(CACHE_INHIBITED_STORES, 0x01, 52), - PMC_POWERPC_EVENT(L1_DATA_LOAD_HIT, 0x01, 53), - PMC_POWERPC_EVENT(L1_DATA_TOUCH_HIT, 0x01, 54), - PMC_POWERPC_EVENT(L1_DATA_STORE_HIT, 0x01, 55), - PMC_POWERPC_EVENT(L1_DATA_TOTAL_HITS, 0x01, 56), - PMC_POWERPC_EVENT(DST_INSTR_DISPATCHED, 0x01, 57), - PMC_POWERPC_EVENT(REFRESHED_DSTS, 0x01, 58), - PMC_POWERPC_EVENT(SUCCESSFUL_DST_TABLE_SEARCHES, 0x01, 59), - PMC_POWERPC_EVENT(DSS_INSTR_COMPLETED, 0x01, 60), - PMC_POWERPC_EVENT(DST_STREAM_0_CACHE_LINE_FETCHES, 0x01, 61), - PMC_POWERPC_EVENT(VTQ_SUSPENDS_DUE_TO_CTX_CHANGE, 0x01, 62), - PMC_POWERPC_EVENT(VTQ_LINE_FETCH_HIT, 0x01, 63), - PMC_POWERPC_EVENT(VEC_LOAD_INSTR_COMPLETED, 0x01, 64), - PMC_POWERPC_EVENT(FP_STORE_INSTR_COMPLETED_IN_LSU, 0x01, 65), - PMC_POWERPC_EVENT(FPU_RENORMALIZATION, 0x01, 66), - PMC_POWERPC_EVENT(FPU_DENORMALIZATION, 0x01, 67), - PMC_POWERPC_EVENT(FP_STORE_CAUSES_STALL_IN_LSU, 0x01, 68), - PMC_POWERPC_EVENT(LD_ST_TRUE_ALIAS_STALL, 0x01, 70), - PMC_POWERPC_EVENT(LSU_INDEXED_ALIAS_STALL, 0x01, 71), - PMC_POWERPC_EVENT(LSU_ALIAS_VS_FSQ_WB0_WB1, 0x01, 72), - PMC_POWERPC_EVENT(LSU_ALIAS_VS_CSQ, 0x01, 73), - PMC_POWERPC_EVENT(LSU_LOAD_HIT_LINE_ALIAS_VS_CSQ0, 0x01, 74), - PMC_POWERPC_EVENT(LSU_LOAD_MISS_LINE_ALIAS_VS_CSQ0, 0x01, 75), - PMC_POWERPC_EVENT(LSU_TOUCH_LINE_ALIAS_VS_FSQ_WB0_WB1, 0x01, 76), - PMC_POWERPC_EVENT(LSU_TOUCH_ALIAS_VS_CSQ, 0x01, 77), - PMC_POWERPC_EVENT(LSU_LMQ_FULL_STALL, 0x01, 78), - PMC_POWERPC_EVENT(FP_LOAD_INSTR_COMPLETED_IN_LSU, 0x01, 79), - PMC_POWERPC_EVENT(FP_LOAD_SINGLE_INSTR_COMPLETED_IN_LSU, 0x01, 80), - PMC_POWERPC_EVENT(FP_LOAD_DOUBLE_COMPLETED_IN_LSU, 0x01, 81), - PMC_POWERPC_EVENT(LSU_RA_LATCH_STALL, 0x01, 82), - PMC_POWERPC_EVENT(LSU_LOAD_VS_STORE_QUEUE_ALIAS_STALL, 0x01, 83), - PMC_POWERPC_EVENT(LSU_LMQ_INDEX_ALIAS, 0x01, 84), - PMC_POWERPC_EVENT(LSU_STORE_QUEUE_INDEX_ALIAS, 0x01, 85), - PMC_POWERPC_EVENT(LSU_CSQ_FORWARDING, 0x01, 86), - PMC_POWERPC_EVENT(LSU_MISALIGNED_LOAD_FINISH, 0x01, 87), - PMC_POWERPC_EVENT(LSU_MISALIGN_STORE_COMPLETED, 0x01, 88), - PMC_POWERPC_EVENT(LSU_MISALIGN_STALL, 0x01, 89), - PMC_POWERPC_EVENT(FP_ONE_QUARTER_FPSCR_RENAMES_BUSY, 0x01, 90), - PMC_POWERPC_EVENT(FP_ONE_HALF_FPSCR_RENAMES_BUSY, 0x01, 91), - PMC_POWERPC_EVENT(FP_THREE_QUARTERS_FPSCR_RENAMES_BUSY, 0x01, 92), - PMC_POWERPC_EVENT(FP_ALL_FPSCR_RENAMES_BUSY, 0x01, 93), - PMC_POWERPC_EVENT(FP_DENORMALIZED_RESULT, 0x01, 94), - PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISSES, 0x02, 23), - PMC_POWERPC_EVENT(DISPATCHES_TO_FPR_ISSUE_QUEUE, 0x02, 24), - PMC_POWERPC_EVENT(LSU_INSTR_COMPLETED, 0x02, 25), - PMC_POWERPC_EVENT(LOAD_INSTR_COMPLETED, 0x02, 26), - PMC_POWERPC_EVENT(SS_SM_INSTR_COMPLETED, 0x02, 27), - PMC_POWERPC_EVENT(TLBIE_INSTR_COMPLETED, 0x02, 28), - PMC_POWERPC_EVENT(LWARX_INSTR_COMPLETED, 0x02, 29), - PMC_POWERPC_EVENT(MFSPR_INSTR_COMPLETED, 0x02, 30), - PMC_POWERPC_EVENT(REFETCH_SERIALIZATION, 0x02, 31), - PMC_POWERPC_EVENT(COMPLETION_QUEUE_ENTRIES_OVER_THRESHOLD, 0x02, 32), - PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x02, 33), - PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x02, 34), - PMC_POWERPC_EVENT(ITLB_NON_SPECULATIVE_MISSES, 0x02, 35), - PMC_POWERPC_EVENT(CYCLES_WAITING_FROM_L1_INSTR_CACHE_MISS, 0x02, 36), - PMC_POWERPC_EVENT(L1_DATA_LOAD_ACCESS_MISS, 0x02, 37), - PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS, 0x02, 38), - PMC_POWERPC_EVENT(L1_DATA_STORE_MISS, 0x02, 39), - PMC_POWERPC_EVENT(L1_DATA_TOUCH_MISS_CYCLES, 0x02, 40), - PMC_POWERPC_EVENT(L1_DATA_CYCLES_USED, 0x02, 41), - PMC_POWERPC_EVENT(DST_STREAM_1_CACHE_LINE_FETCHES, 0x02, 42), - PMC_POWERPC_EVENT(VTQ_STREAM_CANCELED_PREMATURELY, 0x02, 43), - PMC_POWERPC_EVENT(VTQ_RESUMES_DUE_TO_CTX_CHANGE, 0x02, 44), - PMC_POWERPC_EVENT(VTQ_LINE_FETCH_MISS, 0x02, 45), - PMC_POWERPC_EVENT(VTQ_LINE_FETCH, 0x02, 46), - PMC_POWERPC_EVENT(TLBIE_SNOOPS, 0x02, 47), - PMC_POWERPC_EVENT(L1_INSTR_CACHE_RELOADS, 0x02, 48), - PMC_POWERPC_EVENT(L1_DATA_CACHE_RELOADS, 0x02, 49), - PMC_POWERPC_EVENT(L1_DATA_CACHE_CASTOUTS_TO_L2, 0x02, 50), - PMC_POWERPC_EVENT(STORE_MERGE_GATHER, 0x02, 51), - PMC_POWERPC_EVENT(CACHEABLE_STORE_MERGE_TO_32_BYTES, 0x02, 52), - PMC_POWERPC_EVENT(DATA_BKPT_MATCHES, 0x02, 53), - PMC_POWERPC_EVENT(FALL_THROUGH_BRANCHES_PROCESSED, 0x02, 54), - PMC_POWERPC_EVENT(FIRST_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x02, 55), - PMC_POWERPC_EVENT(SECOND_SPECULATION_BUFFER_ACTIVE, 0x02, 56), - PMC_POWERPC_EVENT(BPU_STALL_ON_LR_DEPENDENCY, 0x02, 57), - PMC_POWERPC_EVENT(BTIC_MISS, 0x02, 58), - PMC_POWERPC_EVENT(BRANCH_LINK_STACK_CORRECTLY_RESOLVED, 0x02, 59), - PMC_POWERPC_EVENT(FPR_ISSUE_STALLED, 0x02, 60), - PMC_POWERPC_EVENT(SWITCHES_BETWEEN_PRIV_USER, 0x02, 61), - PMC_POWERPC_EVENT(LSU_COMPLETES_FP_STORE_SINGLE, 0x02, 62), - PMC_POWERPC_EVENT(CYCLES_TWO_INSTR_COMPLETED, 0x04, 8), - PMC_POWERPC_EVENT(CYCLES_ONE_INSTR_DISPATCHED, 0x04, 9), - PMC_POWERPC_EVENT(VR_ISSUE_QUEUE_DISPATCHES, 0x04, 10), - PMC_POWERPC_EVENT(VR_STALLS, 0x04, 11), - PMC_POWERPC_EVENT(GPR_RENAME_BUFFER_ENTRIES_OVER_THRESHOLD, 0x04, 12), - PMC_POWERPC_EVENT(FPR_ISSUE_QUEUE_ENTRIES, 0x04, 13), - PMC_POWERPC_EVENT(FPU_INSTR_COMPLETED, 0x04, 14), - PMC_POWERPC_EVENT(STWCX_INSTR_COMPLETED, 0x04, 15), - PMC_POWERPC_EVENT(LS_LM_INSTR_PIECES, 0x04, 16), - PMC_POWERPC_EVENT(ITLB_HW_SEARCH_CYCLES_OVER_THRESHOLD, 0x04, 17), - PMC_POWERPC_EVENT(DTLB_MISSES, 0x04, 18), - PMC_POWERPC_EVENT(CANCELLED_L1_INSTR_CACHE_MISSES, 0x04, 19), - PMC_POWERPC_EVENT(L1_DATA_CACHE_OP_HIT, 0x04, 20), - PMC_POWERPC_EVENT(L1_DATA_LOAD_MISS_CYCLES, 0x04, 21), - PMC_POWERPC_EVENT(L1_DATA_PUSHES, 0x04, 22), - PMC_POWERPC_EVENT(L1_DATA_TOTAL_MISS, 0x04, 23), - PMC_POWERPC_EVENT(VT2_FETCHES, 0x04, 24), - PMC_POWERPC_EVENT(TAKEN_BRANCHES_PROCESSED, 0x04, 25), - PMC_POWERPC_EVENT(BRANCH_FLUSHES, 0x04, 26), - PMC_POWERPC_EVENT(SECOND_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x04, 27), - PMC_POWERPC_EVENT(THIRD_SPECULATION_BUFFER_ACTIVE, 0x04, 28), - PMC_POWERPC_EVENT(BRANCH_UNIT_STALL_ON_CTR_DEPENDENCY, 0x04, 29), - PMC_POWERPC_EVENT(FAST_BTIC_HIT, 0x04, 30), - PMC_POWERPC_EVENT(BRANCH_LINK_STACK_MISPREDICTED, 0x04, 31), - PMC_POWERPC_EVENT(CYCLES_THREE_INSTR_COMPLETED, 0x08, 14), - PMC_POWERPC_EVENT(CYCLES_NO_INSTR_DISPATCHED, 0x08, 15), - PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_ENTRIES_OVER_THRESHOLD, 0x08, 16), - PMC_POWERPC_EVENT(GPR_ISSUE_QUEUE_STALLED, 0x08, 17), - PMC_POWERPC_EVENT(IU1_INSTR_COMPLETED, 0x08, 18), - PMC_POWERPC_EVENT(DSSALL_INSTR_COMPLETED, 0x08, 19), - PMC_POWERPC_EVENT(TLBSYNC_INSTR_COMPLETED, 0x08, 20), - PMC_POWERPC_EVENT(SYNC_INSTR_COMPLETED, 0x08, 21), - PMC_POWERPC_EVENT(SS_SM_INSTR_PIECES, 0x08, 22), - PMC_POWERPC_EVENT(DTLB_HW_SEARCH_CYCLES, 0x08, 23), - PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x08, 24), - PMC_POWERPC_EVENT(SUCCESSFUL_STWCX, 0x08, 25), - PMC_POWERPC_EVENT(DST_STREAM_3_CACHE_LINE_FETCHES, 0x08, 26), - PMC_POWERPC_EVENT(THIRD_SPECULATIVE_BRANCH_BUFFER_RESOLVED_CORRECTLY, 0x08, 27), - PMC_POWERPC_EVENT(MISPREDICTED_BRANCHES, 0x08, 28), - PMC_POWERPC_EVENT(FOLDED_BRANCHES, 0x08, 29), - PMC_POWERPC_EVENT(FP_STORE_DOUBLE_COMPLETES_IN_LSU, 0x08, 30), - PMC_POWERPC_EVENT(L2_CACHE_HITS, 0x30, 2), - PMC_POWERPC_EVENT(L3_CACHE_HITS, 0x30, 3), - PMC_POWERPC_EVENT(L2_INSTR_CACHE_MISSES, 0x30, 4), - PMC_POWERPC_EVENT(L3_INSTR_CACHE_MISSES, 0x30, 5), - PMC_POWERPC_EVENT(L2_DATA_CACHE_MISSES, 0x30, 6), - PMC_POWERPC_EVENT(L3_DATA_CACHE_MISSES, 0x30, 7), - PMC_POWERPC_EVENT(L2_LOAD_HITS, 0x10, 8), - PMC_POWERPC_EVENT(L2_STORE_HITS, 0x10, 9), - PMC_POWERPC_EVENT(L3_LOAD_HITS, 0x10, 10), - PMC_POWERPC_EVENT(L3_STORE_HITS, 0x10, 11), - PMC_POWERPC_EVENT(L2_TOUCH_HITS, 0x30, 13), - PMC_POWERPC_EVENT(L3_TOUCH_HITS, 0x30, 14), - PMC_POWERPC_EVENT(SNOOP_RETRIES, 0x30, 15), - PMC_POWERPC_EVENT(SNOOP_MODIFIED, 0x10, 16), - PMC_POWERPC_EVENT(SNOOP_VALID, 0x10, 17), - PMC_POWERPC_EVENT(INTERVENTION, 0x30, 18), - PMC_POWERPC_EVENT(L2_CACHE_MISSES, 0x10, 19), - PMC_POWERPC_EVENT(L3_CACHE_MISSES, 0x10, 20), - PMC_POWERPC_EVENT(L2_CACHE_CASTOUTS, 0x20, 8), - PMC_POWERPC_EVENT(L3_CACHE_CASTOUTS, 0x20, 9), - PMC_POWERPC_EVENT(L2SQ_FULL_CYCLES, 0x20, 10), - PMC_POWERPC_EVENT(L3SQ_FULL_CYCLES, 0x20, 11), - PMC_POWERPC_EVENT(RAQ_FULL_CYCLES, 0x20, 16), - PMC_POWERPC_EVENT(WAQ_FULL_CYCLES, 0x20, 17), - PMC_POWERPC_EVENT(L1_EXTERNAL_INTERVENTIONS, 0x20, 19), - PMC_POWERPC_EVENT(L2_EXTERNAL_INTERVENTIONS, 0x20, 20), - PMC_POWERPC_EVENT(L3_EXTERNAL_INTERVENTIONS, 0x20, 21), - PMC_POWERPC_EVENT(EXTERNAL_INTERVENTIONS, 0x20, 22), - PMC_POWERPC_EVENT(EXTERNAL_PUSHES, 0x20, 23), - PMC_POWERPC_EVENT(EXTERNAL_SNOOP_RETRY, 0x20, 24), - PMC_POWERPC_EVENT(DTQ_FULL_CYCLES, 0x20, 25), - PMC_POWERPC_EVENT(BUS_RETRY, 0x20, 26), - PMC_POWERPC_EVENT(L2_VALID_REQUEST, 0x20, 27), - PMC_POWERPC_EVENT(BORDQ_FULL, 0x20, 28), - PMC_POWERPC_EVENT(BUS_TAS_FOR_READS, 0x20, 42), - PMC_POWERPC_EVENT(BUS_TAS_FOR_WRITES, 0x20, 43), - PMC_POWERPC_EVENT(BUS_READS_NOT_RETRIED, 0x20, 44), - PMC_POWERPC_EVENT(BUS_WRITES_NOT_RETRIED, 0x20, 45), - PMC_POWERPC_EVENT(BUS_READS_WRITES_NOT_RETRIED, 0x20, 46), - PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_L1_RETRY, 0x20, 47), - PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_PREVIOUS_ADJACENT, 0x20, 48), - PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_COLLISION, 0x20, 49), - PMC_POWERPC_EVENT(BUS_RETRY_DUE_TO_INTERVENTION_ORDERING, 0x20, 50), - PMC_POWERPC_EVENT(SNOOP_REQUESTS, 0x20, 51), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_REQUEST, 0x20, 52), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD, 0x20, 53), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_STORE, 0x20, 54), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_INSTR_FETCH, 0x20, 55), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_COLLISION_VS_LOAD_STORE_INSTR_FETCH, 0x20, 56), - PMC_POWERPC_EVENT(PREFETCH_ENGINE_FULL, 0x20, 57) -}; - -const size_t powerpc_event_codes_size = - sizeof(powerpc_event_codes) / sizeof(powerpc_event_codes[0]); +static unsigned int ppc_npmcs; int pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) { - (void) cc; - (void) maxsamples; - (void) tf; - return (0); -} + int frames = 0; + uintptr_t *sp; -static pmc_value_t -powerpc_pmcn_read(unsigned int pmc) -{ - switch (pmc) { - case 0: - return mfspr(SPR_PMC1); - break; - case 1: - return mfspr(SPR_PMC2); - break; - case 2: - return mfspr(SPR_PMC3); - break; - case 3: - return mfspr(SPR_PMC4); - break; - case 4: - return mfspr(SPR_PMC5); - break; - case 5: - return mfspr(SPR_PMC6); - default: - panic("Invalid PMC number: %d\n", pmc); - } -} - -static void -powerpc_pmcn_write(unsigned int pmc, uint32_t val) -{ - switch (pmc) { - case 0: - mtspr(SPR_PMC1, val); - break; - case 1: - mtspr(SPR_PMC2, val); - break; - case 2: - mtspr(SPR_PMC3, val); - break; - case 3: - mtspr(SPR_PMC4, val); - break; - case 4: - mtspr(SPR_PMC5, val); - break; - case 5: - mtspr(SPR_PMC6, val); - break; - default: - panic("Invalid PMC number: %d\n", pmc); - } -} - -static int -powerpc_allocate_pmc(int cpu, int ri, struct pmc *pm, - const struct pmc_op_pmcallocate *a) -{ - enum pmc_event pe; - uint32_t caps, config, counter; - int i; + cc[frames++] = tf->srr0; + sp = (uintptr_t *)tf->fixreg[1]; - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, - ("[powerpc,%d] illegal row index %d", __LINE__, ri)); - - caps = a->pm_caps; - - /* - * TODO: Check actual class for different generations. - */ - if (a->pm_class != PMC_CLASS_PPC7450) - return (EINVAL); - pe = a->pm_ev; - for (i = 0; i < powerpc_event_codes_size; i++) { - if (powerpc_event_codes[i].pe_ev == pe) { - config = powerpc_event_codes[i].pe_code; - counter = powerpc_event_codes[i].pe_counter_mask; + for (frames = 1; frames < maxsamples; frames++) { + if (!INKERNEL(sp)) break; - } - } - if (i == powerpc_event_codes_size) - return (EINVAL); - - if ((counter & (1 << ri)) == 0) - return (EINVAL); - - if (caps & PMC_CAP_SYSTEM) - config |= POWERPC_PMC_KERNEL_ENABLE; - if (caps & PMC_CAP_USER) - config |= POWERPC_PMC_USER_ENABLE; - if ((caps & (PMC_CAP_USER | PMC_CAP_SYSTEM)) == 0) - config |= POWERPC_PMC_ENABLE; - - pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; - - PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); - - return 0; -} - -static int -powerpc_read_pmc(int cpu, int ri, pmc_value_t *v) -{ - struct pmc *pm; - pmc_value_t tmp; - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, - ("[powerpc,%d] illegal row index %d", __LINE__, ri)); - - pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; - tmp = powerpc_pmcn_read(ri); - PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); - if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) - *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); - else - *v = tmp; - - return 0; -} - -static int -powerpc_write_pmc(int cpu, int ri, pmc_value_t v) -{ - struct pmc *pm; - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, - ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); - - pm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; - - if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) - v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - - PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); - - powerpc_pmcn_write(ri, v); - - return 0; -} - -static int -powerpc_config_pmc(int cpu, int ri, struct pmc *pm) -{ - struct pmc_hw *phw; - - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, - ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); - - phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; - - KASSERT(pm == NULL || phw->phw_pmc == NULL, - ("[powerpc,%d] pm=%p phw->pm=%p hwpmc not unconfigured", - __LINE__, pm, phw->phw_pmc)); - - phw->phw_pmc = pm; - - return 0; -} - -static int -powerpc_start_pmc(int cpu, int ri) -{ - uint32_t config; - struct pmc *pm; - struct pmc_hw *phw; - register_t pmc_mmcr; - - phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; - pm = phw->phw_pmc; - config = pm->pm_md.pm_powerpc.pm_powerpc_evsel & ~POWERPC_PMC_ENABLE; - - /* Enable the PMC. */ - switch (ri) { - case 0: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC1SEL(pmc_mmcr, config); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 1: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC2SEL(pmc_mmcr, config); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 2: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC3SEL(pmc_mmcr, config); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - case 3: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC4SEL(pmc_mmcr, config); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 4: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC5SEL(pmc_mmcr, config); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - case 5: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC6SEL(pmc_mmcr, config); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - default: - break; + cc[frames++] = *(sp + 1); + sp = (uintptr_t *)*sp; } - - /* The mask is inverted (enable is 1) compared to the flags in MMCR0, which - * are Freeze flags. - */ - config = ~pm->pm_md.pm_powerpc.pm_powerpc_evsel & POWERPC_PMC_ENABLE; - - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr &= ~SPR_MMCR0_FC; - pmc_mmcr |= config; - mtspr(SPR_MMCR0, pmc_mmcr); - - return 0; -} - -static int -powerpc_stop_pmc(int cpu, int ri) -{ - struct pmc *pm; - struct pmc_hw *phw; - register_t pmc_mmcr; - - phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; - pm = phw->phw_pmc; - - /* - * Disable the PMCs. - */ - switch (ri) { - case 0: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC1SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 1: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC2SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 2: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC3SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - case 3: - pmc_mmcr = mfspr(SPR_MMCR0); - pmc_mmcr = PPC_SET_PMC4SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR0, pmc_mmcr); - break; - case 4: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC5SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - case 5: - pmc_mmcr = mfspr(SPR_MMCR1); - pmc_mmcr = PPC_SET_PMC6SEL(pmc_mmcr, 0); - mtspr(SPR_MMCR1, pmc_mmcr); - break; - default: - break; - } - return 0; -} - -static int -powerpc_release_pmc(int cpu, int ri, struct pmc *pmc) -{ - struct pmc_hw *phw; - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, - ("[powerpc,%d] illegal row-index %d", __LINE__, ri)); - - phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; - KASSERT(phw->phw_pmc == NULL, - ("[powerpc,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); - - return 0; + return (frames); } static int powerpc_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) { - return 0; + return (0); } static int powerpc_switch_out(struct pmc_cpu *pc, struct pmc_process *pp) { - return 0; -} - -static int -powerpc_intr(int cpu, struct trapframe *tf) -{ - int i, error, retval; - uint32_t config; - struct pmc *pm; - struct powerpc_cpu *pac; - pmc_value_t v; - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); - - PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, - TRAPF_USERMODE(tf)); - - retval = 0; - - pac = powerpc_pcpu[cpu]; - - /* - * look for all PMCs that have interrupted: - * - look for a running, sampling PMC which has overflowed - * and which has a valid 'struct pmc' association - * - * If found, we call a helper to process the interrupt. - */ - - for (i = 0; i < PPC_MAX_PMCS; i++) { - if ((pm = pac->pc_ppcpmcs[i].phw_pmc) == NULL || - !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { - continue; - } - - if (!POWERPC_PMC_HAS_OVERFLOWED(i)) - continue; - - retval = 1; /* Found an interrupting PMC. */ - - if (pm->pm_state != PMC_STATE_RUNNING) - continue; - - /* Stop the PMC, reload count. */ - v = pm->pm_sc.pm_reloadcount; - config = mfspr(SPR_MMCR0); - - mtspr(SPR_MMCR0, config | SPR_MMCR0_FC); - powerpc_pmcn_write(i, v); - - /* Restart the counter if logging succeeded. */ - error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, - TRAPF_USERMODE(tf)); - mtspr(SPR_MMCR0, config); - if (error != 0) - powerpc_stop_pmc(cpu, i); - atomic_add_int(retval ? &pmc_stats.pm_intr_processed : - &pmc_stats.pm_intr_ignored, 1); - - } - - /* Re-enable PERF exceptions. */ - mtspr(SPR_MMCR0, mfspr(SPR_MMCR0) | SPR_MMCR0_PMXE); - - return (retval); + return (0); } -static int +int powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) { int error; @@ -715,7 +89,7 @@ powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d], illegal CPU %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < PPC_MAX_PMCS, + KASSERT(ri >= 0 && ri < ppc_npmcs, ("[powerpc,%d] row-index %d out of range", __LINE__, ri)); phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; @@ -735,65 +109,20 @@ powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) return (0); } -static int +int powerpc_get_config(int cpu, int ri, struct pmc **ppm) { *ppm = powerpc_pcpu[cpu]->pc_ppcpmcs[ri].phw_pmc; - return 0; -} - -static int -powerpc_pcpu_init(struct pmc_mdep *md, int cpu) -{ - int first_ri, i; - struct pmc_cpu *pc; - struct powerpc_cpu *pac; - struct pmc_hw *phw; - - KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), - ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); - - powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC, - M_WAITOK|M_ZERO); - pac->pc_ppcpmcs = malloc(sizeof(struct pmc_hw) * PPC_MAX_PMCS, - M_PMC, M_WAITOK|M_ZERO); - pc = pmc_pcpu[cpu]; - first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450].pcd_ri; - KASSERT(pc != NULL, ("[powerpc,%d] NULL per-cpu pointer", __LINE__)); - - for (i = 0, phw = pac->pc_ppcpmcs; i < PPC_MAX_PMCS; i++, phw++) { - phw->phw_state = PMC_PHW_FLAG_IS_ENABLED | - PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i); - phw->phw_pmc = NULL; - pc->pc_hwpmcs[i + first_ri] = phw; - } - - /* Clear the MMCRs, and set FC, to disable all PMCs. */ - mtspr(SPR_MMCR0, SPR_MMCR0_FC | SPR_MMCR0_PMXE | SPR_MMCR0_PMC1CE | SPR_MMCR0_PMCNCE); - mtspr(SPR_MMCR1, 0); - - return 0; -} - -static int -powerpc_pcpu_fini(struct pmc_mdep *md, int cpu) -{ - uint32_t mmcr0 = mfspr(SPR_MMCR0); - - mmcr0 |= SPR_MMCR0_FC; - mtspr(SPR_MMCR0, mmcr0); - free(powerpc_pcpu[cpu]->pc_ppcpmcs, M_PMC); - free(powerpc_pcpu[cpu], M_PMC); - return 0; + return (0); } struct pmc_mdep * pmc_md_initialize() { struct pmc_mdep *pmc_mdep; - struct pmc_classdep *pcd; + int error; + uint16_t vers; /* * Allocate space for pointers to PMC HW descriptors and for @@ -807,30 +136,31 @@ pmc_md_initialize() pmc_mdep->pmd_cputype = PMC_CPU_PPC_7450; - pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_PPC7450]; - pcd->pcd_caps = POWERPC_PMC_CAPS; - pcd->pcd_class = PMC_CLASS_PPC7450; - pcd->pcd_num = PPC_MAX_PMCS; - pcd->pcd_ri = pmc_mdep->pmd_npmc; - pcd->pcd_width = 32; /* All PMCs, even in ppc970, are 32-bit */ - - pcd->pcd_allocate_pmc = powerpc_allocate_pmc; - pcd->pcd_config_pmc = powerpc_config_pmc; - pcd->pcd_pcpu_fini = powerpc_pcpu_fini; - pcd->pcd_pcpu_init = powerpc_pcpu_init; - pcd->pcd_describe = powerpc_describe; - pcd->pcd_get_config = powerpc_get_config; - pcd->pcd_read_pmc = powerpc_read_pmc; - pcd->pcd_release_pmc = powerpc_release_pmc; - pcd->pcd_start_pmc = powerpc_start_pmc; - pcd->pcd_stop_pmc = powerpc_stop_pmc; - pcd->pcd_write_pmc = powerpc_write_pmc; + vers = mfpvr() >> 16; - pmc_mdep->pmd_intr = powerpc_intr; pmc_mdep->pmd_switch_in = powerpc_switch_in; pmc_mdep->pmd_switch_out = powerpc_switch_out; - pmc_mdep->pmd_npmc += PPC_MAX_PMCS; + switch (vers) { + case MPC7447A: + case MPC7448: + case MPC7450: + case MPC7455: + case MPC7457: + error = pmc_mpc7xxx_initialize(pmc_mdep); + case IBM970: + case IBM970FX: + case IBM970MP: + default: + error = -1; + break; + } + + if (error != 0) { + pmc_mdep_free(pmc_mdep); + pmc_mdep = NULL; + return NULL; + } return (pmc_mdep); } diff --git a/sys/dev/hwpmc/hwpmc_powerpc.h b/sys/dev/hwpmc/hwpmc_powerpc.h new file mode 100644 index 0000000..5e3ca92 --- /dev/null +++ b/sys/dev/hwpmc/hwpmc_powerpc.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2013 Justin Hibbits + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _DEV_HWPMC_POWERPC_H_ +#define _DEV_HWPMC_POWERPC_H_ 1 + +#ifdef _KERNEL + +#define POWERPC_PMC_CAPS (PMC_CAP_INTERRUPT | PMC_CAP_USER | \ + PMC_CAP_SYSTEM | PMC_CAP_EDGE | \ + PMC_CAP_THRESHOLD | PMC_CAP_READ | \ + PMC_CAP_WRITE | PMC_CAP_INVERT | \ + PMC_CAP_QUALIFIER) + +#define POWERPC_PMC_KERNEL_ENABLE (0x1 << 30) +#define POWERPC_PMC_USER_ENABLE (0x1 << 31) + +#define POWERPC_PMC_ENABLE (POWERPC_PMC_KERNEL_ENABLE | POWERPC_PMC_USER_ENABLE) +#define POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(V) (0x80000000-(V)) +#define POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (0x80000000-(P)) + +struct powerpc_cpu { + struct pmc_hw *pc_ppcpmcs; +}; + +extern struct powerpc_cpu **powerpc_pcpu; + +extern int pmc_mpc7xxx_initialize(struct pmc_mdep *pmc_mdep); +extern int pmc_ppc970_initialize(struct pmc_mdep *pmc_mdep); + +extern int powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc); +extern int powerpc_get_config(int cpu, int ri, struct pmc **ppm); +#endif /* _KERNEL */ + +#endif /* _DEV_HWPMC_POWERPC_H_ */ diff --git a/sys/modules/hwpmc/Makefile b/sys/modules/hwpmc/Makefile index 8948805..0ebf7a1 100644 --- a/sys/modules/hwpmc/Makefile +++ b/sys/modules/hwpmc/Makefile @@ -29,7 +29,7 @@ SRCS+= hwpmc_ia64.c .endif .if ${MACHINE_CPUARCH} == "powerpc" -SRCS+= hwpmc_powerpc.c +SRCS+= hwpmc_powerpc.c hwpmc_mpc7xxx.c .endif .if ${MACHINE_CPUARCH} == "sparc64" diff --git a/sys/powerpc/include/pmc_mdep.h b/sys/powerpc/include/pmc_mdep.h index 3456368..678852b 100644 --- a/sys/powerpc/include/pmc_mdep.h +++ b/sys/powerpc/include/pmc_mdep.h @@ -7,7 +7,8 @@ #ifndef _MACHINE_PMC_MDEP_H_ #define _MACHINE_PMC_MDEP_H_ -#define PMC_MDEP_CLASS_INDEX_PPC7450 1 +#define PMC_MDEP_CLASS_INDEX_PPC7450 0 +#define PMC_MDEP_CLASS_INDEX_PPC970 0 union pmc_md_op_pmcallocate { uint64_t __pad[4]; -- cgit v1.1 From 67d6bf79922448fb405226340f66c60404c48d8c Mon Sep 17 00:00:00 2001 From: jhibbits Date: Tue, 3 Sep 2013 00:42:15 +0000 Subject: Enable PMC interrupt handling, and fix a DTrace trap handling bug. --- sys/powerpc/aim/trap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 97f4ca1..2edbbfa 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -197,13 +197,11 @@ trap(struct trapframe *frame) #ifdef HWPMC_HOOKS if (type == EXC_PERF && (pmc_intr != NULL)) { -#ifdef notyet - (*pmc_intr)(PCPU_GET(cpuid), frame); - if (!user) + (*pmc_intr)(PCPU_GET(cpuid), frame); + if (user) + userret(td, frame); return; -#endif } - else #endif #ifdef KDTRACE_HOOKS /* @@ -316,9 +314,11 @@ trap(struct trapframe *frame) if (*(uintptr_t *)frame->srr0 == 0x7c810808) { if (dtrace_invop_jump_addr != NULL) { dtrace_invop_jump_addr(frame); + return; } } } + break; #endif #ifdef __powerpc64__ case EXC_DSE: -- cgit v1.1 From b59e843b9f67d1b62296aea8d3e5a33f65bea7ea Mon Sep 17 00:00:00 2001 From: bryanv Date: Tue, 3 Sep 2013 02:26:57 +0000 Subject: Fix unintended compiler constant folding Pointed out by: dim@ --- sys/dev/virtio/virtqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/dev/virtio/virtqueue.c b/sys/dev/virtio/virtqueue.c index beff14c..5eda6cd 100644 --- a/sys/dev/virtio/virtqueue.c +++ b/sys/dev/virtio/virtqueue.c @@ -449,10 +449,10 @@ virtqueue_postpone_intr(struct virtqueue *vq, vq_postpone_t hint) switch (hint) { case VQ_POSTPONE_SHORT: - ndesc /= 4; + ndesc = ndesc / 4; break; case VQ_POSTPONE_LONG: - ndesc *= 3 / 4; + ndesc = (ndesc * 3) / 4; break; case VQ_POSTPONE_EMPTIED: break; -- cgit v1.1 From 2be33f6260dea6796085c2693f9d25570a6f5920 Mon Sep 17 00:00:00 2001 From: bryanv Date: Tue, 3 Sep 2013 02:28:31 +0000 Subject: Complete any pending Tx frames before attempting the next transmit Also complete pending frames in the watchdog function when the EVENT_IDX feature was negotiated just in case the completion interrupt was postponed. --- sys/dev/virtio/network/if_vtnet.c | 9 +++++++++ sys/dev/virtio/network/if_vtnetvar.h | 1 + 2 files changed, 10 insertions(+) (limited to 'sys') diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 5ab4b970b..93c6007 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -592,6 +592,9 @@ vtnet_setup_features(struct vtnet_softc *sc) vtnet_negotiate_features(sc); + if (virtio_with_feature(dev, VIRTIO_RING_F_EVENT_IDX)) + sc->vtnet_flags |= VTNET_FLAG_EVENT_IDX; + if (virtio_with_feature(dev, VIRTIO_NET_F_MAC)) { /* This feature should always be negotiated. */ sc->vtnet_flags |= VTNET_FLAG_MAC; @@ -2155,6 +2158,8 @@ vtnet_start_locked(struct vtnet_txq *txq, struct ifnet *ifp) sc->vtnet_link_active == 0) return; + vtnet_txq_eof(txq); + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { if (virtqueue_full(vq)) break; @@ -2226,6 +2231,8 @@ vtnet_txq_mq_start_locked(struct vtnet_txq *txq, struct mbuf *m) return (error); } + vtnet_txq_eof(txq); + while ((m = drbr_peek(ifp, br)) != NULL) { error = vtnet_txq_encap(txq, &m); if (error) { @@ -2471,6 +2478,8 @@ vtnet_watchdog(struct vtnet_txq *txq) sc = txq->vtntx_sc; VTNET_TXQ_LOCK(txq); + if (sc->vtnet_flags & VTNET_FLAG_EVENT_IDX) + vtnet_txq_eof(txq); if (txq->vtntx_watchdog == 0 || --txq->vtntx_watchdog) { VTNET_TXQ_UNLOCK(txq); return (0); diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h index 5921103..7f04a93 100644 --- a/sys/dev/virtio/network/if_vtnetvar.h +++ b/sys/dev/virtio/network/if_vtnetvar.h @@ -138,6 +138,7 @@ struct vtnet_softc { #define VTNET_FLAG_MRG_RXBUFS 0x0080 #define VTNET_FLAG_LRO_NOMRG 0x0100 #define VTNET_FLAG_MULTIQ 0x0200 +#define VTNET_FLAG_EVENT_IDX 0x0400 int vtnet_link_active; int vtnet_hdr_size; -- cgit v1.1 From bb22f91e17456594c9e4128dd0e8cd8a2f56569d Mon Sep 17 00:00:00 2001 From: uqs Date: Tue, 3 Sep 2013 12:08:08 +0000 Subject: Fix 'make depend' --- sys/modules/cam/Makefile | 1 + sys/modules/send/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/modules/cam/Makefile b/sys/modules/cam/Makefile index c2dec72..c3ecf56 100644 --- a/sys/modules/cam/Makefile +++ b/sys/modules/cam/Makefile @@ -13,6 +13,7 @@ SRCS+= opt_scsi.h SRCS+= opt_cd.h SRCS+= opt_pt.h SRCS+= opt_sa.h +SRCS+= opt_ses.h SRCS+= device_if.h bus_if.h vnode_if.h SRCS+= cam.c SRCS+= cam_compat.c diff --git a/sys/modules/send/Makefile b/sys/modules/send/Makefile index 1cb976b..06ea9e0 100644 --- a/sys/modules/send/Makefile +++ b/sys/modules/send/Makefile @@ -2,6 +2,6 @@ .PATH: ${.CURDIR}/../../netinet6 KMOD= send -SRCS= send.c +SRCS= send.c opt_kdtrace.h .include -- cgit v1.1 From e3bbc9eb391688555f18ba164956fff19f72368a Mon Sep 17 00:00:00 2001 From: gibbs Date: Tue, 3 Sep 2013 13:49:00 +0000 Subject: sys/dev/xen/blkback/blkback.c: Initialize the request id for requests in xbb_get_resources() instead of its previous location in xbb_dispatch_io(). This guarantees that all request types (e.g. BLKIF_OP_FLUSH_DISKCACHE) have the front-end specified id recorded. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Roger Pau Monné Sponsored by: Citrix Systems R&D --- sys/dev/xen/blkback/blkback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index 33f6faf..3ea3c97 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -1239,6 +1239,7 @@ xbb_get_resources(struct xbb_softc *xbb, struct xbb_xen_reqlist **reqlist, nreq->reqlist = *reqlist; nreq->req_ring_idx = ring_idx; + nreq->id = ring_req->id; if (xbb->abi != BLKIF_PROTOCOL_NATIVE) { bcopy(ring_req, &nreq->ring_req_storage, sizeof(*ring_req)); @@ -1608,7 +1609,6 @@ xbb_dispatch_io(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist) req_ring_idx = nreq->req_ring_idx; nr_sects = 0; nseg = ring_req->nr_segments; - nreq->id = ring_req->id; nreq->nr_pages = nseg; nreq->nr_512b_sectors = 0; req_seg_idx = 0; -- cgit v1.1 From 4f53813f88df44c7bf7c7c5d15d2fd3bada36ab7 Mon Sep 17 00:00:00 2001 From: emaste Date: Tue, 3 Sep 2013 15:22:04 +0000 Subject: Connect libexecinfo to the build Sponsored by: DARPA, AFRL --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/sys/param.h b/sys/sys/param.h index 2ba9201..88c8d37 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1000051 /* Master, propagated to newvers */ +#define __FreeBSD_version 1000052 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, -- cgit v1.1 From 8ec798134a6d611c2af470ec8576cfe300cef5e7 Mon Sep 17 00:00:00 2001 From: jmg Date: Tue, 3 Sep 2013 18:31:23 +0000 Subject: Use the fact that the AES-NI instructions can be pipelined to improve performance... Use SSE2 instructions for calculating the XTS tweek factor... Let the compiler do more work and handle register allocation by using intrinsics, now only the key schedule is in assembly... Replace .byte hard coded instructions w/ the proper instructions now that both clang and gcc support them... On my machine, pulling the code to userland I saw performance go from ~150MB/sec to 2GB/sec in XTS mode. GELI on GNOP saw a more modest increase of about 3x due to other system overhead (geom and opencrypto)... These changes allow almost full disk io rate w/ geli... Reviewed by: -current, -security Thanks to: Mike Hamburg for the XTS tweek algorithm --- sys/conf/files.amd64 | 7 +- sys/conf/files.i386 | 7 +- sys/crypto/aesni/aesencdec.h | 136 ++++++++++++++++++++++ sys/crypto/aesni/aesencdec_amd64.S | 135 ---------------------- sys/crypto/aesni/aesencdec_i386.S | 166 --------------------------- sys/crypto/aesni/aeskeys_amd64.S | 96 ++++++---------- sys/crypto/aesni/aesni.c | 8 +- sys/crypto/aesni/aesni.h | 15 +-- sys/crypto/aesni/aesni_wrap.c | 225 +++++++++++++++++++++++++++++-------- sys/modules/aesni/Makefile | 13 ++- 10 files changed, 380 insertions(+), 428 deletions(-) create mode 100644 sys/crypto/aesni/aesencdec.h delete mode 100644 sys/crypto/aesni/aesencdec_amd64.S delete mode 100644 sys/crypto/aesni/aesencdec_i386.S (limited to 'sys') diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 6d35d1f..1a66aa5 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -138,10 +138,13 @@ amd64/amd64/uma_machdep.c standard amd64/amd64/vm_machdep.c standard amd64/pci/pci_cfgreg.c optional pci cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}" -crypto/aesni/aesencdec_amd64.S optional aesni crypto/aesni/aeskeys_amd64.S optional aesni crypto/aesni/aesni.c optional aesni -crypto/aesni/aesni_wrap.c optional aesni +aesni_wrap.o optional aesni \ + dependency "$S/crypto/aesni/aesni_wrap.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -maes ${.IMPSRC}" \ + no-implicit-rule \ + clean "aesni_wrap.o" crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb crypto/via/padlock.c optional padlock diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 2ac0b61..24dac5f 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -124,10 +124,13 @@ bf_enc.o optional crypto | ipsec \ dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ no-implicit-rule -crypto/aesni/aesencdec_i386.S optional aesni crypto/aesni/aeskeys_i386.S optional aesni crypto/aesni/aesni.c optional aesni -crypto/aesni/aesni_wrap.c optional aesni +aesni_wrap.o optional aesni \ + dependency "$S/crypto/aesni/aesni_wrap.c" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -maes ${.IMPSRC}" \ + no-implicit-rule \ + clean "aesni_wrap.o" crypto/des/arch/i386/des_enc.S optional crypto | ipsec | netsmb crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock diff --git a/sys/crypto/aesni/aesencdec.h b/sys/crypto/aesni/aesencdec.h new file mode 100644 index 0000000..0c9bf5f --- /dev/null +++ b/sys/crypto/aesni/aesencdec.h @@ -0,0 +1,136 @@ +/*- + * Copyright 2013 John-Mark Gurney + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include + +static inline void +aesni_enc8(int rounds, const uint8_t *key_schedule, __m128i a, + __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g, + __m128i h, __m128i out[8]) +{ + const __m128i *keysched = (const __m128i *)key_schedule; + int i; + + a ^= keysched[0]; + b ^= keysched[0]; + c ^= keysched[0]; + d ^= keysched[0]; + e ^= keysched[0]; + f ^= keysched[0]; + g ^= keysched[0]; + h ^= keysched[0]; + + for (i = 0; i < rounds; i++) { + a = _mm_aesenc_si128(a, keysched[i + 1]); + b = _mm_aesenc_si128(b, keysched[i + 1]); + c = _mm_aesenc_si128(c, keysched[i + 1]); + d = _mm_aesenc_si128(d, keysched[i + 1]); + e = _mm_aesenc_si128(e, keysched[i + 1]); + f = _mm_aesenc_si128(f, keysched[i + 1]); + g = _mm_aesenc_si128(g, keysched[i + 1]); + h = _mm_aesenc_si128(h, keysched[i + 1]); + } + + out[0] = _mm_aesenclast_si128(a, keysched[i + 1]); + out[1] = _mm_aesenclast_si128(b, keysched[i + 1]); + out[2] = _mm_aesenclast_si128(c, keysched[i + 1]); + out[3] = _mm_aesenclast_si128(d, keysched[i + 1]); + out[4] = _mm_aesenclast_si128(e, keysched[i + 1]); + out[5] = _mm_aesenclast_si128(f, keysched[i + 1]); + out[6] = _mm_aesenclast_si128(g, keysched[i + 1]); + out[7] = _mm_aesenclast_si128(h, keysched[i + 1]); +} + +static inline void +aesni_dec8(int rounds, const uint8_t *key_schedule, __m128i a, + __m128i b, __m128i c, __m128i d, __m128i e, __m128i f, __m128i g, + __m128i h, __m128i out[8]) +{ + const __m128i *keysched = (const __m128i *)key_schedule; + int i; + + a ^= keysched[0]; + b ^= keysched[0]; + c ^= keysched[0]; + d ^= keysched[0]; + e ^= keysched[0]; + f ^= keysched[0]; + g ^= keysched[0]; + h ^= keysched[0]; + + for (i = 0; i < rounds; i++) { + a = _mm_aesdec_si128(a, keysched[i + 1]); + b = _mm_aesdec_si128(b, keysched[i + 1]); + c = _mm_aesdec_si128(c, keysched[i + 1]); + d = _mm_aesdec_si128(d, keysched[i + 1]); + e = _mm_aesdec_si128(e, keysched[i + 1]); + f = _mm_aesdec_si128(f, keysched[i + 1]); + g = _mm_aesdec_si128(g, keysched[i + 1]); + h = _mm_aesdec_si128(h, keysched[i + 1]); + } + + out[0] = _mm_aesdeclast_si128(a, keysched[i + 1]); + out[1] = _mm_aesdeclast_si128(b, keysched[i + 1]); + out[2] = _mm_aesdeclast_si128(c, keysched[i + 1]); + out[3] = _mm_aesdeclast_si128(d, keysched[i + 1]); + out[4] = _mm_aesdeclast_si128(e, keysched[i + 1]); + out[5] = _mm_aesdeclast_si128(f, keysched[i + 1]); + out[6] = _mm_aesdeclast_si128(g, keysched[i + 1]); + out[7] = _mm_aesdeclast_si128(h, keysched[i + 1]); +} + +static inline __m128i +aesni_enc(int rounds, const uint8_t *key_schedule, const __m128i from) +{ + __m128i tmp; + const __m128i *keysched = (const __m128i *)key_schedule; + int i; + + tmp = from ^ keysched[0]; + + for (i = 0; i < rounds; i++) + tmp = _mm_aesenc_si128(tmp, keysched[i + 1]); + + return _mm_aesenclast_si128(tmp, keysched[i + 1]); +} + +static inline __m128i +aesni_dec(int rounds, const uint8_t *key_schedule, const __m128i from) +{ + __m128i tmp; + const __m128i *keysched = (const __m128i *)key_schedule; + int i; + + tmp = from ^ keysched[0]; + + for (i = 0; i < rounds; i++) + tmp = _mm_aesdec_si128(tmp, keysched[i + 1]); + + return _mm_aesdeclast_si128(tmp, keysched[i + 1]); +} diff --git a/sys/crypto/aesni/aesencdec_amd64.S b/sys/crypto/aesni/aesencdec_amd64.S deleted file mode 100644 index f77918b..0000000 --- a/sys/crypto/aesni/aesencdec_amd64.S +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2010 Konstantin Belousov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - - .text - -ENTRY(aesni_enc) - .cfi_startproc - movdqu (%rdx),%xmm0 - cmpq $0,%r8 - je 1f - movdqu (%r8),%xmm1 /* unaligned load into reg */ - pxor %xmm1,%xmm0 /* pxor otherwise can fault on iv */ -1: - pxor (%rsi),%xmm0 -2: - addq $0x10,%rsi -// aesenc (%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdc,0x06 - decl %edi - jne 2b - addq $0x10,%rsi -// aesenclast (%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdd,0x06 - movdqu %xmm0,(%rcx) - retq - .cfi_endproc -END(aesni_enc) - -ENTRY(aesni_dec) - .cfi_startproc - movdqu (%rdx),%xmm0 - pxor (%rsi),%xmm0 -1: - addq $0x10,%rsi -// aesdec (%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x06 - decl %edi - jne 1b - addq $0x10,%rsi -// aesdeclast (%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x06 - cmpq $0,%r8 - je 2f - movdqu (%r8),%xmm1 - pxor %xmm1,%xmm0 -2: - movdqu %xmm0,(%rcx) - retq - .cfi_endproc -END(aesni_dec) - -ENTRY(aesni_decrypt_cbc) - .cfi_startproc - shrq $4,%rdx - movdqu (%r8),%xmm1 -1: - movdqu (%rcx),%xmm0 - movdqa %xmm0,%xmm2 - pxor (%rsi),%xmm0 - cmpl $12,%edi -// aesdec 0x10(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x10 -// aesdec 0x20(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x20 -// aesdec 0x30(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x30 -// aesdec 0x40(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x40 -// aesdec 0x50(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x50 -// aesdec 0x60(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x60 -// aesdec 0x70(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x46,0x70 -// aesdec 0x80(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0x80,0x00,0x00,0x00 -// aesdec 0x90(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0x90,0x00,0x00,0x00 - jge 2f -// aesdeclast 0xa0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x86,0xa0,0x00,0x00,0x00 - jmp 4f -2: -// aesdec 0xa0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0xa0,0x00,0x00,0x00 -// aesdec 0xb0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0xb0,0x00,0x00,0x00 - jg 3f -// aesdeclast 0xc0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x86,0xc0,0x00,0x00,0x00 - jmp 4f -3: -// aesdec 0xc0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0xc0,0x00,0x00,0x00 -// aesdec 0xd0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x86,0xd0,0x00,0x00,0x00 -// aesdeclast 0xe0(%rsi),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x86,0xe0,0x00,0x00,0x00 -4: - pxor %xmm1,%xmm0 - movdqu %xmm0,(%rcx) - movdqa %xmm2,%xmm1 // iv - addq $0x10,%rcx - decq %rdx - jne 1b - retq - .cfi_endproc -END(aesni_decrypt_cbc) - - .ident "$FreeBSD$" diff --git a/sys/crypto/aesni/aesencdec_i386.S b/sys/crypto/aesni/aesencdec_i386.S deleted file mode 100644 index 78de311..0000000 --- a/sys/crypto/aesni/aesencdec_i386.S +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * Copyright (c) 2010 Konstantin Belousov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -ENTRY(aesni_enc) - .cfi_startproc - pushl %ebp - .cfi_adjust_cfa_offset 4 - movl %esp,%ebp - movl 8(%ebp),%ecx /* rounds */ - movl 16(%ebp),%edx - movdqu (%edx),%xmm0 /* from */ - movl 24(%ebp),%eax /* iv */ - cmpl $0,%eax - je 1f - movdqu (%eax),%xmm1 - pxor %xmm1,%xmm0 -1: - movl 12(%ebp),%eax /* key */ - pxor (%eax),%xmm0 -2: - addl $0x10,%eax -// aesenc (%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdc,0x00 - loopne 2b - addl $0x10,%eax -// aesenclast (%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdd,0x00 - movl 20(%ebp),%eax - movdqu %xmm0,(%eax) /* to */ - leave - .cfi_adjust_cfa_offset -4 - retl - .cfi_endproc -END(aesni_enc) - -ENTRY(aesni_dec) - .cfi_startproc - pushl %ebp - .cfi_adjust_cfa_offset 4 - movl %esp,%ebp - movl 8(%ebp),%ecx /* rounds */ - movl 16(%ebp),%edx - movdqu (%edx),%xmm0 /* from */ - movl 12(%ebp),%eax /* key */ - pxor (%eax),%xmm0 -1: - addl $0x10,%eax -// aesdec (%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x00 - loopne 1b - addl $0x10,%eax -// aesdeclast (%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x00 - movl 24(%ebp),%eax - cmpl $0,%eax /* iv */ - je 2f - movdqu (%eax),%xmm1 - pxor %xmm1,%xmm0 -2: - movl 20(%ebp),%eax - movdqu %xmm0,(%eax) /* to */ - leave - .cfi_adjust_cfa_offset -4 - retl - .cfi_endproc -END(aesni_dec) - -ENTRY(aesni_decrypt_cbc) - .cfi_startproc - pushl %ebp - .cfi_adjust_cfa_offset 4 - movl %esp,%ebp - pushl %ebx - pushl %esi - movl 12(%ebp),%eax /* key */ - movl 16(%ebp),%ecx /* length */ - shrl $4,%ecx - movl 20(%ebp),%ebx /* buf */ - movl 24(%ebp),%esi - movdqu (%esi),%xmm1 /* iv */ - movl 8(%ebp),%esi /* rounds */ -1: - movdqu (%ebx),%xmm0 - movdqa %xmm0,%xmm2 - pxor (%eax),%xmm0 - cmpl $12,%esi -// aesdec 0x10(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x10 -// aesdec 0x20(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x20 -// aesdec 0x30(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x30 -// aesdec 0x40(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x40 -// aesdec 0x50(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x50 -// aesdec 0x60(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x60 -// aesdec 0x70(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x40,0x70 -// aesdec 0x80(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0x80,0x00,0x00,0x00 -// aesdec 0x90(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0x90,0x00,0x00,0x00 - jge 2f -// aesdeclast 0xa0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x80,0xa0,0x00,0x00,0x00 - jmp 4f -2: -// aesdec 0xa0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0xa0,0x00,0x00,0x00 -// aesdec 0xb0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0xb0,0x00,0x00,0x00 - jg 3f -// aesdeclast 0xc0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x80,0xc0,0x00,0x00,0x00 - jmp 4f -3: -// aesdec 0xc0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0xc0,0x00,0x00,0x00 -// aesdec 0xd0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xde,0x80,0xd0,0x00,0x00,0x00 -// aesdeclast 0xe0(%eax),%xmm0 - .byte 0x66,0x0f,0x38,0xdf,0x80,0xe0,0x00,0x00,0x00 -4: - pxor %xmm1,%xmm0 - movdqu %xmm0,(%ebx) - movdqa %xmm2,%xmm1 - addl $0x10,%ebx - decl %ecx - jne 1b - - popl %esi - popl %ebx - leave - .cfi_adjust_cfa_offset -4 - retl - .cfi_endproc -END(aesni_decrypt_cbc) - - .ident "$FreeBSD$" diff --git a/sys/crypto/aesni/aeskeys_amd64.S b/sys/crypto/aesni/aeskeys_amd64.S index 23a4d3d..9b3e98c 100644 --- a/sys/crypto/aesni/aeskeys_amd64.S +++ b/sys/crypto/aesni/aeskeys_amd64.S @@ -125,103 +125,72 @@ ENTRY(aesni_set_enckey) movups 0x10(%rdi),%xmm2 # other user key movaps %xmm2,(%rsi) addq $0x10,%rsi -// aeskeygenassist $0x1,%xmm2,%xmm1 # round 1 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x01 + aeskeygenassist $0x1,%xmm2,%xmm1 # round 1 call _key_expansion_256a -// aeskeygenassist $0x1,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x01 + aeskeygenassist $0x1,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x2,%xmm2,%xmm1 # round 2 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x02 + aeskeygenassist $0x2,%xmm2,%xmm1 # round 2 call _key_expansion_256a -// aeskeygenassist $0x2,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x02 + aeskeygenassist $0x2,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x4,%xmm2,%xmm1 # round 3 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x04 + aeskeygenassist $0x4,%xmm2,%xmm1 # round 3 call _key_expansion_256a -// aeskeygenassist $0x4,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x04 + aeskeygenassist $0x4,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x8,%xmm2,%xmm1 # round 4 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x08 + aeskeygenassist $0x8,%xmm2,%xmm1 # round 4 call _key_expansion_256a -// aeskeygenassist $0x8,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x08 + aeskeygenassist $0x8,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x10,%xmm2,%xmm1 # round 5 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x10 + aeskeygenassist $0x10,%xmm2,%xmm1 # round 5 call _key_expansion_256a -// aeskeygenassist $0x10,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x10 + aeskeygenassist $0x10,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x20,%xmm2,%xmm1 # round 6 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x20 + aeskeygenassist $0x20,%xmm2,%xmm1 # round 6 call _key_expansion_256a -// aeskeygenassist $0x20,%xmm0,%xmm1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x20 + aeskeygenassist $0x20,%xmm0,%xmm1 call _key_expansion_256b -// aeskeygenassist $0x40,%xmm2,%xmm1 # round 7 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x40 + aeskeygenassist $0x40,%xmm2,%xmm1 # round 7 call _key_expansion_256a retq .Lenc_key192: movq 0x10(%rdi),%xmm2 # other user key -// aeskeygenassist $0x1,%xmm2,%xmm1 # round 1 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x01 + aeskeygenassist $0x1,%xmm2,%xmm1 # round 1 call _key_expansion_192a -// aeskeygenassist $0x2,%xmm2,%xmm1 # round 2 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x02 + aeskeygenassist $0x2,%xmm2,%xmm1 # round 2 call _key_expansion_192b -// aeskeygenassist $0x4,%xmm2,%xmm1 # round 3 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x04 + aeskeygenassist $0x4,%xmm2,%xmm1 # round 3 call _key_expansion_192a -// aeskeygenassist $0x8,%xmm2,%xmm1 # round 4 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x08 + aeskeygenassist $0x8,%xmm2,%xmm1 # round 4 call _key_expansion_192b -// aeskeygenassist $0x10,%xmm2,%xmm1 # round 5 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x10 + aeskeygenassist $0x10,%xmm2,%xmm1 # round 5 call _key_expansion_192a -// aeskeygenassist $0x20,%xmm2,%xmm1 # round 6 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x20 + aeskeygenassist $0x20,%xmm2,%xmm1 # round 6 call _key_expansion_192b -// aeskeygenassist $0x40,%xmm2,%xmm1 # round 7 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x40 + aeskeygenassist $0x40,%xmm2,%xmm1 # round 7 call _key_expansion_192a -// aeskeygenassist $0x80,%xmm2,%xmm1 # round 8 - .byte 0x66,0x0f,0x3a,0xdf,0xca,0x80 + aeskeygenassist $0x80,%xmm2,%xmm1 # round 8 call _key_expansion_192b retq .Lenc_key128: -// aeskeygenassist $0x1,%xmm0,%xmm1 # round 1 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x01 + aeskeygenassist $0x1,%xmm0,%xmm1 # round 1 call _key_expansion_128 -// aeskeygenassist $0x2,%xmm0,%xmm1 # round 2 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x02 + aeskeygenassist $0x2,%xmm0,%xmm1 # round 2 call _key_expansion_128 -// aeskeygenassist $0x4,%xmm0,%xmm1 # round 3 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x04 + aeskeygenassist $0x4,%xmm0,%xmm1 # round 3 call _key_expansion_128 -// aeskeygenassist $0x8,%xmm0,%xmm1 # round 4 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x08 + aeskeygenassist $0x8,%xmm0,%xmm1 # round 4 call _key_expansion_128 -// aeskeygenassist $0x10,%xmm0,%xmm1 # round 5 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x10 + aeskeygenassist $0x10,%xmm0,%xmm1 # round 5 call _key_expansion_128 -// aeskeygenassist $0x20,%xmm0,%xmm1 # round 6 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x20 + aeskeygenassist $0x20,%xmm0,%xmm1 # round 6 call _key_expansion_128 -// aeskeygenassist $0x40,%xmm0,%xmm1 # round 7 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x40 + aeskeygenassist $0x40,%xmm0,%xmm1 # round 7 call _key_expansion_128 -// aeskeygenassist $0x80,%xmm0,%xmm1 # round 8 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x80 + aeskeygenassist $0x80,%xmm0,%xmm1 # round 8 call _key_expansion_128 -// aeskeygenassist $0x1b,%xmm0,%xmm1 # round 9 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x1b + aeskeygenassist $0x1b,%xmm0,%xmm1 # round 9 call _key_expansion_128 -// aeskeygenassist $0x36,%xmm0,%xmm1 # round 10 - .byte 0x66,0x0f,0x3a,0xdf,0xc8,0x36 + aeskeygenassist $0x36,%xmm0,%xmm1 # round 10 call _key_expansion_128 retq .cfi_endproc @@ -238,8 +207,7 @@ ENTRY(aesni_set_deckey) 1: addq $0x10,%rsi subq $0x10,%rdi -// aesimc (%rdi),%xmm1 - .byte 0x66,0x0f,0x38,0xdb,0x0f + aesimc (%rdi),%xmm1 movdqa %xmm1,(%rsi) decl %edx jne 1b diff --git a/sys/crypto/aesni/aesni.c b/sys/crypto/aesni/aesni.c index ca00a57..73eb28a 100644 --- a/sys/crypto/aesni/aesni.c +++ b/sys/crypto/aesni/aesni.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include "cryptodev_if.h" +#include struct aesni_softc { int32_t cid; @@ -74,6 +74,12 @@ aesni_probe(device_t dev) device_printf(dev, "No AESNI support.\n"); return (EINVAL); } + + if ((cpu_feature & CPUID_SSE2) == 0) { + device_printf(dev, "No SSE2 support but AESNI!?!\n"); + return (EINVAL); + } + device_set_desc_copy(dev, "AES-CBC,AES-XTS"); return (0); } diff --git a/sys/crypto/aesni/aesni.h b/sys/crypto/aesni/aesni.h index 78255b7..17ca9c5 100644 --- a/sys/crypto/aesni/aesni.h +++ b/sys/crypto/aesni/aesni.h @@ -71,12 +71,6 @@ struct aesni_session { /* * Internal functions, implemented in assembler. */ -void aesni_enc(int rounds, const uint8_t *key_schedule, - const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN], - const uint8_t iv[AES_BLOCK_LEN]); -void aesni_dec(int rounds, const uint8_t *key_schedule, - const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN], - const uint8_t iv[AES_BLOCK_LEN]); void aesni_set_enckey(const uint8_t *userkey, uint8_t *encrypt_schedule, int number_of_rounds); void aesni_set_deckey(const uint8_t *encrypt_schedule, @@ -88,12 +82,19 @@ void aesni_set_deckey(const uint8_t *encrypt_schedule, void aesni_encrypt_cbc(int rounds, const void *key_schedule, size_t len, const uint8_t *from, uint8_t *to, const uint8_t iv[AES_BLOCK_LEN]); void aesni_decrypt_cbc(int rounds, const void *key_schedule, size_t len, - const uint8_t *from, const uint8_t iv[AES_BLOCK_LEN]); + uint8_t *buf, const uint8_t iv[AES_BLOCK_LEN]); void aesni_encrypt_ecb(int rounds, const void *key_schedule, size_t len, const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN]); void aesni_decrypt_ecb(int rounds, const void *key_schedule, size_t len, const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN]); +void aesni_encrypt_xts(int rounds, const void *data_schedule, + const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to, + const uint8_t iv[AES_BLOCK_LEN]); +void aesni_decrypt_xts(int rounds, const void *data_schedule, + const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to, + const uint8_t iv[AES_BLOCK_LEN]); + int aesni_cipher_setup(struct aesni_session *ses, struct cryptoini *encini); int aesni_cipher_process(struct aesni_session *ses, diff --git a/sys/crypto/aesni/aesni_wrap.c b/sys/crypto/aesni/aesni_wrap.c index 3340b1f..197baf7 100644 --- a/sys/crypto/aesni/aesni_wrap.c +++ b/sys/crypto/aesni/aesni_wrap.c @@ -2,6 +2,7 @@ * Copyright (C) 2008 Damien Miller * Copyright (c) 2010 Konstantin Belousov * Copyright (c) 2010-2011 Pawel Jakub Dawidek + * Copyright 2012-2013 John-Mark Gurney * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,13 +29,15 @@ #include __FBSDID("$FreeBSD$"); - + #include #include #include #include #include #include + +#include "aesencdec.h" MALLOC_DECLARE(M_AESNI); @@ -42,28 +45,78 @@ void aesni_encrypt_cbc(int rounds, const void *key_schedule, size_t len, const uint8_t *from, uint8_t *to, const uint8_t iv[AES_BLOCK_LEN]) { - const uint8_t *ivp; + __m128i tot, ivreg; size_t i; len /= AES_BLOCK_LEN; - ivp = iv; + ivreg = _mm_loadu_si128((const __m128i *)iv); for (i = 0; i < len; i++) { - aesni_enc(rounds - 1, key_schedule, from, to, ivp); - ivp = to; + tot = aesni_enc(rounds - 1, key_schedule, + _mm_loadu_si128((const __m128i *)from) ^ ivreg); + ivreg = tot; + _mm_storeu_si128((__m128i *)to, tot); from += AES_BLOCK_LEN; to += AES_BLOCK_LEN; } } void -aesni_encrypt_ecb(int rounds, const void *key_schedule, size_t len, - const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN]) +aesni_decrypt_cbc(int rounds, const void *key_schedule, size_t len, + uint8_t *buf, const uint8_t iv[AES_BLOCK_LEN]) { - size_t i; + __m128i blocks[8]; + __m128i *bufs; + __m128i ivreg, nextiv; + size_t i, j, cnt; + + ivreg = _mm_loadu_si128((const __m128i *)iv); + cnt = len / AES_BLOCK_LEN / 8; + for (i = 0; i < cnt; i++) { + bufs = (__m128i *)buf; + aesni_dec8(rounds - 1, key_schedule, bufs[0], bufs[1], + bufs[2], bufs[3], bufs[4], bufs[5], bufs[6], + bufs[7], &blocks[0]); + for (j = 0; j < 8; j++) { + nextiv = bufs[j]; + bufs[j] = blocks[j] ^ ivreg; + ivreg = nextiv; + } + buf += AES_BLOCK_LEN * 8; + } + i *= 8; + cnt = len / AES_BLOCK_LEN; + for (; i < cnt; i++) { + bufs = (__m128i *)buf; + nextiv = bufs[0]; + bufs[0] = aesni_dec(rounds - 1, key_schedule, bufs[0]) ^ ivreg; + ivreg = nextiv; + buf += AES_BLOCK_LEN; + } +} - len /= AES_BLOCK_LEN; - for (i = 0; i < len; i++) { - aesni_enc(rounds - 1, key_schedule, from, to, NULL); +void +aesni_encrypt_ecb(int rounds, const void *key_schedule, size_t len, + const uint8_t *from, uint8_t *to) +{ + __m128i tot; + const __m128i *blocks; + size_t i, cnt; + + cnt = len / AES_BLOCK_LEN / 8; + for (i = 0; i < cnt; i++) { + blocks = (const __m128i *)from; + aesni_enc8(rounds - 1, key_schedule, blocks[0], blocks[1], + blocks[2], blocks[3], blocks[4], blocks[5], blocks[6], + blocks[7], (__m128i *)to); + from += AES_BLOCK_LEN * 8; + to += AES_BLOCK_LEN * 8; + } + i *= 8; + cnt = len / AES_BLOCK_LEN; + for (; i < cnt; i++) { + tot = aesni_enc(rounds - 1, key_schedule, + _mm_loadu_si128((const __m128i *)from)); + _mm_storeu_si128((__m128i *)to, tot); from += AES_BLOCK_LEN; to += AES_BLOCK_LEN; } @@ -73,11 +126,25 @@ void aesni_decrypt_ecb(int rounds, const void *key_schedule, size_t len, const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN]) { - size_t i; - - len /= AES_BLOCK_LEN; - for (i = 0; i < len; i++) { - aesni_dec(rounds - 1, key_schedule, from, to, NULL); + __m128i tot; + const __m128i *blocks; + size_t i, cnt; + + cnt = len / AES_BLOCK_LEN / 8; + for (i = 0; i < cnt; i++) { + blocks = (const __m128i *)from; + aesni_dec8(rounds - 1, key_schedule, blocks[0], blocks[1], + blocks[2], blocks[3], blocks[4], blocks[5], blocks[6], + blocks[7], (__m128i *)to); + from += AES_BLOCK_LEN * 8; + to += AES_BLOCK_LEN * 8; + } + i *= 8; + cnt = len / AES_BLOCK_LEN; + for (; i < cnt; i++) { + tot = aesni_dec(rounds - 1, key_schedule, + _mm_loadu_si128((const __m128i *)from)); + _mm_storeu_si128((__m128i *)to, tot); from += AES_BLOCK_LEN; to += AES_BLOCK_LEN; } @@ -87,34 +154,88 @@ aesni_decrypt_ecb(int rounds, const void *key_schedule, size_t len, #define AES_XTS_IVSIZE 8 #define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ +static inline __m128i +xts_crank_lfsr(__m128i inp) +{ + const __m128i alphamask = _mm_set_epi32(1, 1, 1, AES_XTS_ALPHA); + __m128i xtweak, ret; + + /* set up xor mask */ + xtweak = _mm_shuffle_epi32(inp, 0x93); + xtweak = _mm_srai_epi32(xtweak, 31); + xtweak &= alphamask; + + /* next term */ + ret = _mm_slli_epi32(inp, 1); + ret ^= xtweak; + + return ret; +} + static void -aesni_crypt_xts_block(int rounds, const void *key_schedule, uint64_t *tweak, - const uint64_t *from, uint64_t *to, uint64_t *block, int do_encrypt) +aesni_crypt_xts_block(int rounds, const void *key_schedule, __m128i *tweak, + const __m128i *from, __m128i *to, int do_encrypt) { - int carry; + __m128i block; - block[0] = from[0] ^ tweak[0]; - block[1] = from[1] ^ tweak[1]; + block = *from ^ *tweak; if (do_encrypt) - aesni_enc(rounds - 1, key_schedule, (uint8_t *)block, (uint8_t *)to, NULL); + block = aesni_enc(rounds - 1, key_schedule, block); else - aesni_dec(rounds - 1, key_schedule, (uint8_t *)block, (uint8_t *)to, NULL); + block = aesni_dec(rounds - 1, key_schedule, block); - to[0] ^= tweak[0]; - to[1] ^= tweak[1]; + *to = block ^ *tweak; - /* Exponentiate tweak. */ - carry = ((tweak[0] & 0x8000000000000000ULL) > 0); - tweak[0] <<= 1; - if (tweak[1] & 0x8000000000000000ULL) { - uint8_t *twk = (uint8_t *)tweak; + *tweak = xts_crank_lfsr(*tweak); +} - twk[0] ^= AES_XTS_ALPHA; - } - tweak[1] <<= 1; - if (carry) - tweak[1] |= 1; +static void +aesni_crypt_xts_block8(int rounds, const void *key_schedule, __m128i *tweak, + const __m128i *from, __m128i *to, int do_encrypt) +{ + __m128i tmptweak; + __m128i a, b, c, d, e, f, g, h; + __m128i tweaks[8]; + __m128i tmp[8]; + + tmptweak = *tweak; + + /* + * unroll the loop. This lets gcc put values directly in the + * register and saves memory accesses. + */ +#define PREPINP(v, pos) \ + do { \ + tweaks[(pos)] = tmptweak; \ + (v) = from[(pos)] ^ tmptweak; \ + tmptweak = xts_crank_lfsr(tmptweak); \ + } while (0) + PREPINP(a, 0); + PREPINP(b, 1); + PREPINP(c, 2); + PREPINP(d, 3); + PREPINP(e, 4); + PREPINP(f, 5); + PREPINP(g, 6); + PREPINP(h, 7); + *tweak = tmptweak; + + if (do_encrypt) + aesni_enc8(rounds - 1, key_schedule, a, b, c, d, e, f, g, h, + tmp); + else + aesni_dec8(rounds - 1, key_schedule, a, b, c, d, e, f, g, h, + tmp); + + to[0] = tmp[0] ^ tweaks[0]; + to[1] = tmp[1] ^ tweaks[1]; + to[2] = tmp[2] ^ tweaks[2]; + to[3] = tmp[3] ^ tweaks[3]; + to[4] = tmp[4] ^ tweaks[4]; + to[5] = tmp[5] ^ tweaks[5]; + to[6] = tmp[6] ^ tweaks[6]; + to[7] = tmp[7] ^ tweaks[7]; } static void @@ -122,9 +243,9 @@ aesni_crypt_xts(int rounds, const void *data_schedule, const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to, const uint8_t iv[AES_BLOCK_LEN], int do_encrypt) { - uint64_t block[AES_XTS_BLOCKSIZE / 8]; - uint8_t tweak[AES_XTS_BLOCKSIZE]; - size_t i; + __m128i tweakreg; + uint8_t tweak[AES_XTS_BLOCKSIZE] __aligned(16); + size_t i, cnt; /* * Prepare tweak as E_k2(IV). IV is specified as LE representation @@ -137,21 +258,27 @@ aesni_crypt_xts(int rounds, const void *data_schedule, #else #error Only LITTLE_ENDIAN architectures are supported. #endif - aesni_enc(rounds - 1, tweak_schedule, tweak, tweak, NULL); - - len /= AES_XTS_BLOCKSIZE; - for (i = 0; i < len; i++) { - aesni_crypt_xts_block(rounds, data_schedule, (uint64_t *)tweak, - (const uint64_t *)from, (uint64_t *)to, block, do_encrypt); + tweakreg = _mm_loadu_si128((__m128i *)&tweak[0]); + tweakreg = aesni_enc(rounds - 1, tweak_schedule, tweakreg); + + cnt = len / AES_XTS_BLOCKSIZE / 8; + for (i = 0; i < cnt; i++) { + aesni_crypt_xts_block8(rounds, data_schedule, &tweakreg, + (const __m128i *)from, (__m128i *)to, do_encrypt); + from += AES_XTS_BLOCKSIZE * 8; + to += AES_XTS_BLOCKSIZE * 8; + } + i *= 8; + cnt = len / AES_XTS_BLOCKSIZE; + for (; i < cnt; i++) { + aesni_crypt_xts_block(rounds, data_schedule, &tweakreg, + (const __m128i *)from, (__m128i *)to, do_encrypt); from += AES_XTS_BLOCKSIZE; to += AES_XTS_BLOCKSIZE; } - - bzero(tweak, sizeof(tweak)); - bzero(block, sizeof(block)); } -static void +void aesni_encrypt_xts(int rounds, const void *data_schedule, const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to, const uint8_t iv[AES_BLOCK_LEN]) @@ -161,7 +288,7 @@ aesni_encrypt_xts(int rounds, const void *data_schedule, iv, 1); } -static void +void aesni_decrypt_xts(int rounds, const void *data_schedule, const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to, const uint8_t iv[AES_BLOCK_LEN]) diff --git a/sys/modules/aesni/Makefile b/sys/modules/aesni/Makefile index 9e25a46..26dbedc 100644 --- a/sys/modules/aesni/Makefile +++ b/sys/modules/aesni/Makefile @@ -3,8 +3,17 @@ .PATH: ${.CURDIR}/../../crypto/aesni KMOD= aesni -SRCS= aesni.c aesni_wrap.c -SRCS+= aesencdec_${MACHINE_CPUARCH}.S aeskeys_${MACHINE_CPUARCH}.S +SRCS= aesni.c +SRCS+= aeskeys_${MACHINE_CPUARCH}.S SRCS+= device_if.h bus_if.h opt_bus.h cryptodev_if.h +OBJS+= aesni_wrap.o + +# Remove -nostdinc so we can get the intrinsics. +aesni_wrap.o: aesni_wrap.c + ${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} \ + -mmmx -msse -maes ${.IMPSRC} + ${CTFCONVERT_CMD} + .include + -- cgit v1.1 From 0ad83fb9853866226b8cf7681559a523baee8467 Mon Sep 17 00:00:00 2001 From: tuexen Date: Tue, 3 Sep 2013 19:31:59 +0000 Subject: Remove redundant field pr_sctp_on. MFC after: 1 week --- sys/netinet/sctp_indata.c | 2 +- sys/netinet/sctp_output.c | 9 +-------- sys/netinet/sctp_structs.h | 2 -- sys/netinet/sctp_timer.c | 2 +- sys/netinet/sctputil.c | 1 - 5 files changed, 3 insertions(+), 13 deletions(-) (limited to 'sys') diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index dc5b7e1..7ebf7f1 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -4718,7 +4718,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, } } TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); - if (tp1->pr_sctp_on) { + if (PR_SCTP_ENABLED(tp1->flags)) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; } diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index ddd9175..3d76b7e 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -6067,7 +6067,6 @@ sctp_get_frag_point(struct sctp_tcb *stcb, static void sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp) { - sp->pr_sctp_on = 0; /* * We assume that the user wants PR_SCTP_TTL if the user provides a * positive lifetime but does not specify any PR_SCTP policy. This @@ -6077,7 +6076,6 @@ sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp) */ if (PR_SCTP_ENABLED(sp->sinfo_flags)) { sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags); - sp->pr_sctp_on = 1; } else { return; } @@ -7425,13 +7423,8 @@ dont_do_it: } chk->send_size += pads; } - /* We only re-set the policy if it is on */ - if (sp->pr_sctp_on) { - sctp_set_prsctp_policy(sp); + if (PR_SCTP_ENABLED(chk->flags)) { asoc->pr_sctp_cnt++; - chk->pr_sctp_on = 1; - } else { - chk->pr_sctp_on = 0; } if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) { /* All done pull and kill the message */ diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 508e0e1..a8b86c6 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -446,7 +446,6 @@ struct sctp_tmit_chunk { uint8_t do_rtt; uint8_t book_size_scale; uint8_t no_fr_allowed; - uint8_t pr_sctp_on; uint8_t copy_by_ref; uint8_t window_probe; }; @@ -522,7 +521,6 @@ struct sctp_stream_queue_pending { uint8_t holds_key_ref; uint8_t msg_is_complete; uint8_t some_taken; - uint8_t pr_sctp_on; uint8_t sender_all_done; uint8_t put_last_out; uint8_t discard_rest; diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index a09ba34..833c94a 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -446,7 +446,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb) } } TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); - if (chk->pr_sctp_on) { + if (PR_SCTP_ENABLED(chk->flags)) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; } diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index bdc3c90..c101118 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -4833,7 +4833,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, atomic_add_int(&chk->whoTo->ref_count, 1); chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1); stcb->asoc.pr_sctp_cnt++; - chk->pr_sctp_on = 1; TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next); stcb->asoc.sent_queue_cnt++; stcb->asoc.pr_sctp_cnt++; -- cgit v1.1 From 8f38cafe697c2231df73bf68b210df1f6a325b58 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 3 Sep 2013 21:21:47 +0000 Subject: Add support for the 'invpcid' instruction to binutils and DDB's disassembler on amd64. MFC after: 1 month --- sys/amd64/amd64/db_disasm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/amd64/amd64/db_disasm.c b/sys/amd64/amd64/db_disasm.c index 46144e0..b229909 100644 --- a/sys/amd64/amd64/db_disasm.c +++ b/sys/amd64/amd64/db_disasm.c @@ -127,7 +127,7 @@ struct finst { static const struct inst db_inst_0f388x[] = { /*80*/ { "", TRUE, SDEP, op2(E, Rq), "invept" }, /*81*/ { "", TRUE, SDEP, op2(E, Rq), "invvpid" }, -/*82*/ { "", FALSE, NONE, 0, 0 }, +/*82*/ { "", TRUE, SDEP, op2(E, Rq), "invpcid" }, /*83*/ { "", FALSE, NONE, 0, 0 }, /*84*/ { "", FALSE, NONE, 0, 0 }, /*85*/ { "", FALSE, NONE, 0, 0 }, -- cgit v1.1 From 09ea56b1ca848cde0d84751e27d792fd33e7ab5b Mon Sep 17 00:00:00 2001 From: imp Date: Tue, 3 Sep 2013 22:04:55 +0000 Subject: Newer versions of gcc define __INT64_C and __UINT64_C, so avoid redefining them if gcc provides them. --- sys/mips/include/_stdint.h | 2 ++ sys/powerpc/include/_stdint.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'sys') diff --git a/sys/mips/include/_stdint.h b/sys/mips/include/_stdint.h index 510b8ea..ebf6eb5 100644 --- a/sys/mips/include/_stdint.h +++ b/sys/mips/include/_stdint.h @@ -66,6 +66,7 @@ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) +#ifndef __INT64_C #ifdef __mips_n64 #define __INT64_C(c) (c ## L) #define __UINT64_C(c) (c ## UL) @@ -73,6 +74,7 @@ #define __INT64_C(c) (c ## LL) #define __UINT64_C(c) (c ## ULL) #endif +#endif /* * ISO/IEC 9899:1999 diff --git a/sys/powerpc/include/_stdint.h b/sys/powerpc/include/_stdint.h index 6ad1fd2..9928a1a 100644 --- a/sys/powerpc/include/_stdint.h +++ b/sys/powerpc/include/_stdint.h @@ -65,6 +65,7 @@ #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) +#ifndef __INT64_C #ifdef __LP64__ #define __INT64_C(c) (c ## L) #define __UINT64_C(c) (c ## UL) @@ -72,6 +73,7 @@ #define __INT64_C(c) (c ## LL) #define __UINT64_C(c) (c ## ULL) #endif +#endif /* * ISO/IEC 9899:1999 -- cgit v1.1 From 3e7c5db622a38e9023feea4bf6f255018f73d77b Mon Sep 17 00:00:00 2001 From: sbruno Date: Tue, 3 Sep 2013 22:33:06 +0000 Subject: Add options GEOM_PART_GPT and options MSDOSFS to the DIR-825 Reviewed by: adrian@ --- sys/mips/conf/DIR-825 | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sys') diff --git a/sys/mips/conf/DIR-825 b/sys/mips/conf/DIR-825 index 62189cfc..7740d4d 100644 --- a/sys/mips/conf/DIR-825 +++ b/sys/mips/conf/DIR-825 @@ -54,12 +54,15 @@ options NO_SYSCTL_DESCR device geom_map # to get access to the SPI flash partitions device geom_uncompress # compressed in-memory filesystem hackery! options GEOM_UNCOMPRESS +options GEOM_PART_GPT options ROOTDEVNAME=\"ufs:/dev/map/rootfs.uncompress\" options AR71XX_REALMEM=64*1024*1024 options AR71XX_ENV_UBOOT +options MSDOSFS # Read MSDOS filesystems; useful for USB/CF + # options MD_ROOT # options MD_ROOT_SIZE="6144" -- cgit v1.1 From 297fdff2ee7de617834750c5c0bccefb87ab0374 Mon Sep 17 00:00:00 2001 From: np Date: Tue, 3 Sep 2013 23:34:04 +0000 Subject: For TOE connections, the window scale factor in CPL_PASS_ACCEPT_REQ is set to 15 to indicate that the peer did not send a window scale option with its SYN. Do not send a window scale option in the SYN|ACK reply in that case. --- sys/dev/cxgbe/tom/t4_listen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c index 9e1dc80..17f4adb 100644 --- a/sys/dev/cxgbe/tom/t4_listen.c +++ b/sys/dev/cxgbe/tom/t4_listen.c @@ -1007,7 +1007,7 @@ calc_opt2p(struct adapter *sc, struct port_info *pi, int rxqid, opt2 |= F_TSTAMPS_EN; if (tcpopt->sack) opt2 |= F_SACK_EN; - if (tcpopt->wsf > 0) + if (tcpopt->wsf <= 14) opt2 |= F_WND_SCALE_EN; } -- cgit v1.1 From 6fc9e86bed06cceacd24183cdcc5260109b6050a Mon Sep 17 00:00:00 2001 From: jhibbits Date: Wed, 4 Sep 2013 04:11:38 +0000 Subject: Fix hwpmc(4) for 32-bit PowerPC. --- sys/dev/hwpmc/hwpmc_powerpc.c | 9 ++------- sys/dev/hwpmc/hwpmc_powerpc.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c index a6453ec..c7d8f3d 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.c +++ b/sys/dev/hwpmc/hwpmc_powerpc.c @@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include /* For VM_MIN_KERNEL_ADDRESS/VM_MAX_KERNEL_ADDRESS */ @@ -44,11 +46,6 @@ __FBSDID("$FreeBSD$"); #define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \ ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS) -/* - * Per-processor information. - */ -static unsigned int ppc_npmcs; - int pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) @@ -89,8 +86,6 @@ powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d], illegal CPU %d", __LINE__, cpu)); - KASSERT(ri >= 0 && ri < ppc_npmcs, - ("[powerpc,%d] row-index %d out of range", __LINE__, ri)); phw = &powerpc_pcpu[cpu]->pc_ppcpmcs[ri]; snprintf(powerpc_name, sizeof(powerpc_name), "POWERPC-%d", ri); diff --git a/sys/dev/hwpmc/hwpmc_powerpc.h b/sys/dev/hwpmc/hwpmc_powerpc.h index 5e3ca92..a9b54f4 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.h +++ b/sys/dev/hwpmc/hwpmc_powerpc.h @@ -51,7 +51,6 @@ struct powerpc_cpu { extern struct powerpc_cpu **powerpc_pcpu; extern int pmc_mpc7xxx_initialize(struct pmc_mdep *pmc_mdep); -extern int pmc_ppc970_initialize(struct pmc_mdep *pmc_mdep); extern int powerpc_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc); extern int powerpc_get_config(int cpu, int ri, struct pmc **ppm); -- cgit v1.1 From 6246a085996b90b2d917d31003b5c534a10da6fd Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 4 Sep 2013 10:17:50 +0000 Subject: Make default cache size more modern. Requested by: Slawa Olhovchenkov --- sys/netgraph/netflow/ng_netflow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/netgraph/netflow/ng_netflow.h b/sys/netgraph/netflow/ng_netflow.h index 875a75d..0d708b7 100644 --- a/sys/netgraph/netflow/ng_netflow.h +++ b/sys/netgraph/netflow/ng_netflow.h @@ -416,7 +416,7 @@ struct netflow { * indexed by hash hash. Each hash element consist of tailqueue * head and mutex to protect this element. */ -#define CACHESIZE (65536*4) +#define CACHESIZE (65536*16) #define CACHELOWAT (CACHESIZE * 3/4) #define CACHEHIGHWAT (CACHESIZE * 9/10) uma_zone_t zone; -- cgit v1.1 From 00a02e74da5ce54cb9325f0270ca4a3d24ea36d3 Mon Sep 17 00:00:00 2001 From: jhb Date: Wed, 4 Sep 2013 11:52:28 +0000 Subject: Trim a couple of panic messages. --- sys/kern/subr_witness.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 37e8cf2..9d3040d 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1138,18 +1138,12 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file, iclass = LOCK_CLASS(interlock); lock1 = find_instance(lock_list, interlock); if (lock1 == NULL) - kassert_panic( - "interlock (%s) %s not locked while locking" - " %s @ %s:%d", + kassert_panic("interlock (%s) %s not locked @ %s:%d", iclass->lc_name, interlock->lo_name, - flags & LOP_EXCLUSIVE ? "exclusive" : "shared", fixup_filename(file), line); else if ((lock1->li_flags & LI_RECURSEMASK) != 0) - kassert_panic( - "interlock (%s) %s recursed while locking %s" - " @ %s:%d", + kassert_panic("interlock (%s) %s recursed @ %s:%d", iclass->lc_name, interlock->lo_name, - flags & LOP_EXCLUSIVE ? "exclusive" : "shared", fixup_filename(file), line); } -- cgit v1.1 From f978cc2905edf33ef1b241102709c3d80ddcd629 Mon Sep 17 00:00:00 2001 From: brooks Date: Wed, 4 Sep 2013 17:19:21 +0000 Subject: MFP4 217312, 222008, 222052, 222053, 222673, 231484, 231491, 231565, 570643 Rework the timeout code to use actual time rather than a DELAY() loop and to use both typical and maximum to allow logging of timeout failures. Also correct the erase timeout, it is specified in milliseconds not microseconds like the other timeouts. Do not invoke DELAY() between status queries as this adds significant latency which in turn reduced write performance substantially. Sanity check timeout values from the hardware. Implement support for buffered writes (only enabled on Intel/Sharp parts for now). This yields an order of magnitude speedup on the 64MB Intel StrataFlash parts we use. When making a copy of the block to modify, also keep a clean copy around until we are ready to commit the block and use it to avoid unnecessary erases. In the non-buffer write case, also use it to avoid unnecessary writes when the block has not been erased. This yields a significant speedup when doing things like zeroing a block. Sponsored by: DARPA, AFRL Reviewed by: imp (previous version) --- sys/dev/cfi/cfi_bus_nexus.c | 5 + sys/dev/cfi/cfi_core.c | 329 ++++++++++++++++++++++++++++++++++++++------ sys/dev/cfi/cfi_dev.c | 12 +- sys/dev/cfi/cfi_disk.c | 6 + sys/dev/cfi/cfi_reg.h | 14 +- sys/dev/cfi/cfi_var.h | 21 ++- 6 files changed, 340 insertions(+), 47 deletions(-) (limited to 'sys') diff --git a/sys/dev/cfi/cfi_bus_nexus.c b/sys/dev/cfi/cfi_bus_nexus.c index 1b317e6..4e1fa4e 100644 --- a/sys/dev/cfi/cfi_bus_nexus.c +++ b/sys/dev/cfi/cfi_bus_nexus.c @@ -4,6 +4,11 @@ * Copyright (c) 2009 Sam Leffler, Errno Consulting * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: diff --git a/sys/dev/cfi/cfi_core.c b/sys/dev/cfi/cfi_core.c index 083f5fc..f318ebc 100644 --- a/sys/dev/cfi/cfi_core.c +++ b/sys/dev/cfi/cfi_core.c @@ -1,7 +1,13 @@ /*- * Copyright (c) 2007, Juniper Networks, Inc. + * Copyright (c) 2012-2013, SRI International * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -49,6 +55,8 @@ __FBSDID("$FreeBSD$"); #include #include +static void cfi_add_sysctls(struct cfi_softc *); + extern struct cdevsw cfi_cdevsw; char cfi_driver_name[] = "cfi"; @@ -262,6 +270,7 @@ cfi_attach(device_t dev) struct cfi_softc *sc; u_int blksz, blocks; u_int r, u; + uint64_t mtoexp, ttoexp; #ifdef CFI_SUPPORT_STRATAFLASH uint64_t ppr; char name[KENV_MNAMELEN], value[32]; @@ -279,11 +288,79 @@ cfi_attach(device_t dev) sc->sc_tag = rman_get_bustag(sc->sc_res); sc->sc_handle = rman_get_bushandle(sc->sc_res); - /* Get time-out values for erase and write. */ - sc->sc_write_timeout = 1 << cfi_read_qry(sc, CFI_QRY_TTO_WRITE); - sc->sc_erase_timeout = 1 << cfi_read_qry(sc, CFI_QRY_TTO_ERASE); - sc->sc_write_timeout *= 1 << cfi_read_qry(sc, CFI_QRY_MTO_WRITE); - sc->sc_erase_timeout *= 1 << cfi_read_qry(sc, CFI_QRY_MTO_ERASE); + /* Get time-out values for erase, write, and buffer write. */ + ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_ERASE); + mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_ERASE); + if (ttoexp == 0) { + device_printf(dev, "erase timeout == 0, using 2^16ms\n"); + ttoexp = 16; + } + if (ttoexp > 41) { + device_printf(dev, "insane timeout: 2^%jdms\n", ttoexp); + return (EINVAL); + } + if (mtoexp == 0) { + device_printf(dev, "max erase timeout == 0, using 2^%jdms\n", + ttoexp + 4); + mtoexp = 4; + } + if (ttoexp + mtoexp > 41) { + device_printf(dev, "insane max erase timeout: 2^%jd\n", + ttoexp + mtoexp); + return (EINVAL); + } + sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] = SBT_1MS * (1ULL << ttoexp); + sc->sc_max_timeouts[CFI_TIMEOUT_ERASE] = + sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] * (1ULL << mtoexp); + + ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_WRITE); + mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_WRITE); + if (ttoexp == 0) { + device_printf(dev, "write timeout == 0, using 2^18ns\n"); + ttoexp = 18; + } + if (ttoexp > 51) { + device_printf(dev, "insane write timeout: 2^%jdus\n", ttoexp); + return (EINVAL); + } + if (mtoexp == 0) { + device_printf(dev, "max write timeout == 0, using 2^%jdms\n", + ttoexp + 4); + mtoexp = 4; + } + if (ttoexp + mtoexp > 51) { + device_printf(dev, "insane max write timeout: 2^%jdus\n", + ttoexp + mtoexp); + return (EINVAL); + } + sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] = SBT_1US * (1ULL << ttoexp); + sc->sc_max_timeouts[CFI_TIMEOUT_WRITE] = + sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] * (1ULL << mtoexp); + + ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE); + mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE); + /* Don't check for 0, it means not-supported. */ + if (ttoexp > 51) { + device_printf(dev, "insane write timeout: 2^%jdus\n", ttoexp); + return (EINVAL); + } + if (ttoexp + mtoexp > 51) { + device_printf(dev, "insane max write timeout: 2^%jdus\n", + ttoexp + mtoexp); + return (EINVAL); + } + sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] = + SBT_1US * (1ULL << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE)); + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE] = + sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] * + (1ULL << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE)); + + /* Get the maximum size of a multibyte program */ + if (sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] != 0) + sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) | + cfi_read_qry(sc, CFI_QRY_MAXBUF) << 8); + else + sc->sc_maxbuf = 0; /* Get erase regions. */ sc->sc_regions = cfi_read_qry(sc, CFI_QRY_NREGIONS); @@ -317,6 +394,8 @@ cfi_attach(device_t dev) "%s%u", cfi_driver_name, u); sc->sc_nod->si_drv1 = sc; + cfi_add_sysctls(sc); + #ifdef CFI_SUPPORT_STRATAFLASH /* * Store the Intel factory PPR in the environment. In some @@ -337,6 +416,45 @@ cfi_attach(device_t dev) return (0); } +static void +cfi_add_sysctls(struct cfi_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *children; + + ctx = device_get_sysctl_ctx(sc->sc_dev); + children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)); + + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "typical_erase_timout_count", + CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_ERASE], + 0, "Number of times the typical erase timeout was exceeded"); + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "max_erase_timout_count", + CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_ERASE], 0, + "Number of times the maximum erase timeout was exceeded"); + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "typical_write_timout_count", + CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_WRITE], 0, + "Number of times the typical write timeout was exceeded"); + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "max_write_timout_count", + CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_WRITE], 0, + "Number of times the maximum write timeout was exceeded"); + if (sc->sc_maxbuf > 0) { + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "typical_bufwrite_timout_count", + CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_BUFWRITE], 0, + "Number of times the typical buffered write timeout was " + "exceeded"); + SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + "max_bufwrite_timout_count", + CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_BUFWRITE], 0, + "Number of times the maximum buffered write timeout was " + "exceeded"); + } +} + int cfi_detach(device_t dev) { @@ -351,17 +469,22 @@ cfi_detach(device_t dev) } static int -cfi_wait_ready(struct cfi_softc *sc, u_int ofs, u_int timeout) +cfi_wait_ready(struct cfi_softc *sc, u_int ofs, sbintime_t start, + enum cfi_wait_cmd cmd) { - int done, error; + int done, error, tto_exceeded; uint32_t st0 = 0, st = 0; + sbintime_t now; done = 0; error = 0; - timeout *= 10; - while (!done && !error && timeout) { - DELAY(100); - timeout--; + tto_exceeded = 0; + while (!done && !error) { + /* + * Save time before we start so we always do one check + * after the timeout has expired. + */ + now = sbinuptime(); switch (sc->sc_cmdset) { case CFI_VEND_INTEL_ECS: @@ -390,6 +513,25 @@ cfi_wait_ready(struct cfi_softc *sc, u_int ofs, u_int timeout) done = ((st & 0x40) == (st0 & 0x40)) ? 1 : 0; break; } + + if (tto_exceeded || + now > start + sc->sc_typical_timeouts[cmd]) { + if (!tto_exceeded) { + tto_exceeded = 1; + sc->sc_tto_counts[cmd]++; +#ifdef CFI_DEBUG_TIMEOUT + device_printf(sc->sc_dev, + "typical timeout exceeded (cmd %d)", cmd); +#endif + } + if (now > start + sc->sc_max_timeouts[cmd]) { + sc->sc_mto_counts[cmd]++; +#ifdef CFI_DEBUG_TIMEOUT + device_printf(sc->sc_dev, + "max timeout exceeded (cmd %d)", cmd); +#endif + } + } } if (!done && !error) error = ETIMEDOUT; @@ -405,9 +547,12 @@ cfi_write_block(struct cfi_softc *sc) uint8_t *x8; uint16_t *x16; uint32_t *x32; - } ptr; + } ptr, cpyprt; register_t intr; - int error, i; + int error, i, neederase = 0; + uint32_t st; + u_int wlen; + sbintime_t start; /* Intel flash must be unlocked before modification */ switch (sc->sc_cmdset) { @@ -419,31 +564,124 @@ cfi_write_block(struct cfi_softc *sc) break; } - /* Erase the block. */ - switch (sc->sc_cmdset) { - case CFI_VEND_INTEL_ECS: - case CFI_VEND_INTEL_SCS: - cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE); - cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM); - break; - case CFI_VEND_AMD_SCS: - case CFI_VEND_AMD_ECS: - cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START, - CFI_AMD_ERASE_SECTOR); - cfi_amd_write(sc, sc->sc_wrofs, 0, CFI_AMD_BLOCK_ERASE); - break; - default: - /* Better safe than sorry... */ - return (ENODEV); - } - error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_erase_timeout); - if (error) - goto out; + /* Check if an erase is required. */ + for (i = 0; i < sc->sc_wrbufsz; i++) + if ((sc->sc_wrbuf[i] & sc->sc_wrbufcpy[i]) != sc->sc_wrbuf[i]) { + neederase = 1; + break; + } + + if (neederase) { + intr = intr_disable(); + start = sbinuptime(); + /* Erase the block. */ + switch (sc->sc_cmdset) { + case CFI_VEND_INTEL_ECS: + case CFI_VEND_INTEL_SCS: + cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE); + cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM); + break; + case CFI_VEND_AMD_SCS: + case CFI_VEND_AMD_ECS: + cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START, + CFI_AMD_ERASE_SECTOR); + cfi_amd_write(sc, sc->sc_wrofs, 0, CFI_AMD_BLOCK_ERASE); + break; + default: + /* Better safe than sorry... */ + intr_restore(intr); + return (ENODEV); + } + intr_restore(intr); + error = cfi_wait_ready(sc, sc->sc_wrofs, start, + CFI_TIMEOUT_ERASE); + if (error) + goto out; + } else + error = 0; - /* Write the block. */ + /* Write the block using a multibyte write if supported. */ ptr.x8 = sc->sc_wrbuf; + cpyprt.x8 = sc->sc_wrbufcpy; + if (sc->sc_maxbuf > sc->sc_width) { + switch (sc->sc_cmdset) { + case CFI_VEND_INTEL_ECS: + case CFI_VEND_INTEL_SCS: + for (i = 0; i < sc->sc_wrbufsz; i += wlen) { + wlen = MIN(sc->sc_maxbuf, sc->sc_wrbufsz - i); + + intr = intr_disable(); + + start = sbinuptime(); + do { + cfi_write(sc, sc->sc_wrofs + i, + CFI_BCS_BUF_PROG_SETUP); + if (sbinuptime() > start + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE]) { + error = ETIMEDOUT; + goto out; + } + st = cfi_read(sc, sc->sc_wrofs + i); + } while (! (st & CFI_INTEL_STATUS_WSMS)); + + cfi_write(sc, sc->sc_wrofs + i, + (wlen / sc->sc_width) - 1); + switch (sc->sc_width) { + case 1: + bus_space_write_region_1(sc->sc_tag, + sc->sc_handle, sc->sc_wrofs + i, + ptr.x8 + i, wlen); + break; + case 2: + bus_space_write_region_2(sc->sc_tag, + sc->sc_handle, sc->sc_wrofs + i, + ptr.x16 + i / 2, wlen / 2); + break; + case 4: + bus_space_write_region_4(sc->sc_tag, + sc->sc_handle, sc->sc_wrofs + i, + ptr.x32 + i / 4, wlen / 4); + break; + } + + cfi_write(sc, sc->sc_wrofs + i, + CFI_BCS_CONFIRM); + + intr_restore(intr); + + error = cfi_wait_ready(sc, sc->sc_wrofs + i, + start, CFI_TIMEOUT_BUFWRITE); + if (error != 0) + goto out; + } + goto out; + default: + /* Fall through to single word case */ + break; + } + + } + + /* Write the block one byte/word at a time. */ for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) { + /* Avoid writing unless we are actually changing bits */ + if (!neederase) { + switch (sc->sc_width) { + case 1: + if(*(ptr.x8 + i) == *(cpyprt.x8 + i)) + continue; + break; + case 2: + if(*(ptr.x16 + i / 2) == *(cpyprt.x16 + i / 2)) + continue; + break; + case 4: + if(*(ptr.x32 + i / 4) == *(cpyprt.x32 + i / 4)) + continue; + break; + } + } + /* * Make sure the command to start a write and the * actual write happens back-to-back without any @@ -451,6 +689,7 @@ cfi_write_block(struct cfi_softc *sc) */ intr = intr_disable(); + start = sbinuptime(); switch (sc->sc_cmdset) { case CFI_VEND_INTEL_ECS: case CFI_VEND_INTEL_SCS: @@ -464,21 +703,22 @@ cfi_write_block(struct cfi_softc *sc) switch (sc->sc_width) { case 1: bus_space_write_1(sc->sc_tag, sc->sc_handle, - sc->sc_wrofs + i, *(ptr.x8)++); + sc->sc_wrofs + i, *(ptr.x8 + i)); break; case 2: bus_space_write_2(sc->sc_tag, sc->sc_handle, - sc->sc_wrofs + i, *(ptr.x16)++); + sc->sc_wrofs + i, *(ptr.x16 + i / 2)); break; case 4: bus_space_write_4(sc->sc_tag, sc->sc_handle, - sc->sc_wrofs + i, *(ptr.x32)++); + sc->sc_wrofs + i, *(ptr.x32 + i / 4)); break; } - + intr_restore(intr); - error = cfi_wait_ready(sc, sc->sc_wrofs, sc->sc_write_timeout); + error = cfi_wait_ready(sc, sc->sc_wrofs, start, + CFI_TIMEOUT_WRITE); if (error) goto out; } @@ -576,6 +816,7 @@ cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id) #ifdef CFI_ARMEDANDDANGEROUS register_t intr; int i, error; + sbintime_t start; #endif if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) @@ -585,11 +826,12 @@ cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id) #ifdef CFI_ARMEDANDDANGEROUS for (i = 7; i >= 4; i--, id >>= 16) { intr = intr_disable(); + start = sbinuptime(); cfi_write(sc, 0, CFI_INTEL_PP_SETUP); cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff); intr_restore(intr); - error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, - sc->sc_write_timeout); + error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, + CFI_TIMEOUT_WRITE); if (error) break; } @@ -629,6 +871,7 @@ cfi_intel_set_plr(struct cfi_softc *sc) #ifdef CFI_ARMEDANDDANGEROUS register_t intr; int error; + sbintime_t start; #endif if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) return EOPNOTSUPP; @@ -638,10 +881,12 @@ cfi_intel_set_plr(struct cfi_softc *sc) /* worthy of console msg */ device_printf(sc->sc_dev, "set PLR\n"); intr = intr_disable(); + binuptime(&start); cfi_write(sc, 0, CFI_INTEL_PP_SETUP); cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD); intr_restore(intr); - error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, sc->sc_write_timeout); + error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, + CFI_TIMEOUT_WRITE); cfi_write(sc, 0, CFI_BCS_READ_ARRAY); return error; #else diff --git a/sys/dev/cfi/cfi_dev.c b/sys/dev/cfi/cfi_dev.c index d511eac..7d1f92b 100644 --- a/sys/dev/cfi/cfi_dev.c +++ b/sys/dev/cfi/cfi_dev.c @@ -1,7 +1,13 @@ /*- * Copyright (c) 2007, Juniper Networks, Inc. + * Copyright (c) 2012-2013, SRI International * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -72,7 +78,8 @@ struct cdevsw cfi_cdevsw = { * Begin writing into a new block/sector. We read the sector into * memory and keep updating that, until we move into another sector * or the process stops writing. At that time we write the whole - * sector to flash (see cfi_block_finish). + * sector to flash (see cfi_block_finish). To avoid unneeded erase + * cycles, keep a pristine copy of the sector on hand. */ int cfi_block_start(struct cfi_softc *sc, u_int ofs) @@ -116,6 +123,8 @@ cfi_block_start(struct cfi_softc *sc, u_int ofs) break; } } + sc->sc_wrbufcpy = malloc(sc->sc_wrbufsz, M_TEMP, M_WAITOK); + memcpy(sc->sc_wrbufcpy, sc->sc_wrbuf, sc->sc_wrbufsz); sc->sc_writing = 1; return (0); } @@ -131,6 +140,7 @@ cfi_block_finish(struct cfi_softc *sc) error = cfi_write_block(sc); free(sc->sc_wrbuf, M_TEMP); + free(sc->sc_wrbufcpy, M_TEMP); sc->sc_wrbuf = NULL; sc->sc_wrbufsz = 0; sc->sc_wrofs = 0; diff --git a/sys/dev/cfi/cfi_disk.c b/sys/dev/cfi/cfi_disk.c index f5bcb1b..7980722 100644 --- a/sys/dev/cfi/cfi_disk.c +++ b/sys/dev/cfi/cfi_disk.c @@ -1,7 +1,13 @@ /*- * Copyright (c) 2009 Sam Leffler, Errno Consulting + * Copyright (c) 2012-2013, SRI International * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: diff --git a/sys/dev/cfi/cfi_reg.h b/sys/dev/cfi/cfi_reg.h index 7c22211..c810e3f 100644 --- a/sys/dev/cfi/cfi_reg.h +++ b/sys/dev/cfi/cfi_reg.h @@ -1,7 +1,13 @@ /*- * Copyright (c) 2007, Juniper Networks, Inc. + * Copyright (c) 2012-2013, SRI International * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -44,8 +50,8 @@ struct cfi_qry { u_char max_vcc; u_char min_vpp; u_char max_vpp; - u_char tto_byte_write; /* 2**n milliseconds. */ - u_char tto_buf_write; /* 2**n milliseconds. */ + u_char tto_byte_write; /* 2**n microseconds. */ + u_char tto_buf_write; /* 2**n microseconds. */ u_char tto_block_erase; /* 2**n milliseconds. */ u_char tto_chip_erase; /* 2**n milliseconds. */ u_char mto_byte_write; /* 2**n times typical t/o. */ @@ -70,12 +76,15 @@ struct cfi_qry { #define CFI_QRY_VEND offsetof(struct cfi_qry, pri_vend) #define CFI_QRY_TTO_WRITE offsetof(struct cfi_qry, tto_byte_write) +#define CFI_QRY_TTO_BUFWRITE offsetof(struct cfi_qry, tto_buf_write) #define CFI_QRY_TTO_ERASE offsetof(struct cfi_qry, tto_block_erase) #define CFI_QRY_MTO_WRITE offsetof(struct cfi_qry, mto_byte_write) +#define CFI_QRY_MTO_BUFWRITE offsetof(struct cfi_qry, mto_buf_write) #define CFI_QRY_MTO_ERASE offsetof(struct cfi_qry, mto_block_erase) #define CFI_QRY_SIZE offsetof(struct cfi_qry, size) #define CFI_QRY_IFACE offsetof(struct cfi_qry, iface) +#define CFI_QRY_MAXBUF offsetof(struct cfi_qry, max_buf_write_size) #define CFI_QRY_NREGIONS offsetof(struct cfi_qry, nregions) #define CFI_QRY_REGION0 offsetof(struct cfi_qry, region) #define CFI_QRY_REGION(x) (CFI_QRY_REGION0 + (x) * 4) @@ -102,6 +111,7 @@ struct cfi_qry { #define CFI_BCS_ERASE_SUSPEND 0xb0 #define CFI_BCS_ERASE_RESUME 0xd0 /* Equals CONFIRM */ #define CFI_BCS_CONFIRM 0xd0 +#define CFI_BCS_BUF_PROG_SETUP 0xe8 #define CFI_BCS_READ_ARRAY 0xff /* Intel commands. */ diff --git a/sys/dev/cfi/cfi_var.h b/sys/dev/cfi/cfi_var.h index 15c7769..e218a4d 100644 --- a/sys/dev/cfi/cfi_var.h +++ b/sys/dev/cfi/cfi_var.h @@ -1,7 +1,13 @@ /*- * Copyright (c) 2007, Juniper Networks, Inc. + * Copyright (c) 2012-2013, SRI International * All rights reserved. * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * (FA8750-10-C-0237) ("CTSRD"), as part of the DARPA CRASH research + * programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,6 +38,12 @@ #ifndef _DEV_CFI_VAR_H_ #define _DEV_CFI_VAR_H_ +enum cfi_wait_cmd { + CFI_TIMEOUT_ERASE, + CFI_TIMEOUT_WRITE, + CFI_TIMEOUT_BUFWRITE +}; + struct cfi_region { u_int r_blocks; u_int r_blksz; @@ -51,13 +63,18 @@ struct cfi_softc { struct cfi_region *sc_region; /* Array of region info. */ u_int sc_cmdset; - u_int sc_erase_timeout; - u_int sc_write_timeout; + sbintime_t sc_typical_timeouts[3]; + sbintime_t sc_max_timeouts[3]; + u_int sc_tto_counts[3]; + u_int sc_mto_counts[3]; + + u_int sc_maxbuf; struct cdev *sc_nod; struct proc *sc_opened; /* Process that has us opened. */ u_char *sc_wrbuf; + u_char *sc_wrbufcpy; u_int sc_wrbufsz; u_int sc_wrofs; u_int sc_writing; -- cgit v1.1 From 30863284569c055ee48c4dd2b86af9f5626c834b Mon Sep 17 00:00:00 2001 From: eadler Date: Wed, 4 Sep 2013 18:42:05 +0000 Subject: Revert r255152: It turns out that synaptics_support was turned off by default because its probing method is too intrusive not because it was unstable. Once this is fixed it should be enabled once again. Reported by: delphij, jkim --- sys/dev/atkbdc/psm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 5a1fd37..9a6ae72 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -375,10 +375,10 @@ static devclass_t psm_devclass; static int tap_enabled = -1; TUNABLE_INT("hw.psm.tap_enabled", &tap_enabled); -static int synaptics_support = 1; +static int synaptics_support = 0; TUNABLE_INT("hw.psm.synaptics_support", &synaptics_support); -static int trackpoint_support = 1; +static int trackpoint_support = 0; TUNABLE_INT("hw.psm.trackpoint_support", &trackpoint_support); static int verbose = PSM_DEBUG; -- cgit v1.1 From 1eec0c04d002462ffc14d1d3a0e51db88bcecc7b Mon Sep 17 00:00:00 2001 From: gonzo Date: Wed, 4 Sep 2013 20:34:36 +0000 Subject: Add 32-bit support for Gxemul's oldtestmips machine emulation Original work by: kan@ --- sys/dev/gxemul/cons/gxemul_cons.c | 10 +++--- sys/dev/gxemul/disk/gxemul_disk.c | 15 +++++++++ sys/dev/gxemul/disk/gxemul_diskreg.h | 14 ++++++++- sys/dev/gxemul/ether/gxreg.h | 7 +++++ sys/mips/conf/GXEMUL32 | 61 ++++++++++++++++++++++++++++++++++++ sys/mips/gxemul/mpreg.h | 7 +++++ 6 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 sys/mips/conf/GXEMUL32 (limited to 'sys') diff --git a/sys/dev/gxemul/cons/gxemul_cons.c b/sys/dev/gxemul/cons/gxemul_cons.c index b83aa94..cb3b000 100644 --- a/sys/dev/gxemul/cons/gxemul_cons.c +++ b/sys/dev/gxemul/cons/gxemul_cons.c @@ -99,18 +99,16 @@ static void gxemul_cons_timeout(void *); * XXXRW: Should be using FreeBSD's bus routines here, but they are not * available until later in the boot. */ -typedef uint64_t paddr_t; -typedef uint64_t vaddr_t; -static inline vaddr_t -mips_phys_to_uncached(paddr_t phys) +static inline vm_offset_t +mips_phys_to_uncached(vm_paddr_t phys) { return (MIPS_PHYS_TO_DIRECT_UNCACHED(phys)); } static inline uint8_t -mips_ioread_uint8(vaddr_t vaddr) +mips_ioread_uint8(vm_offset_t vaddr) { uint8_t v; @@ -119,7 +117,7 @@ mips_ioread_uint8(vaddr_t vaddr) } static inline void -mips_iowrite_uint8(vaddr_t vaddr, uint8_t v) +mips_iowrite_uint8(vm_offset_t vaddr, uint8_t v) { __asm__ __volatile__ ("sb %0, 0(%1)" : : "r" (v), "r" (vaddr)); diff --git a/sys/dev/gxemul/disk/gxemul_disk.c b/sys/dev/gxemul/disk/gxemul_disk.c index 8cf52e4..3b7e649 100644 --- a/sys/dev/gxemul/disk/gxemul_disk.c +++ b/sys/dev/gxemul/disk/gxemul_disk.c @@ -214,7 +214,14 @@ gxemul_disk_read(unsigned diskid, void *buf, off_t off) if (off < 0 || off % GXEMUL_DISK_DEV_BLOCKSIZE != 0) return (EINVAL); +#ifdef _LP64 GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET, (uint64_t)off); +#else + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_LO, + (uint32_t)(off & 0xffffffff)); + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_HI, + (uint32_t)((off >> 32) & 0xffffffff)); +#endif GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_DISKID, diskid); GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_START, GXEMUL_DISK_DEV_START_READ); switch (GXEMUL_DISK_DEV_READ(GXEMUL_DISK_DEV_STATUS)) { @@ -280,7 +287,15 @@ gxemul_disk_write(unsigned diskid, const void *buf, off_t off) if (off < 0 || off % GXEMUL_DISK_DEV_BLOCKSIZE != 0) return (EINVAL); +#ifdef _LP64 GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET, (uint64_t)off); +#else + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_LO, + (uint32_t)(off & 0xffffffff)); + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_OFFSET_HI, + (uint32_t)((off >> 32) & 0xffffffff)); +#endif + GXEMUL_DISK_DEV_WRITE(GXEMUL_DISK_DEV_DISKID, diskid); dst = GXEMUL_DISK_DEV_FUNCTION(GXEMUL_DISK_DEV_BLOCK); diff --git a/sys/dev/gxemul/disk/gxemul_diskreg.h b/sys/dev/gxemul/disk/gxemul_diskreg.h index c3460e5..f837944 100644 --- a/sys/dev/gxemul/disk/gxemul_diskreg.h +++ b/sys/dev/gxemul/disk/gxemul_diskreg.h @@ -36,16 +36,28 @@ #define GXEMUL_DISK_DEV_ID_START (0x0000) #define GXEMUL_DISK_DEV_ID_END (0x0100) -#define GXEMUL_DISK_DEV_OFFSET (0x0000) +#ifdef _LP64 +#define GXEMUL_DISK_DEV_OFFSET (0x0000) +#else +#define GXEMUL_DISK_DEV_OFFSET_LO (0x0000) +#define GXEMUL_DISK_DEV_OFFSET_HI (0x0008) +#endif #define GXEMUL_DISK_DEV_DISKID (0x0010) #define GXEMUL_DISK_DEV_START (0x0020) #define GXEMUL_DISK_DEV_STATUS (0x0030) #define GXEMUL_DISK_DEV_BLOCK (0x4000) +#ifdef _LP64 #define GXEMUL_DISK_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_DISK_DEV_BASE + (f)) #define GXEMUL_DISK_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_DISK_DEV_FUNCTION(f) +#else +#define GXEMUL_DISK_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_DISK_DEV_BASE + (f)) +#define GXEMUL_DISK_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_DISK_DEV_FUNCTION(f) +#endif #define GXEMUL_DISK_DEV_WRITE(f, v) \ *GXEMUL_DISK_DEV_FUNCTION(f) = (v) diff --git a/sys/dev/gxemul/ether/gxreg.h b/sys/dev/gxemul/ether/gxreg.h index e67f43d..a528250 100644 --- a/sys/dev/gxemul/ether/gxreg.h +++ b/sys/dev/gxemul/ether/gxreg.h @@ -40,10 +40,17 @@ #define GXEMUL_ETHER_DEV_COMMAND (0x4020) #define GXEMUL_ETHER_DEV_MAC (0x4040) +#ifdef _LP64 #define GXEMUL_ETHER_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_ETHER_DEV_BASE + (f)) #define GXEMUL_ETHER_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_ETHER_DEV_FUNCTION(f) +#else +#define GXEMUL_ETHER_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_ETHER_DEV_BASE + (f)) +#define GXEMUL_ETHER_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_ETHER_DEV_FUNCTION(f) +#endif #define GXEMUL_ETHER_DEV_WRITE(f, v) \ *GXEMUL_ETHER_DEV_FUNCTION(f) = (v) diff --git a/sys/mips/conf/GXEMUL32 b/sys/mips/conf/GXEMUL32 new file mode 100644 index 0000000..6bd756f --- /dev/null +++ b/sys/mips/conf/GXEMUL32 @@ -0,0 +1,61 @@ +# +# GXEMUL "oldtestmips" sample kernel configuration. +# +# $FreeBSD$ +# + +ident GXEMUL + +machine mips mips +cpu CPU_MIPS4KC + +options HZ=100 + +makeoptions KERNLOADADDR=0x80100000 + +include "../gxemul/std.gxemul" + +hints "GXEMUL.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +# Make an SMP-capable kernel by default +options SMP # Symmetric MultiProcessor Kernel + +options SCHED_ULE +options INET # InterNETworking +options INET6 # IPv6 communications protocols + +options FFS #Berkeley Fast Filesystem + +# Debugging for use in -current +#options DEADLKRES #Enable the deadlock resolver +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +options ROOTDEVNAME=\"ufs:gxemul_disk0\" + +device gxemul_cons +device gxemul_disk +device gxemul_ether + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +device tun # Packet tunnel. +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter diff --git a/sys/mips/gxemul/mpreg.h b/sys/mips/gxemul/mpreg.h index e09946d..f562d07 100644 --- a/sys/mips/gxemul/mpreg.h +++ b/sys/mips/gxemul/mpreg.h @@ -43,10 +43,17 @@ #define GXEMUL_MP_DEV_IPI_READ 0x00c0 #define GXEMUL_MP_DEV_CYCLES 0x00d0 +#ifdef _LP64 #define GXEMUL_MP_DEV_FUNCTION(f) \ (volatile uint64_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) #define GXEMUL_MP_DEV_READ(f) \ (volatile uint64_t)*GXEMUL_MP_DEV_FUNCTION(f) +#else +#define GXEMUL_MP_DEV_FUNCTION(f) \ + (volatile uint32_t *)MIPS_PHYS_TO_DIRECT_UNCACHED(GXEMUL_MP_DEV_BASE + (f)) +#define GXEMUL_MP_DEV_READ(f) \ + (volatile uint32_t)*GXEMUL_MP_DEV_FUNCTION(f) +#endif #define GXEMUL_MP_DEV_WRITE(f, v) \ *GXEMUL_MP_DEV_FUNCTION(f) = (v) -- cgit v1.1 From 99fb6f77e5b8c132aeb7ed08996b210789c5e3aa Mon Sep 17 00:00:00 2001 From: rmacklem Date: Wed, 4 Sep 2013 22:47:56 +0000 Subject: Crashes have been observed for NFSv4.1 mounts when the system is being shut down which were caused by the nfscbd_pool being destroyed before the backchannel is disabled. This patch is believed to fix the problem, by simply avoiding ever destroying the nfscbd_pool. Since the NFS client module cannot be unloaded, this should not cause a memory leak. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clkrpc.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/fs/nfsclient/nfs_clkrpc.c b/sys/fs/nfsclient/nfs_clkrpc.c index 8b0b234..502fec5 100644 --- a/sys/fs/nfsclient/nfs_clkrpc.c +++ b/sys/fs/nfsclient/nfs_clkrpc.c @@ -278,17 +278,15 @@ nfsrvd_cbinit(int terminating) while (nfs_numnfscbd > 0) msleep(&nfs_numnfscbd, NFSDLOCKMUTEXPTR, PZERO, "nfscbdt", 0); - NFSD_UNLOCK(); - svcpool_destroy(nfscbd_pool); - nfscbd_pool = NULL; - } else - NFSD_UNLOCK(); - - nfscbd_pool = svcpool_create("nfscbd", NULL); - nfscbd_pool->sp_rcache = NULL; - nfscbd_pool->sp_assign = NULL; - nfscbd_pool->sp_done = NULL; + } - NFSD_LOCK(); + if (nfscbd_pool == NULL) { + NFSD_UNLOCK(); + nfscbd_pool = svcpool_create("nfscbd", NULL); + nfscbd_pool->sp_rcache = NULL; + nfscbd_pool->sp_assign = NULL; + nfscbd_pool->sp_done = NULL; + NFSD_LOCK(); + } } -- cgit v1.1 From 23ba68da73b54f9fe365d3131a80b52961a4c767 Mon Sep 17 00:00:00 2001 From: kib Date: Wed, 4 Sep 2013 23:31:29 +0000 Subject: Tidy up some loose ends in the PCID code: - Restore the pre-PCID TLB shootdown handlers for whole address space and single page invalidation asm code, and assign the IPI handler to them when PCID is not supported or disabled. Old handlers have linear control flow. But, still use the common return sequence. - Stop using pcpu for INVPCID descriptors in the invlrg handler. It is enough to allocate descriptors on the stack. As result, two SWAPGS instructions are shaved off from the code for Haswell+. - Fix the reverted condition in invlrng for checking of the PCID support [1], also in invlrng check that pmap is kernel pmap before performing other tests. For the kernel pmap, which provides global mappings, the INVLPG must be used for invalidation always. - Save the pre-computed pmap' %CR3 register in the struct pmap. This allows to remove several checks for pm_pcid validity when %CR3 is reloaded [2]. Noted by: gibbs [1] Discussed with: alc [2] Tested by: pho, flo Sponsored by: The FreeBSD Foundation --- sys/amd64/amd64/apic_vector.S | 110 +++++++++++++++++++++++++----------------- sys/amd64/amd64/genassym.c | 1 - sys/amd64/amd64/mp_machdep.c | 21 +++++--- sys/amd64/amd64/pmap.c | 31 ++++++------ sys/amd64/amd64/vm_machdep.c | 4 +- sys/amd64/include/pcpu.h | 1 - sys/amd64/include/pmap.h | 1 + sys/amd64/include/smp.h | 2 + 8 files changed, 98 insertions(+), 73 deletions(-) (limited to 'sys') diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 79ec5ed..d002b4d 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -168,7 +168,7 @@ global_invltlb: invltlb_ret_clear_pm_save: movq smp_tlb_pmap,%rdx testq %rdx,%rdx - jz invltlb_ret + jz invltlb_ret_rdx testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) jz 1f swapgs @@ -179,16 +179,17 @@ invltlb_ret_clear_pm_save: 2: LK btcl %eax,PM_SAVE(%rdx) SUPERALIGN_TEXT -invltlb_ret: +invltlb_ret_rdx: + popq %rdx +invltlb_ret_rax: movq lapic, %rax movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ LK incl smp_tlb_wait - popq %rdx popq %rax jmp doreti_iret SUPERALIGN_TEXT -IDTVEC(invltlb) +IDTVEC(invltlb_pcid) #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) PUSH_FRAME movl PCPU(CPUID), %eax @@ -206,8 +207,6 @@ IDTVEC(invltlb) pushq %rdx movq %cr3,%rax - cmpl $0,pmap_pcid_enabled - je 2f movq $smp_tlb_invpcid,%rdx cmpl $0,(%rdx) @@ -216,8 +215,7 @@ IDTVEC(invltlb) je global_invltlb /* - * Non-zero smp_tlb_invpcid, only invalidate TLB for entries with - * current PCID. + * Only invalidate TLB for entries with current PCID. */ cmpl $0,invpcid_works je 1f @@ -233,21 +231,36 @@ IDTVEC(invltlb) je 2f movq %rdx,%cr3 /* Invalidate, bit 63 is zero. */ btsq $63,%rax - - /* - * Invalidate the TLB if PCID is not enabled. - * Restore the old address space. - */ 2: movq %rax,%cr3 jmp invltlb_ret_clear_pm_save + SUPERALIGN_TEXT +IDTVEC(invltlb) +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + PUSH_FRAME + movl PCPU(CPUID), %eax +#ifdef COUNT_XINVLTLB_HITS + incl xhits_gbl(,%rax,4) +#endif +#ifdef COUNT_IPIS + movq ipi_invltlb_counts(,%rax,8),%rax + incq (%rax) +#endif + POP_FRAME +#endif + + pushq %rax + movq %cr3, %rax /* invalidate the TLB */ + movq %rax, %cr3 + jmp invltlb_ret_rax + /* * Single page TLB shootdown */ .text SUPERALIGN_TEXT -IDTVEC(invlpg) +IDTVEC(invlpg_pcid) #if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) PUSH_FRAME movl PCPU(CPUID), %eax @@ -264,8 +277,6 @@ IDTVEC(invlpg) pushq %rax pushq %rdx movq $smp_tlb_invpcid,%rdx - cmpl $0,pmap_pcid_enabled - je 3f cmpl $0,invpcid_works jne 2f @@ -291,7 +302,7 @@ IDTVEC(invlpg) btsq $63,%rcx movq %rcx,%cr3 popq %rcx - jmp invltlb_ret + jmp invltlb_ret_rdx /* * Invalidate the TLB entry using INVPCID_ADDR. @@ -300,7 +311,7 @@ IDTVEC(invlpg) xorl %eax,%eax /* invpcid (%rdx),%rax */ .byte 0x66,0x0f,0x38,0x82,0x02 - jmp invltlb_ret + jmp invltlb_ret_rdx /* * PCID is not supported or kernel pmap. @@ -309,7 +320,27 @@ IDTVEC(invlpg) 3: movq 8(%rdx),%rax invlpg (%rax) - jmp invltlb_ret + jmp invltlb_ret_rdx + + SUPERALIGN_TEXT +IDTVEC(invlpg) +#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) + PUSH_FRAME + movl PCPU(CPUID), %eax +#ifdef COUNT_XINVLTLB_HITS + incl xhits_pg(,%rax,4) +#endif +#ifdef COUNT_IPIS + movq ipi_invlpg_counts(,%rax,8),%rax + incq (%rax) +#endif + POP_FRAME +#endif + + pushq %rax + movq smp_tlb_invpcid+8,%rax + invlpg (%rax) /* invalidate single page */ + jmp invltlb_ret_rax /* * Page range TLB shootdown. @@ -334,15 +365,15 @@ IDTVEC(invlrng) pushq %rdx movq $smp_tlb_invpcid,%rdx cmpl $0,pmap_pcid_enabled - jne invlrng_single_page - cmpl $0,invpcid_works - jne invlrng_invpcid + je invlrng_single_page /* kernel pmap - use invlpg to invalidate global mapping */ cmpl $0,(%rdx) je invlrng_single_page cmpl $-1,(%rdx) je global_invltlb + cmpl $0,invpcid_works + jne invlrng_invpcid pushq %rcx movq %cr3,%rcx @@ -362,37 +393,27 @@ IDTVEC(invlrng) btsq $63,%rcx movq %rcx,%cr3 popq %rcx - jmp invltlb_ret + jmp invltlb_ret_rdx invlrng_invpcid: - testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) - jz 1f - swapgs -1: pushq %rcx + subq $16,%rsp movq (%rdx),%rcx - movq %rcx,PCPU(INVPCID_DESCR) + movq %rcx,(%rsp) movq 8(%rdx),%rax - movq %rax,PCPU(INVPCID_DESCR)+8 + movq %rax,8(%rsp) movq smp_tlb_addr2,%rcx - xorl %eax,%eax - movq $PC_INVPCID_DESCR,%rdx - gs - subq 8(%rdx),%rcx + subq %rax,%rcx shrq $PAGE_SHIFT,%rcx -2: - gs +1: // invpcid (%rdx),%rax .byte 0x66,0x0f,0x38,0x82,0x02 - gs - addq $PAGE_SIZE,8(%rdx) + addq $PAGE_SIZE,8(%rsp) dec %rcx - jne 2b + jne 1b + addq $16,%rsp popq %rcx - testb $SEL_RPL_MASK,NAKE_INTR_CS(%rsp) - jz invltlb_ret - swapgs - jmp invltlb_ret + jmp invltlb_ret_rdx invlrng_single_page: movq 8(%rdx),%rdx @@ -401,7 +422,7 @@ invlrng_single_page: addq $PAGE_SIZE,%rdx cmpq %rax,%rdx jb 1b - jmp invltlb_ret + jmp invltlb_ret_rdx /* * Invalidate cache. @@ -418,9 +439,8 @@ IDTVEC(invlcache) #endif pushq %rax - pushq %rdx wbinvd - jmp invltlb_ret + jmp invltlb_ret_rax /* * Handler for IPIs sent via the per-cpu IPI bitmap. diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 62017e7..028a2cd 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -228,7 +228,6 @@ ASSYM(PC_LDT, offsetof(struct pcpu, pc_ldt)); ASSYM(PC_COMMONTSSP, offsetof(struct pcpu, pc_commontssp)); ASSYM(PC_TSS, offsetof(struct pcpu, pc_tss)); ASSYM(PC_PM_SAVE_CNT, offsetof(struct pcpu, pc_pm_save_cnt)); -ASSYM(PC_INVPCID_DESCR, offsetof(struct pcpu, pc_invpcid_descr)); ASSYM(LA_VER, offsetof(struct LAPIC, version)); ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 530aa61..3addd43 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -127,6 +127,8 @@ static u_long *ipi_hardclock_counts[MAXCPU]; extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); +extern int pmap_pcid_enabled; + /* * Local data and functions. */ @@ -524,8 +526,15 @@ cpu_mp_start(void) } /* Install an inter-CPU IPI for TLB invalidation */ - setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); - setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); + if (pmap_pcid_enabled) { + setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT, + SEL_KPL, 0); + setidt(IPI_INVLPG, IDTVEC(invlpg_pcid), SDT_SYSIGT, + SEL_KPL, 0); + } else { + setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); + setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); + } setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0); /* Install an inter-CPU IPI for cache invalidation. */ @@ -605,8 +614,6 @@ cpu_mp_announce(void) } } -extern int pmap_pcid_enabled; - /* * AP CPU's call this to initialize themselves. */ @@ -1141,8 +1148,7 @@ smp_tlb_shootdown(u_int vector, pmap_t pmap, vm_offset_t addr1, smp_tlb_invpcid.pcid = 0; } else { smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | - (pmap->pm_pcid == -1 ? 0 : pmap->pm_pcid); + pcid_cr3 = pmap->pm_cr3; } smp_tlb_addr2 = addr2; smp_tlb_pmap = pmap; @@ -1176,8 +1182,7 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, smp_tlb_invpcid.pcid = 0; } else { smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | - (pmap->pm_pcid == -1 ? 0 : pmap->pm_pcid); + pcid_cr3 = pmap->pm_cr3; } smp_tlb_addr2 = addr2; smp_tlb_pmap = pmap; diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d905961..cecd92d 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -728,6 +728,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr) */ PMAP_LOCK_INIT(kernel_pmap); kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys); + kernel_pmap->pm_cr3 = KPML4phys; CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */ CPU_ZERO(&kernel_pmap->pm_save); TAILQ_INIT(&kernel_pmap->pm_pvchunk); @@ -1049,8 +1050,7 @@ pmap_invalidate_page_pcid(pmap_t pmap, vm_offset_t va) cr3 = rcr3(); critical_enter(); - load_cr3(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | pmap->pm_pcid | - CR3_PCID_SAVE); + load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); invlpg(va); load_cr3(cr3 | CR3_PCID_SAVE); critical_exit(); @@ -1137,8 +1137,7 @@ pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) cr3 = rcr3(); critical_enter(); - load_cr3(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4) | pmap->pm_pcid | - CR3_PCID_SAVE); + load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); load_cr3(cr3 | CR3_PCID_SAVE); @@ -1239,8 +1238,7 @@ pmap_invalidate_all(pmap_t pmap) * Bit 63 is clear, pcid TLB * entries are invalidated. */ - load_cr3(DMAP_TO_PHYS((vm_offset_t) - pmap->pm_pml4) | pmap->pm_pcid); + load_cr3(pmap->pm_cr3); load_cr3(cr3 | CR3_PCID_SAVE); critical_exit(); } @@ -1862,6 +1860,7 @@ pmap_pinit0(pmap_t pmap) PMAP_LOCK_INIT(pmap); pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys); + pmap->pm_cr3 = KPML4phys; pmap->pm_root.rt_root = 0; CPU_ZERO(&pmap->pm_active); CPU_ZERO(&pmap->pm_save); @@ -1869,7 +1868,6 @@ pmap_pinit0(pmap_t pmap) TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); pmap->pm_pcid = pmap_pcid_enabled ? 0 : -1; - CPU_ZERO(&pmap->pm_save); } /* @@ -1889,7 +1887,8 @@ pmap_pinit(pmap_t pmap) VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL) VM_WAIT; - pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml4pg)); + pmap->pm_cr3 = VM_PAGE_TO_PHYS(pml4pg); + pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(pmap->pm_cr3); if ((pml4pg->flags & PG_ZERO) == 0) pagezero(pmap->pm_pml4); @@ -1911,7 +1910,13 @@ pmap_pinit(pmap_t pmap) CPU_ZERO(&pmap->pm_active); TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); - pmap->pm_pcid = pmap_pcid_enabled ? alloc_unr(&pcid_unr) : -1; + if (pmap_pcid_enabled) { + pmap->pm_pcid = alloc_unr(&pcid_unr); + if (pmap->pm_pcid != -1) + pmap->pm_cr3 |= pmap->pm_pcid; + } else { + pmap->pm_pcid = -1; + } CPU_ZERO(&pmap->pm_save); return (1); @@ -5936,7 +5941,6 @@ pmap_activate(struct thread *td) { pmap_t pmap, oldpmap; u_int cpuid; - u_int64_t cr3; critical_enter(); pmap = vmspace_pmap(td->td_proc->p_vmspace); @@ -5951,11 +5955,8 @@ pmap_activate(struct thread *td) CPU_SET(cpuid, &pmap->pm_active); CPU_SET(cpuid, &pmap->pm_save); #endif - cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4); - if (pmap->pm_pcid != -1) - cr3 |= pmap->pm_pcid; - td->td_pcb->pcb_cr3 = cr3; - load_cr3(cr3); + td->td_pcb->pcb_cr3 = pmap->pm_cr3; + load_cr3(pmap->pm_cr3); PCPU_SET(curpmap, pmap); critical_exit(); } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 3764f72..3e961e9 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -220,9 +220,7 @@ cpu_fork(td1, p2, td2, flags) * return address on stack. These are the kernel mode register values. */ pmap2 = vmspace_pmap(p2->p_vmspace); - pcb2->pcb_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap2->pm_pml4); - if (pmap2->pm_pcid != -1) - pcb2->pcb_cr3 |= pmap2->pm_pcid; + pcb2->pcb_cr3 = pmap2->pm_cr3; pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */ pcb2->pcb_rbp = 0; pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *); diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index 0e11975..387df1a 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -68,7 +68,6 @@ /* Pointer to the CPU TSS descriptor */ \ struct system_segment_descriptor *pc_tss; \ uint64_t pc_pm_save_cnt; \ - char pc_invpcid_descr[16]; \ u_int pc_cmci_mask; /* MCx banks for CMCI */ \ uint64_t pc_dbreg[16]; /* ddb debugging regs */ \ int pc_dbreg_cmd; /* ddb debugging reg cmd */ \ diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index fa42389..b570cb7 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -238,6 +238,7 @@ struct md_page { struct pmap { struct mtx pm_mtx; pml4_entry_t *pm_pml4; /* KVA of level 4 page table */ + uint64_t pm_cr3; TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */ cpuset_t pm_active; /* active on cpus */ cpuset_t pm_save; /* Context valid on cpus mask */ diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index d6cd476..d1b366b 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -45,7 +45,9 @@ extern u_long *ipi_rendezvous_counts[MAXCPU]; /* IPI handlers */ inthand_t + IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid enabled */ IDTVEC(invltlb), /* TLB shootdowns - global */ + IDTVEC(invlpg_pcid), /* TLB shootdowns - 1 page, pcid enabled */ IDTVEC(invlpg), /* TLB shootdowns - 1 page */ IDTVEC(invlrng), /* TLB shootdowns - page range */ IDTVEC(invlcache), /* Write back and invalidate cache */ -- cgit v1.1 From ceb5fa1b16f231bab58c8a447b3c122dd1c5bf6c Mon Sep 17 00:00:00 2001 From: gibbs Date: Wed, 4 Sep 2013 23:32:49 +0000 Subject: Correct blkback handling of the BLKIF_OP_FLUSH_DISKCACHE opcode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly round-trip the "operation code" for client requests. sys/dev/xen/blkback/blkback.c: In xbb_dispatch_dev() when processing a flush request, correctly set bio->bio_caller1 to the request list (not bare request) for the operation, as is expected by the completion handler xbb_bio_done(). In xbb_get_resources(), initialize "operation" in the driver's internal request object from the client's "ring request", so it is correct when used to populate the reply when this operation completes. Submitted by: Roger Pau Monné Sponsored by: Citrix Systems R&D Reviewed by: gibbs --- sys/dev/xen/blkback/blkback.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'sys') diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index 3ea3c97..21fbb41 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -230,7 +230,7 @@ struct xbb_xen_reqlist { int num_children; /** - * Number of I/O requests dispatched to the backend. + * Number of I/O requests still pending on the backend. */ int pendcnt; @@ -327,13 +327,6 @@ struct xbb_xen_req { int nr_512b_sectors; /** - * The number of struct bio requests still outstanding for this - * request on the backend device. This field is only used for - * device (rather than file) backed I/O. - */ - int pendcnt; - - /** * BLKIF_OP code for this request. */ int operation; @@ -1240,6 +1233,7 @@ xbb_get_resources(struct xbb_softc *xbb, struct xbb_xen_reqlist **reqlist, nreq->reqlist = *reqlist; nreq->req_ring_idx = ring_idx; nreq->id = ring_req->id; + nreq->operation = ring_req->operation; if (xbb->abi != BLKIF_PROTOCOL_NATIVE) { bcopy(ring_req, &nreq->ring_req_storage, sizeof(*ring_req)); @@ -2062,7 +2056,6 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, { struct xbb_dev_data *dev_data; struct bio *bios[XBB_MAX_SEGMENTS_PER_REQLIST]; - struct xbb_xen_req *nreq; off_t bio_offset; struct bio *bio; struct xbb_sg *xbb_sg; @@ -2080,7 +2073,6 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, bio_idx = 0; if (operation == BIO_FLUSH) { - nreq = STAILQ_FIRST(&reqlist->contig_req_list); bio = g_new_bio(); if (__predict_false(bio == NULL)) { DPRINTF("Unable to allocate bio for BIO_FLUSH\n"); @@ -2094,10 +2086,10 @@ xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, bio->bio_offset = 0; bio->bio_data = 0; bio->bio_done = xbb_bio_done; - bio->bio_caller1 = nreq; + bio->bio_caller1 = reqlist; bio->bio_pblkno = 0; - nreq->pendcnt = 1; + reqlist->pendcnt = 1; SDT_PROBE1(xbb, kernel, xbb_dispatch_dev, flush, device_get_unit(xbb->dev)); -- cgit v1.1 From 029a6f5d92dc57925b5f155d94d6e01fdab7a45d Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 00:09:56 +0000 Subject: Change the cap_rights_t type from uint64_t to a structure that we can extend in the future in a backward compatible (API and ABI) way. The cap_rights_t represents capability rights. We used to use one bit to represent one right, but we are running out of spare bits. Currently the new structure provides place for 114 rights (so 50 more than the previous cap_rights_t), but it is possible to grow the structure to hold at least 285 rights, although we can make it even larger if 285 rights won't be enough. The structure definition looks like this: struct cap_rights { uint64_t cr_rights[CAP_RIGHTS_VERSION + 2]; }; The initial CAP_RIGHTS_VERSION is 0. The top two bits in the first element of the cr_rights[] array contain total number of elements in the array - 2. This means if those two bits are equal to 0, we have 2 array elements. The top two bits in all remaining array elements should be 0. The next five bits in all array elements contain array index. Only one bit is used and bit position in this five-bits range defines array index. This means there can be at most five array elements in the future. To define new right the CAPRIGHT() macro must be used. The macro takes two arguments - an array index and a bit to set, eg. #define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL) We still support aliases that combine few rights, but the rights have to belong to the same array element, eg: #define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL) #define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL) #define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP) There is new API to manage the new cap_rights_t structure: cap_rights_t *cap_rights_init(cap_rights_t *rights, ...); void cap_rights_set(cap_rights_t *rights, ...); void cap_rights_clear(cap_rights_t *rights, ...); bool cap_rights_is_set(const cap_rights_t *rights, ...); bool cap_rights_is_valid(const cap_rights_t *rights); void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src); void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src); bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little); Capability rights to the cap_rights_init(), cap_rights_set(), cap_rights_clear() and cap_rights_is_set() functions are provided by separating them with commas, eg: cap_rights_t rights; cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT); There is no need to terminate the list of rights, as those functions are actually macros that take care of the termination, eg: #define cap_rights_set(rights, ...) \ __cap_rights_set((rights), __VA_ARGS__, 0ULL) void __cap_rights_set(cap_rights_t *rights, ...); Thanks to using one bit as an array index we can assert in those functions that there are no two rights belonging to different array elements provided together. For example this is illegal and will be detected, because CAP_LOOKUP belongs to element 0 and CAP_PDKILL to element 1: cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL); Providing several rights that belongs to the same array's element this way is correct, but is not advised. It should only be used for aliases definition. This commit also breaks compatibility with some existing Capsicum system calls, but I see no other way to do that. This should be fine as Capsicum is still experimental and this change is not going to 9.x. Sponsored by: The FreeBSD Foundation --- sys/amd64/linux32/linux32_machdep.c | 5 +- sys/bsm/audit_kevents.h | 1 + sys/bsm/audit_record.h | 4 + sys/cddl/compat/opensolaris/sys/file.h | 4 +- .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 15 +- .../opensolaris/uts/common/fs/zfs/zfs_onexit.c | 3 +- sys/compat/freebsd32/freebsd32_capability.c | 20 -- sys/compat/freebsd32/freebsd32_ioctl.c | 4 +- sys/compat/freebsd32/freebsd32_misc.c | 5 +- sys/compat/freebsd32/syscalls.master | 16 +- sys/compat/linux/linux_file.c | 17 +- sys/compat/linux/linux_ioctl.c | 82 ++++-- sys/compat/linux/linux_socket.c | 4 +- sys/compat/svr4/svr4_fcntl.c | 16 +- sys/compat/svr4/svr4_filio.c | 3 +- sys/compat/svr4/svr4_ioctl.c | 4 +- sys/compat/svr4/svr4_misc.c | 10 +- sys/compat/svr4/svr4_stream.c | 12 +- sys/conf/files | 1 + sys/dev/aac/aac_linux.c | 4 +- sys/dev/amr/amr_linux.c | 4 +- sys/dev/filemon/filemon.c | 16 +- sys/dev/hwpmc/hwpmc_logging.c | 4 +- sys/dev/ipmi/ipmi_linux.c | 4 +- sys/dev/iscsi_initiator/iscsi.c | 7 +- sys/dev/mfi/mfi_linux.c | 4 +- sys/dev/tdfx/tdfx_linux.c | 4 +- sys/fs/fdescfs/fdesc_vnops.c | 4 +- sys/fs/fuse/fuse_vfsops.c | 3 +- sys/fs/nfsclient/nfs_clport.c | 9 +- sys/fs/nfsserver/nfs_nfsdport.c | 5 +- sys/i386/ibcs2/ibcs2_fcntl.c | 4 +- sys/i386/ibcs2/ibcs2_ioctl.c | 4 +- sys/i386/ibcs2/ibcs2_misc.c | 11 +- sys/i386/linux/linux_machdep.c | 5 +- sys/kern/capabilities.conf | 3 +- sys/kern/kern_descrip.c | 137 +++++----- sys/kern/kern_event.c | 12 +- sys/kern/kern_exec.c | 4 +- sys/kern/kern_ktrace.c | 8 +- sys/kern/kern_sig.c | 4 +- sys/kern/subr_capability.c | 285 +++++++++++++++++++++ sys/kern/sys_capability.c | 170 ++++++------ sys/kern/sys_generic.c | 32 ++- sys/kern/sys_procdesc.c | 12 +- sys/kern/syscalls.master | 8 +- sys/kern/tty.c | 4 +- sys/kern/uipc_mqueue.c | 25 +- sys/kern/uipc_sem.c | 18 +- sys/kern/uipc_syscalls.c | 82 ++++-- sys/kern/uipc_usrreq.c | 8 +- sys/kern/vfs_acl.c | 18 +- sys/kern/vfs_aio.c | 11 +- sys/kern/vfs_extattr.c | 17 +- sys/kern/vfs_lookup.c | 33 ++- sys/kern/vfs_syscalls.c | 140 ++++++---- sys/netsmb/smb_dev.c | 3 +- sys/nfsserver/nfs_srvkrpc.c | 4 +- sys/security/audit/audit.h | 2 +- sys/security/audit/audit_arg.c | 4 +- sys/security/audit/audit_bsm.c | 3 +- sys/security/audit/audit_private.h | 1 + sys/security/audit/bsm_token.c | 16 ++ sys/security/mac/mac_syscalls.c | 6 +- sys/sys/_types.h | 1 - sys/sys/capability.h | 247 ++++++++++-------- sys/sys/caprights.h | 61 +++++ sys/sys/file.h | 21 +- sys/sys/filedesc.h | 9 +- sys/sys/ktrace.h | 7 +- sys/sys/namei.h | 29 +-- sys/sys/procdesc.h | 4 +- sys/sys/types.h | 9 +- sys/sys/user.h | 4 +- sys/ufs/ffs/ffs_alloc.c | 7 +- sys/vm/vm_mmap.c | 12 +- 76 files changed, 1228 insertions(+), 571 deletions(-) create mode 100644 sys/kern/subr_capability.c create mode 100644 sys/sys/caprights.h (limited to 'sys') diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 65f034a..3dd8f7a 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -519,6 +519,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, } */ bsd_args; int error; struct file *fp; + cap_rights_t rights; error = 0; bsd_args.flags = 0; @@ -567,7 +568,9 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, * protection options specified. */ - if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0) + error = fget(td, bsd_args.fd, + cap_rights_init(&rights, CAP_MMAP), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h index da2bc7c..303d37f 100644 --- a/sys/bsm/audit_kevents.h +++ b/sys/bsm/audit_kevents.h @@ -589,6 +589,7 @@ #define AUE_POSIX_OPENPT 43185 /* FreeBSD. */ #define AUE_CAP_NEW 43186 /* TrustedBSD. */ #define AUE_CAP_RIGHTS_GET 43187 /* TrustedBSD. */ +#define AUE_CAP_GETRIGHTS AUE_CAP_RIGHTS_GET #define AUE_CAP_ENTER 43188 /* TrustedBSD. */ #define AUE_CAP_GETMODE 43189 /* TrustedBSD. */ #define AUE_POSIX_SPAWN 43190 /* Darwin. */ diff --git a/sys/bsm/audit_record.h b/sys/bsm/audit_record.h index 706c6f3..7e6074f 100644 --- a/sys/bsm/audit_record.h +++ b/sys/bsm/audit_record.h @@ -34,6 +34,7 @@ #define _BSM_AUDIT_RECORD_H_ #include /* struct timeval */ +#include /* cap_rights_t */ /* * Token type identifiers. @@ -126,6 +127,8 @@ #define AUT_SOCKINET128 0x81 /* XXX */ #define AUT_SOCKUNIX 0x82 /* XXX */ +#define AUT_RIGHTS 0x83 + /* print values for the arbitrary token */ #define AUP_BINARY 0 #define AUP_OCTAL 1 @@ -248,6 +251,7 @@ token_t *au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, au_tid_addr_t *tid); token_t *au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); +token_t *au_to_rights(cap_rights_t *rightsp); token_t *au_to_return(char status, uint32_t ret); token_t *au_to_return32(char status, uint32_t ret); token_t *au_to_return64(char status, uint64_t ret); diff --git a/sys/cddl/compat/opensolaris/sys/file.h b/sys/cddl/compat/opensolaris/sys/file.h index 0b8f875..a1c1d45 100644 --- a/sys/cddl/compat/opensolaris/sys/file.h +++ b/sys/cddl/compat/opensolaris/sys/file.h @@ -39,11 +39,11 @@ typedef struct file file_t; #include static __inline file_t * -getf(int fd, cap_rights_t rights) +getf(int fd, cap_rights_t *rightsp) { struct file *fp; - if (fget(curthread, fd, rights, &fp) == 0) + if (fget(curthread, fd, rightsp, &fp) == 0) return (fp); return (NULL); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 10456f8..e9fba26 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -4005,6 +4005,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) char *origin = NULL; char *tosnap; char tofs[ZFS_MAXNAMELEN]; + cap_rights_t rights; boolean_t first_recvd_props = B_FALSE; if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || @@ -4022,7 +4023,7 @@ zfs_ioc_recv(zfs_cmd_t *zc) return (error); fd = zc->zc_cookie; - fp = getf(fd, CAP_PREAD); + fp = getf(fd, cap_rights_init(&rights, CAP_PREAD)); if (fp == NULL) { nvlist_free(props); return (SET_ERROR(EBADF)); @@ -4260,7 +4261,11 @@ zfs_ioc_send(zfs_cmd_t *zc) dsl_dataset_rele(tosnap, FTAG); dsl_pool_rele(dp, FTAG); } else { - file_t *fp = getf(zc->zc_cookie, CAP_WRITE); + file_t *fp; + cap_rights_t rights; + + fp = getf(zc->zc_cookie, + cap_rights_init(&rights, CAP_WRITE)); if (fp == NULL) return (SET_ERROR(EBADF)); @@ -4851,10 +4856,11 @@ static int zfs_ioc_diff(zfs_cmd_t *zc) { file_t *fp; + cap_rights_t rights; offset_t off; int error; - fp = getf(zc->zc_cookie, CAP_WRITE); + fp = getf(zc->zc_cookie, cap_rights_init(&rights, CAP_WRITE)); if (fp == NULL) return (SET_ERROR(EBADF)); @@ -5214,6 +5220,7 @@ zfs_ioc_unjail(zfs_cmd_t *zc) static int zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) { + cap_rights_t rights; int error; offset_t off; char *fromname = NULL; @@ -5225,7 +5232,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); - file_t *fp = getf(fd, CAP_READ); + file_t *fp = getf(fd, cap_rights_init(&rights, CAP_READ)); if (fp == NULL) return (SET_ERROR(EBADF)); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c index 05252cb..6a90b9c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c @@ -122,10 +122,11 @@ zfs_onexit_fd_hold(int fd, minor_t *minorp) { file_t *fp, *tmpfp; zfs_onexit_t *zo; + cap_rights_t rights; void *data; int error; - fp = getf(fd, CAP_NONE); + fp = getf(fd, cap_rights_init(&rights)); if (fp == NULL) return (SET_ERROR(EBADF)); diff --git a/sys/compat/freebsd32/freebsd32_capability.c b/sys/compat/freebsd32/freebsd32_capability.c index e17c394..b23cf95 100644 --- a/sys/compat/freebsd32/freebsd32_capability.c +++ b/sys/compat/freebsd32/freebsd32_capability.c @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include -#include #include #ifdef CAPABILITIES @@ -50,17 +49,6 @@ __FBSDID("$FreeBSD$"); MALLOC_DECLARE(M_FILECAPS); int -freebsd32_cap_rights_limit(struct thread *td, - struct freebsd32_cap_rights_limit_args *uap) -{ - struct cap_rights_limit_args ap; - - ap.fd = uap->fd; - ap.rights = PAIR32TO64(uint64_t, uap->rights); - return (sys_cap_rights_limit(td, &ap)); -} - -int freebsd32_cap_ioctls_limit(struct thread *td, struct freebsd32_cap_ioctls_limit_args *uap) { @@ -148,14 +136,6 @@ out: #else /* !CAPABILITIES */ int -freebsd32_cap_rights_limit(struct thread *td, - struct freebsd32_cap_rights_limit_args *uap) -{ - - return (ENOSYS); -} - -int freebsd32_cap_ioctls_limit(struct thread *td, struct freebsd32_cap_ioctls_limit_args *uap) { diff --git a/sys/compat/freebsd32/freebsd32_ioctl.c b/sys/compat/freebsd32/freebsd32_ioctl.c index 81f5c8e..1f90e58 100644 --- a/sys/compat/freebsd32/freebsd32_ioctl.c +++ b/sys/compat/freebsd32/freebsd32_ioctl.c @@ -353,9 +353,11 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) caddr_t data; }*/ ; struct file *fp; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD | FWRITE)) == 0) { fdrop(fp, td); diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 16d1205..a3cf5cf 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1650,6 +1650,7 @@ freebsd32_do_sendfile(struct thread *td, struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; struct file *fp; + cap_rights_t rights; off_t offset; int error; @@ -1686,8 +1687,10 @@ freebsd32_do_sendfile(struct thread *td, AUDIT_ARG_FD(uap->fd); - if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { goto out; + } error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index a2e3e78..f537a54 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -970,9 +970,9 @@ 512 AUE_SHMCTL NOSTD { int freebsd32_shmctl(int shmid, int cmd, \ struct shmid_ds32 *buf); } 513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); } -514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, uint64_t rights); } -515 AUE_CAP_RIGHTS_GET NOPROTO { int cap_rights_get(int fd, \ - uint64_t *rightsp); } +514 AUE_NULL OBSOL cap_new +515 AUE_CAP_RIGHTS_GET NOPROTO { int __cap_rights_get(int version, \ + int fd, cap_rights_t *rightsp); } 516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); } 517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); } 518 AUE_PDFORK NOPROTO { int pdfork(int *fdp, int flags); } @@ -1016,10 +1016,6 @@ int *status, int options, \ struct wrusage32 *wrusage, \ siginfo_t *info); } -533 AUE_CAP_RIGHTS_LIMIT STD { \ - int freebsd32_cap_rights_limit(int fd, \ - int pad, \ - uint32_t rights1, uint32_t rights2); } #else 530 AUE_NULL STD { int freebsd32_posix_fallocate(int fd,\ uint32_t offset1, uint32_t offset2,\ @@ -1033,10 +1029,10 @@ int *status, int options, \ struct wrusage32 *wrusage, \ siginfo_t *info); } -533 AUE_CAP_RIGHTS_LIMIT STD { \ - int freebsd32_cap_rights_limit(int fd, \ - uint32_t rights1, uint32_t rights2); } #endif +533 AUE_CAP_RIGHTS_LIMIT NOPROTO { \ + int cap_rights_limit(int fd, \ + cap_rights_t *rightsp); } 534 AUE_CAP_IOCTLS_LIMIT STD { \ int freebsd32_cap_ioctls_limit(int fd, \ const uint32_t *cmds, size_t ncmds); } diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 49c3fdf..a6b1d35 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -92,6 +92,7 @@ linux_creat(struct thread *td, struct linux_creat_args *args) static int linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode) { + cap_rights_t rights; struct proc *p = td->td_proc; struct file *fp; int fd; @@ -143,7 +144,7 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod * having the same filedesc could use that fd without * checking below. */ - error = fget(td, fd, CAP_IOCTL, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp); if (!error) { sx_slock(&proctree_lock); PROC_LOCK(p); @@ -328,6 +329,7 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, caddr_t outp; /* Linux-format */ int resid, linuxreclen=0; /* Linux-format */ caddr_t lbuf; /* Linux-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -348,7 +350,9 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args, } else justone = 0; - if ((error = getvnode(td->td_proc->p_fd, args->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, args->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { @@ -1024,6 +1028,7 @@ linux_pread(td, uap) struct linux_pread_args *uap; { struct pread_args bsd; + cap_rights_t rights; struct vnode *vp; int error; @@ -1036,7 +1041,9 @@ linux_pread(td, uap) if (error == 0) { /* This seems to violate POSIX but linux does it */ - if ((error = fgetvp(td, uap->fd, CAP_PREAD, &vp)) != 0) + error = fgetvp(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &vp); + if (error != 0) return (error); if (vp->v_type == VDIR) { vrele(vp); @@ -1283,6 +1290,7 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) { struct l_flock linux_flock; struct flock bsd_flock; + cap_rights_t rights; struct file *fp; long arg; int error, result; @@ -1385,7 +1393,8 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args) * significant effect for pipes (SIGIO is not delivered for * pipes under Linux-2.2.35 at least). */ - error = fget(td, args->fd, CAP_FCNTL, &fp); + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_FCNTL), &fp); if (error) return (error); if (fp->f_type == DTYPE_PIPE) { diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 4df28aa..2a4016a 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -189,12 +189,14 @@ struct linux_hd_big_geometry { static int linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_int sectorsize, fwcylinders, fwheads, fwsectors; off_t mediasize, bytespercyl; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { case LINUX_HDIO_GET_GEO: @@ -270,12 +272,14 @@ linux_ioctl_hdio(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_int sectorsize; off_t mediasize; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { case LINUX_BLKGETSIZE: @@ -698,10 +702,12 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args) struct termios bios; struct linux_termios lios; struct linux_termio lio; + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -1438,10 +1444,12 @@ bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp, l_dvd_authinfo *lp) static int linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -1963,10 +1971,12 @@ linux_ioctl_sound(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); switch (args->cmd & 0xffff) { @@ -2351,6 +2361,7 @@ static int linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) { char lifname[LINUX_IFNAMSIZ], ifname[IFNAMSIZ]; + cap_rights_t rights; struct ifnet *ifp; struct file *fp; int error, type; @@ -2358,7 +2369,8 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) ifp = NULL; error = 0; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); type = fp->f_type; fdrop(fp, td); @@ -2581,10 +2593,12 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_private(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error, type; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); type = fp->f_type; fdrop(fp, td); @@ -2606,11 +2620,13 @@ linux_ioctl_drm(struct thread *td, struct linux_ioctl_args *args) static int linux_ioctl_sg(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { printf("sg_linux_ioctl: fget returned %d\n", error); return (error); } @@ -2828,6 +2844,7 @@ linux_v4l_cliplist_copy(struct l_video_window *lvw, struct video_window *vw) static int linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; struct video_tuner vtun; @@ -2845,7 +2862,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCSCHAN: args->cmd = VIDIOCSCHAN; break; case LINUX_VIDIOCGTUNER: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun)); if (error) { @@ -2863,7 +2882,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSTUNER: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vtun, sizeof(l_vtun)); if (error) { @@ -2880,7 +2901,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCCAPTURE: args->cmd = VIDIOCCAPTURE; break; case LINUX_VIDIOCGWIN: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOCGWIN, &vwin, td->td_ucred, td); if (!error) { @@ -2892,7 +2915,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSWIN: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vwin, sizeof(l_vwin)); if (error) { @@ -2915,7 +2940,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCGFBUF: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOCGFBUF, &vbuf, td->td_ucred, td); if (!error) { @@ -2927,7 +2954,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) return (error); case LINUX_VIDIOCSFBUF: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vbuf, sizeof(l_vbuf)); if (error) { @@ -2955,7 +2984,9 @@ linux_ioctl_v4l(struct thread *td, struct linux_ioctl_args *args) case LINUX_VIDIOCGPLAYINFO: args->cmd = VIDIOCGPLAYINFO; break; case LINUX_VIDIOCSMICROCODE: - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = copyin((void *) args->arg, &l_vcode, sizeof(l_vcode)); if (error) { @@ -3108,6 +3139,7 @@ bsd_to_linux_v4l2_format(struct v4l2_format *vf, struct l_v4l2_format *lvf) static int linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; struct v4l2_format vformat; @@ -3199,7 +3231,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) error = copyin((void *)args->arg, &l_vformat, sizeof(l_vformat)); if (error) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); if (linux_to_bsd_v4l2_format(&l_vformat, &vformat) != 0) error = EINVAL; @@ -3222,7 +3256,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) if (error) return (error); linux_to_bsd_v4l2_standard(&l_vstd, &vstd); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); error = fo_ioctl(fp, VIDIOC_ENUMSTD, (caddr_t)&vstd, td->td_ucred, td); @@ -3244,7 +3280,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) sizeof(struct l_v4l2_input)); if (error != 0) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, VIDIOC_ENUMINPUT, (caddr_t)&vinp, td->td_ucred, td); @@ -3263,7 +3301,9 @@ linux_ioctl_v4l2(struct thread *td, struct linux_ioctl_args *args) error = copyin((void *)args->arg, &l_vbuf, sizeof(l_vbuf)); if (error) return (error); - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, + cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error) return (error); linux_to_bsd_v4l2_buffer(&l_vbuf, &vbuf); if ((args->cmd & 0xffff) == LINUX_VIDIOC_QUERYBUF) @@ -3432,6 +3472,7 @@ linux_ioctl_fbsd_usb(struct thread *td, struct linux_ioctl_args *args) int linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; struct handler_element *he; int error, cmd; @@ -3442,7 +3483,8 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args) (unsigned long)args->cmd); #endif - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD|FWRITE)) == 0) { fdrop(fp, td); diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 36b23ac..22f811c 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -748,6 +748,7 @@ int linux_connect(struct thread *, struct linux_connect_args *); int linux_connect(struct thread *td, struct linux_connect_args *args) { + cap_rights_t rights; struct socket *so; struct sockaddr *sa; u_int fflag; @@ -772,7 +773,8 @@ linux_connect(struct thread *td, struct linux_connect_args *args) * socket and use the file descriptor reference instead of * creating a new one. */ - error = fgetsock(td, args->s, CAP_CONNECT, &so, &fflag); + error = fgetsock(td, args->s, cap_rights_init(&rights, CAP_CONNECT), + &so, &fflag); if (error == 0) { error = EISCONN; if (fflag & FNONBLOCK) { diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index 86fab78..8d0b715 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -259,6 +259,7 @@ fd_revoke(td, fd) struct vnode *vp; struct mount *mp; struct vattr vattr; + cap_rights_t rights; int error, *retval; retval = td->td_retval; @@ -267,12 +268,13 @@ fd_revoke(td, fd) * or FreeBSD grows a native frevoke() (more likely), we will need a * CAP_FREVOKE here. * - * In the meantime, use CAP_ALL: if a SVR4 process wants to + * In the meantime, use CAP_ALL(): if a SVR4 process wants to * do an frevoke(), it needs to do it on either a regular file * descriptor or a fully-privileged capability (which is effectively * the same as a non-capability-restricted file descriptor). */ - if ((error = fgetvp(td, fd, CAP_ALL, &vp)) != 0) + CAP_ALL(&rights); + if ((error = fgetvp(td, fd, &rights, &vp)) != 0) return (error); if (vp->v_type != VCHR && vp->v_type != VBLK) { @@ -318,13 +320,15 @@ fd_truncate(td, fd, flp) struct vattr vattr; int error, *retval; struct ftruncate_args ft; + cap_rights_t rights; retval = td->td_retval; /* * We only support truncating the file. */ - if ((error = fget(td, fd, CAP_FTRUNCATE, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp); + if (error != 0) return (error); vp = fp->f_vnode; @@ -401,9 +405,11 @@ svr4_sys_open(td, uap) if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { #if defined(NOTYET) - struct file *fp; + cap_rights_t rights; + struct file *fp; - error = fget(td, retval, CAP_IOCTL, &fp); + error = fget(td, retval, + cap_rights_init(&rights, CAP_IOCTL), &fp); PROC_UNLOCK(p); /* * we may have lost a race the above open() and diff --git a/sys/compat/svr4/svr4_filio.c b/sys/compat/svr4/svr4_filio.c index 0fbba07..b953e72 100644 --- a/sys/compat/svr4/svr4_filio.c +++ b/sys/compat/svr4/svr4_filio.c @@ -104,6 +104,7 @@ svr4_sys_read(td, uap) struct svr4_sys_read_args *uap; { struct read_args ra; + cap_rights_t rights; struct file *fp; struct socket *so = NULL; int so_state; @@ -114,7 +115,7 @@ svr4_sys_read(td, uap) ra.buf = uap->buf; ra.nbyte = uap->nbyte; - if (fget(td, uap->fd, CAP_READ, &fp) != 0) { + if (fget(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp) != 0) { DPRINTF(("Something fishy with the user-supplied file descriptor...\n")); return EBADF; } diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c index 36b0580..a8c8c8c 100644 --- a/sys/compat/svr4/svr4_ioctl.c +++ b/sys/compat/svr4/svr4_ioctl.c @@ -84,6 +84,7 @@ svr4_sys_ioctl(td, uap) struct svr4_sys_ioctl_args *uap; { int *retval; + cap_rights_t rights; struct file *fp; u_long cmd; int (*fun)(struct file *, struct thread *, register_t *, @@ -103,7 +104,8 @@ svr4_sys_ioctl(td, uap) retval = td->td_retval; cmd = uap->com; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); if ((fp->f_flag & (FREAD | FWRITE)) == 0) { diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 0cfaeae..4888698 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -236,6 +236,7 @@ svr4_sys_getdents64(td, uap) int len, reclen; /* BSD-format */ caddr_t outp; /* SVR4-format */ int resid, svr4reclen=0; /* SVR4-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -247,7 +248,9 @@ svr4_sys_getdents64(td, uap) DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", uap->fd, uap->nbytes)); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { @@ -412,6 +415,7 @@ svr4_sys_getdents(td, uap) int len, reclen; /* BSD-format */ caddr_t outp; /* SVR4-format */ int resid, svr4_reclen; /* SVR4-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -424,7 +428,9 @@ svr4_sys_getdents(td, uap) if (uap->nbytes < 0) return (EINVAL); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index 1c7e83e..6348b9b 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -1446,10 +1446,12 @@ svr4_sys_putmsg(td, uap) struct thread *td; struct svr4_sys_putmsg_args *uap; { - struct file *fp; + cap_rights_t rights; + struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_SEND, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_SEND), &fp); + if (error != 0) { #ifdef DEBUG_SVR4 uprintf("putmsg: bad fp\n"); #endif @@ -1618,10 +1620,12 @@ svr4_sys_getmsg(td, uap) struct thread *td; struct svr4_sys_getmsg_args *uap; { - struct file *fp; + cap_rights_t rights; + struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_RECV, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_RECV), &fp); + if (error != 0) { #ifdef DEBUG_SVR4 uprintf("getmsg: bad fp\n"); #endif diff --git a/sys/conf/files b/sys/conf/files index f02944f..8bb4eff 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2847,6 +2847,7 @@ kern/subr_blist.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard +kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_counter.c standard kern/subr_devstat.c standard diff --git a/sys/dev/aac/aac_linux.c b/sys/dev/aac/aac_linux.c index 049e2be..591dfbb 100644 --- a/sys/dev/aac/aac_linux.c +++ b/sys/dev/aac/aac_linux.c @@ -75,11 +75,13 @@ MODULE_DEPEND(aac_linux, linux, 1, 1, 1); static int aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); cmd = args->cmd; diff --git a/sys/dev/amr/amr_linux.c b/sys/dev/amr/amr_linux.c index 44e858b..5b1a17f 100644 --- a/sys/dev/amr/amr_linux.c +++ b/sys/dev/amr/amr_linux.c @@ -72,10 +72,12 @@ MODULE_DEPEND(amr, linux, 1, 1, 1); static int amr_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p); fdrop(fp, p); diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c index ce84e3d..e3fda18 100644 --- a/sys/dev/filemon/filemon.c +++ b/sys/dev/filemon/filemon.c @@ -138,12 +138,6 @@ filemon_dtr(void *data) } } -#if __FreeBSD_version < 900041 -#define FGET_WRITE(a1, a2, a3) fget_write((a1), (a2), (a3)) -#else -#define FGET_WRITE(a1, a2, a3) fget_write((a1), (a2), CAP_WRITE | CAP_SEEK, (a3)) -#endif - static int filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused, struct thread *td) @@ -151,13 +145,21 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused, int error = 0; struct filemon *filemon; struct proc *p; +#if __FreeBSD_version >= 900041 + cap_rights_t rights; +#endif devfs_get_cdevpriv((void **) &filemon); switch (cmd) { /* Set the output file descriptor. */ case FILEMON_SET_FD: - if ((error = FGET_WRITE(td, *(int *)data, &filemon->fp)) == 0) + error = fget_write(td, *(int *)data, +#if __FreeBSD_version >= 900041 + cap_rights_init(&rights, CAP_PWRITE), +#endif + &filemon->fp); + if (error == 0) /* Write the file header. */ filemon_comment(filemon); break; diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index 880bcaa..a60e096 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -570,6 +570,7 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) { int error; struct proc *p; + cap_rights_t rights; /* * As long as it is possible to get a LOR between pmc_sx lock and @@ -593,7 +594,8 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) po->po_file)); /* get a reference to the file state */ - error = fget_write(curthread, logfd, CAP_WRITE, &po->po_file); + error = fget_write(curthread, logfd, + cap_rights_init(&rights, CAP_WRITE), &po->po_file); if (error) goto error; diff --git a/sys/dev/ipmi/ipmi_linux.c b/sys/dev/ipmi/ipmi_linux.c index 430bd08..b6b38f2 100644 --- a/sys/dev/ipmi/ipmi_linux.c +++ b/sys/dev/ipmi/ipmi_linux.c @@ -89,11 +89,13 @@ MODULE_DEPEND(ipmi_linux, linux, 1, 1, 1); static int ipmi_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; u_long cmd; int error; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); cmd = args->cmd; diff --git a/sys/dev/iscsi_initiator/iscsi.c b/sys/dev/iscsi_initiator/iscsi.c index 4dbf163..4a1cb96 100644 --- a/sys/dev/iscsi_initiator/iscsi.c +++ b/sys/dev/iscsi_initiator/iscsi.c @@ -382,16 +382,19 @@ i_ping(struct cdev *dev) static int i_setsoc(isc_session_t *sp, int fd, struct thread *td) { + cap_rights_t rights; int error = 0; if(sp->soc != NULL) isc_stop_receiver(sp); - error = fget(td, fd, CAP_SOCK_CLIENT, &sp->fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), &sp->fp); if(error) return error; - if((error = fgetsock(td, fd, CAP_SOCK_CLIENT, &sp->soc, 0)) == 0) { + error = fgetsock(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), + &sp->soc, 0); + if(error == 0) { sp->td = td; isc_start_receiver(sp); } diff --git a/sys/dev/mfi/mfi_linux.c b/sys/dev/mfi/mfi_linux.c index 3328a66..429d496 100644 --- a/sys/dev/mfi/mfi_linux.c +++ b/sys/dev/mfi/mfi_linux.c @@ -84,6 +84,7 @@ MODULE_DEPEND(mfi, linux, 1, 1, 1); static int mfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { + cap_rights_t rights; struct file *fp; int error; u_long cmd = args->cmd; @@ -97,7 +98,8 @@ mfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) break; } - if ((error = fget(p, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p); fdrop(fp, p); diff --git a/sys/dev/tdfx/tdfx_linux.c b/sys/dev/tdfx/tdfx_linux.c index 0b769f0..fa39ab1 100644 --- a/sys/dev/tdfx/tdfx_linux.c +++ b/sys/dev/tdfx/tdfx_linux.c @@ -45,6 +45,7 @@ LINUX_IOCTL_SET(tdfx, LINUX_IOCTL_TDFX_MIN, LINUX_IOCTL_TDFX_MAX); static int linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args) { + cap_rights_t rights; int error = 0; u_long cmd = args->cmd & 0xffff; @@ -54,7 +55,8 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args) struct file *fp; - if ((error = fget(td, args->fd, CAP_IOCTL, &fp)) != 0) + error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) return (error); /* We simply copy the data and send it right to ioctl */ copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio)); diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index f18c0fc..fe939b1 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -445,6 +445,7 @@ fdesc_setattr(ap) struct mount *mp; struct file *fp; struct thread *td = curthread; + cap_rights_t rights; unsigned fd; int error; @@ -459,7 +460,8 @@ fdesc_setattr(ap) /* * Allow setattr where there is an underlying vnode. */ - error = getvnode(td->td_proc->p_fd, fd, CAP_EXTATTR_SET, &fp); + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); if (error) { /* * getvnode() returns EINVAL if the file descriptor is not diff --git a/sys/fs/fuse/fuse_vfsops.c b/sys/fs/fuse/fuse_vfsops.c index 639550a..0b4f19b 100644 --- a/sys/fs/fuse/fuse_vfsops.c +++ b/sys/fs/fuse/fuse_vfsops.c @@ -220,6 +220,7 @@ fuse_vfsop_mount(struct mount *mp) struct file *fp, *fptmp; char *fspec, *subtype; struct vfsoptlist *opts; + cap_rights_t rights; subtype = NULL; max_read_set = 0; @@ -289,7 +290,7 @@ fuse_vfsop_mount(struct mount *mp) FS_DEBUG2G("mntopts 0x%jx\n", (uintmax_t)mntopts); - err = fget(td, fd, CAP_READ, &fp); + err = fget(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (err != 0) { FS_DEBUG("invalid or not opened device: data=%p\n", data); goto out; diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index d7b082b..b198d59 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -1219,10 +1219,11 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfscbd_args nfscbdarg; struct nfsd_nfscbd_args nfscbdarg2; - int error; struct nameidata nd; struct nfscl_dumpmntopts dumpmntopts; + cap_rights_t rights; char *buf; + int error; if (uap->flag & NFSSVC_CBADDSOCK) { error = copyin(uap->argp, (caddr_t)&nfscbdarg, sizeof(nfscbdarg)); @@ -1233,10 +1234,10 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap) * pretend that we need them all. It is better to be too * careful than too reckless. */ - if ((error = fget(td, nfscbdarg.sock, CAP_SOCK_CLIENT, &fp)) - != 0) { + error = fget(td, nfscbdarg.sock, + cap_rights_init(&rights, CAP_SOCK_CLIENT), &fp); + if (error) return (error); - } if (fp->f_type != DTYPE_SOCKET) { fdrop(fp, td); return (EPERM); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index a6a0169..2f9d40a 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3035,6 +3035,7 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfsd_addsock_args sockarg; struct nfsd_nfsd_args nfsdarg; + cap_rights_t rights; int error; if (uap->flag & NFSSVC_NFSDADDSOCK) { @@ -3046,7 +3047,9 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) * pretend that we need them all. It is better to be too * careful than too reckless. */ - if ((error = fget(td, sockarg.sock, CAP_SOCK_SERVER, &fp)) != 0) + error = fget(td, sockarg.sock, + cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); + if (error != 0) goto out; if (fp->f_type != DTYPE_SOCKET) { fdrop(fp, td); diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c index 2902da7..d061b79 100644 --- a/sys/i386/ibcs2/ibcs2_fcntl.c +++ b/sys/i386/ibcs2/ibcs2_fcntl.c @@ -201,10 +201,12 @@ ibcs2_open(td, uap) free(path, M_TEMP); PROC_LOCK(p); if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { + cap_rights_t rights; struct file *fp; int error; - error = fget(td, td->td_retval[0], CAP_IOCTL, &fp); + error = fget(td, td->td_retval[0], + cap_rights_init(&rights, CAP_IOCTL), &fp); PROC_UNLOCK(p); if (error) return (EBADF); diff --git a/sys/i386/ibcs2/ibcs2_ioctl.c b/sys/i386/ibcs2/ibcs2_ioctl.c index 83e68cd..03fa5f6 100644 --- a/sys/i386/ibcs2/ibcs2_ioctl.c +++ b/sys/i386/ibcs2/ibcs2_ioctl.c @@ -331,10 +331,12 @@ ibcs2_ioctl(td, uap) struct ibcs2_ioctl_args *uap; { struct proc *p = td->td_proc; + cap_rights_t rights; struct file *fp; int error; - if ((error = fget(td, uap->fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid, uap->fd)); return EBADF; diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 9f382aa..28cd83c 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -326,6 +326,7 @@ ibcs2_getdents(td, uap) register int len, reclen; /* BSD-format */ register caddr_t outp; /* iBCS2-format */ register int resid; /* iBCS2-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -337,7 +338,9 @@ ibcs2_getdents(td, uap) #define BSD_DIRENT(cp) ((struct dirent *)(cp)) #define IBCS2_RECLEN(reclen) (reclen + sizeof(u_short)) - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -478,6 +481,7 @@ ibcs2_read(td, uap) register int len, reclen; /* BSD-format */ register caddr_t outp; /* iBCS2-format */ register int resid; /* iBCS2-format */ + cap_rights_t rights; struct file *fp; struct uio auio; struct iovec aiov; @@ -490,8 +494,9 @@ ibcs2_read(td, uap) u_long *cookies = NULL, *cookiep; int ncookies; - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, - &fp)) != 0) { + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) { if (error == EINVAL) return sys_read(td, (struct read_args *)uap); else diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index 14d1892..2d79204 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -422,6 +422,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, } */ bsd_args; int error; struct file *fp; + cap_rights_t rights; error = 0; bsd_args.flags = 0; @@ -473,7 +474,9 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot, * is done in the FreeBSD mmap(). */ - if ((error = fget(td, bsd_args.fd, CAP_MMAP, &fp)) != 0) + error = fget(td, bsd_args.fd, + cap_rights_init(&rights, CAP_MMAP), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf index d2fa51c..eaa5b14 100644 --- a/sys/kern/capabilities.conf +++ b/sys/kern/capabilities.conf @@ -114,8 +114,7 @@ cap_fcntls_limit cap_getmode cap_ioctls_get cap_ioctls_limit -cap_new -cap_rights_get +__cap_rights_get cap_rights_limit ## diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index d0de6b9..a0545e1 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -455,6 +455,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) struct filedescent *fde; struct proc *p; struct vnode *vp; + cap_rights_t rights; int error, flg, tmp; u_int old, new; uint64_t bsize; @@ -515,7 +516,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETFL: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_GETFL, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_GETFL, &fp, NULL); if (error != 0) break; td->td_retval[0] = OFLAGS(fp->f_flag); @@ -523,7 +525,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_SETFL: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_SETFL, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_SETFL, &fp, NULL); if (error != 0) break; do { @@ -550,7 +553,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETOWN: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_GETOWN, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_GETOWN, &fp, NULL); if (error != 0) break; error = fo_ioctl(fp, FIOGETOWN, &tmp, td->td_ucred, td); @@ -560,7 +564,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_SETOWN: - error = fget_unlocked(fdp, fd, CAP_FCNTL, F_SETOWN, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FCNTL), F_SETOWN, &fp, NULL); if (error != 0) break; tmp = arg; @@ -581,7 +586,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) case F_SETLK: do_setlk: - error = fget_unlocked(fdp, fd, CAP_FLOCK, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -688,7 +694,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) break; case F_GETLK: - error = fget_unlocked(fdp, fd, CAP_FLOCK, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, + cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -1281,11 +1288,13 @@ int kern_fstat(struct thread *td, int fd, struct stat *sbp) { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); - if ((error = fget(td, fd, CAP_FSTAT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_FSTAT), &fp); + if (error != 0) return (error); AUDIT_ARG_FILE(td->td_proc, fp); @@ -1339,9 +1348,11 @@ sys_fpathconf(struct thread *td, struct fpathconf_args *uap) { struct file *fp; struct vnode *vp; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_FPATHCONF, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FPATHCONF), &fp); + if (error != 0) return (error); /* If asynchronous I/O is available, it works for all descriptors. */ @@ -1417,7 +1428,7 @@ static void filecaps_fill(struct filecaps *fcaps) { - fcaps->fc_rights = CAP_ALL; + CAP_ALL(&fcaps->fc_rights); fcaps->fc_ioctls = NULL; fcaps->fc_nioctls = -1; fcaps->fc_fcntls = CAP_FCNTL_ALL; @@ -1441,16 +1452,18 @@ static void filecaps_validate(const struct filecaps *fcaps, const char *func) { - KASSERT((fcaps->fc_rights & ~CAP_MASK_VALID) == 0, + KASSERT(cap_rights_is_valid(&fcaps->fc_rights), ("%s: invalid rights", func)); KASSERT((fcaps->fc_fcntls & ~CAP_FCNTL_ALL) == 0, ("%s: invalid fcntls", func)); - KASSERT(fcaps->fc_fcntls == 0 || (fcaps->fc_rights & CAP_FCNTL) != 0, + KASSERT(fcaps->fc_fcntls == 0 || + cap_rights_is_set(&fcaps->fc_rights, CAP_FCNTL), ("%s: fcntls without CAP_FCNTL", func)); KASSERT(fcaps->fc_ioctls != NULL ? fcaps->fc_nioctls > 0 : (fcaps->fc_nioctls == -1 || fcaps->fc_nioctls == 0), ("%s: invalid ioctls", func)); - KASSERT(fcaps->fc_nioctls == 0 || (fcaps->fc_rights & CAP_IOCTL) != 0, + KASSERT(fcaps->fc_nioctls == 0 || + cap_rights_is_set(&fcaps->fc_rights, CAP_IOCTL), ("%s: ioctls without CAP_IOCTL", func)); } @@ -2285,7 +2298,7 @@ finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) } int -fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, +fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, int needfcntl, struct file **fpp, cap_rights_t *haverightsp) { struct file *fp; @@ -2310,11 +2323,11 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, if (fp == NULL) return (EBADF); #ifdef CAPABILITIES - haverights = cap_rights(fdp, fd); - error = cap_check(haverights, needrights); + haverights = *cap_rights(fdp, fd); + error = cap_check(&haverights, needrightsp); if (error != 0) return (error); - if ((needrights & CAP_FCNTL) != 0) { + if (cap_rights_is_set(needrightsp, CAP_FCNTL)) { error = cap_fcntl_check(fdp, fd, needfcntl); if (error != 0) return (error); @@ -2338,7 +2351,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, #ifdef CAPABILITIES *haverightsp = haverights; #else - *haverightsp = CAP_ALL; + CAP_ALL(haverightsp); #endif } return (0); @@ -2359,19 +2372,20 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, */ static __inline int _fget(struct thread *td, int fd, struct file **fpp, int flags, - cap_rights_t needrights, u_char *maxprotp) + cap_rights_t *needrightsp, u_char *maxprotp) { struct filedesc *fdp; struct file *fp; - cap_rights_t haverights; + cap_rights_t haverights, needrights; int error; *fpp = NULL; if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) return (EBADF); + needrights = *needrightsp; if (maxprotp != NULL) - needrights |= CAP_MMAP; - error = fget_unlocked(fdp, fd, needrights, 0, &fp, &haverights); + cap_rights_set(&needrights, CAP_MMAP); + error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights); if (error != 0) return (error); if (fp->f_ops == &badfileops) { @@ -2384,7 +2398,7 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, * If requested, convert capability rights to access flags. */ if (maxprotp != NULL) - *maxprotp = cap_rights_to_vmprot(haverights); + *maxprotp = cap_rights_to_vmprot(&haverights); #else /* !CAPABILITIES */ if (maxprotp != NULL) *maxprotp = VM_PROT_ALL; @@ -2421,32 +2435,32 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, } int -fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return(_fget(td, fd, fpp, 0, rights, NULL)); + return(_fget(td, fd, fpp, 0, rightsp, NULL)); } int -fget_mmap(struct thread *td, int fd, cap_rights_t rights, u_char *maxprotp, +fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp, struct file **fpp) { - return (_fget(td, fd, fpp, 0, rights, maxprotp)); + return (_fget(td, fd, fpp, 0, rightsp, maxprotp)); } int -fget_read(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return(_fget(td, fd, fpp, FREAD, rights, NULL)); + return(_fget(td, fd, fpp, FREAD, rightsp, NULL)); } int -fget_write(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) +fget_write(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp) { - return (_fget(td, fd, fpp, FWRITE, rights, NULL)); + return (_fget(td, fd, fpp, FWRITE, rightsp, NULL)); } /* @@ -2457,15 +2471,15 @@ fget_write(struct thread *td, int fd, cap_rights_t rights, struct file **fpp) * XXX: what about the unused flags ? */ static __inline int -_fgetvp(struct thread *td, int fd, int flags, cap_rights_t needrights, +_fgetvp(struct thread *td, int fd, int flags, cap_rights_t *needrightsp, struct vnode **vpp) { struct file *fp; int error; *vpp = NULL; - error = _fget(td, fd, &fp, flags, needrights, NULL); - if (error) + error = _fget(td, fd, &fp, flags, needrightsp, NULL); + if (error != 0) return (error); if (fp->f_vnode == NULL) { error = EINVAL; @@ -2479,14 +2493,14 @@ _fgetvp(struct thread *td, int fd, int flags, cap_rights_t needrights, } int -fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, 0, rights, vpp)); + return (_fgetvp(td, fd, 0, rightsp, vpp)); } int -fgetvp_rights(struct thread *td, int fd, cap_rights_t need, +fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, struct filecaps *havecaps, struct vnode **vpp) { struct filedesc *fdp; @@ -2503,7 +2517,7 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t need, return (EBADF); #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, fd), need); + error = cap_check(cap_rights(fdp, fd), needrightsp); if (error != 0) return (error); #endif @@ -2519,26 +2533,26 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t need, } int -fgetvp_read(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FREAD, rights, vpp)); + return (_fgetvp(td, fd, FREAD, rightsp, vpp)); } int -fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp) +fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FEXEC, rights, vpp)); + return (_fgetvp(td, fd, FEXEC, rightsp, vpp)); } #ifdef notyet int -fgetvp_write(struct thread *td, int fd, cap_rights_t rights, +fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp) { - return (_fgetvp(td, fd, FWRITE, rights, vpp)); + return (_fgetvp(td, fd, FWRITE, rightsp, vpp)); } #endif @@ -2554,7 +2568,7 @@ fgetvp_write(struct thread *td, int fd, cap_rights_t rights, * during use. */ int -fgetsock(struct thread *td, int fd, cap_rights_t rights, struct socket **spp, +fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, struct socket **spp, u_int *fflagp) { struct file *fp; @@ -2563,7 +2577,7 @@ fgetsock(struct thread *td, int fd, cap_rights_t rights, struct socket **spp, *spp = NULL; if (fflagp != NULL) *fflagp = 0; - if ((error = _fget(td, fd, &fp, 0, rights, NULL)) != 0) + if ((error = _fget(td, fd, &fp, 0, rightsp, NULL)) != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { error = ENOTSOCK; @@ -2637,9 +2651,11 @@ sys_flock(struct thread *td, struct flock_args *uap) struct file *fp; struct vnode *vp; struct flock lf; + cap_rights_t rights; int error; - if ((error = fget(td, uap->fd, CAP_FLOCK, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FLOCK), &fp); + if (error != 0) return (error); if (fp->f_type != DTYPE_VNODE) { fdrop(fp, td); @@ -3185,7 +3201,7 @@ struct export_fd_buf { static int export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt, - int64_t offset, cap_rights_t fd_cap_rights, struct export_fd_buf *efbuf) + int64_t offset, cap_rights_t *rightsp, struct export_fd_buf *efbuf) { struct { int fflag; @@ -3259,7 +3275,10 @@ export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt, for (i = 0; i < NFFLAGS; i++) if (fflags & fflags_table[i].fflag) kif->kf_flags |= fflags_table[i].kf_fflag; - kif->kf_cap_rights = fd_cap_rights; + if (rightsp != NULL) + kif->kf_cap_rights = *rightsp; + else + cap_rights_init(&kif->kf_cap_rights); kif->kf_fd = fd; kif->kf_type = type; kif->kf_ref_count = refcnt; @@ -3302,7 +3321,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) void *data; int error, i; int type, refcnt, fflags; - cap_rights_t fd_cap_rights; + cap_rights_t rights; PROC_LOCK_ASSERT(p, MA_OWNED); @@ -3329,13 +3348,13 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) efbuf->remainder = maxlen; if (tracevp != NULL) export_fd_to_sb(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE, - FREAD | FWRITE, -1, -1, 0, efbuf); + FREAD | FWRITE, -1, -1, NULL, efbuf); if (textvp != NULL) export_fd_to_sb(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); if (cttyvp != NULL) export_fd_to_sb(cttyvp, KF_TYPE_VNODE, KF_FD_TYPE_CTTY, - FREAD | FWRITE, -1, -1, 0, efbuf); + FREAD | FWRITE, -1, -1, NULL, efbuf); error = 0; if (fdp == NULL) goto fail; @@ -3346,30 +3365,30 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) vref(fdp->fd_cdir); data = fdp->fd_cdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_CWD, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } /* root directory */ if (fdp->fd_rdir != NULL) { vref(fdp->fd_rdir); data = fdp->fd_rdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_ROOT, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } /* jail directory */ if (fdp->fd_jdir != NULL) { vref(fdp->fd_jdir); data = fdp->fd_jdir; export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL, - FREAD, -1, -1, 0, efbuf); + FREAD, -1, -1, NULL, efbuf); } for (i = 0; i < fdp->fd_nfiles; i++) { if ((fp = fdp->fd_ofiles[i].fde_file) == NULL) continue; data = NULL; #ifdef CAPABILITIES - fd_cap_rights = cap_rights(fdp, i); + rights = *cap_rights(fdp, i); #else /* !CAPABILITIES */ - fd_cap_rights = 0; + cap_rights_init(&rights); #endif switch (fp->f_type) { case DTYPE_VNODE: @@ -3443,8 +3462,8 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen) * the loop continues. */ error = export_fd_to_sb(data, type, i, fflags, refcnt, - offset, fd_cap_rights, efbuf); - if (error) + offset, &rights, efbuf); + if (error != 0) break; } FILEDESC_SUNLOCK(fdp); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index dfd1c46..8bde25a 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -824,9 +824,11 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent *kevp, *changes; struct kqueue *kq; struct file *fp; + cap_rights_t rights; int i, n, nerrors, error; - if ((error = fget(td, fd, CAP_POST_EVENT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp); + if (error != 0) return (error); if ((error = kqueue_acquire(fp, &kq)) != 0) goto done_norel; @@ -964,6 +966,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa struct filterops *fops; struct file *fp; struct knote *kn, *tkn; + cap_rights_t rights; int error, filt, event; int haskqglobal; @@ -982,7 +985,8 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa findkn: if (fops->f_isfd) { KASSERT(td != NULL, ("td is NULL")); - error = fget(td, kev->ident, CAP_POLL_EVENT, &fp); + error = fget(td, kev->ident, + cap_rights_init(&rights, CAP_POLL_EVENT), &fp); if (error) goto done; @@ -2237,9 +2241,11 @@ kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok) { struct kqueue *kq; struct file *fp; + cap_rights_t rights; int error; - if ((error = fget(td, fd, CAP_POST_EVENT, &fp)) != 0) + error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp); + if (error != 0) return (error); if ((error = kqueue_acquire(fp, &kq)) != 0) goto noacquire; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 833fd18..45f732b 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -338,6 +338,7 @@ do_execve(td, args, mac_p) struct ucred *tracecred = NULL; #endif struct vnode *textvp = NULL, *binvp = NULL; + cap_rights_t rights; int credential_changing; int textset; #ifdef MAC @@ -438,7 +439,8 @@ interpret: /* * Descriptors opened only with O_EXEC or O_RDONLY are allowed. */ - error = fgetvp_exec(td, args->fd, CAP_FEXECVE, &binvp); + error = fgetvp_exec(td, args->fd, + cap_rights_init(&rights, CAP_FEXECVE), &binvp); if (error) goto exec_fail; vn_lock(binvp, LK_EXCLUSIVE | LK_RETRY); diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index e512a33..3b34fb0 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -779,8 +779,8 @@ ktrstruct(name, data, datalen) void ktrcapfail(type, needed, held) enum ktr_cap_fail_type type; - cap_rights_t needed; - cap_rights_t held; + const cap_rights_t *needed; + const cap_rights_t *held; { struct thread *td = curthread; struct ktr_request *req; @@ -791,8 +791,8 @@ ktrcapfail(type, needed, held) return; kcf = &req->ktr_data.ktr_cap_fail; kcf->cap_type = type; - kcf->cap_needed = needed; - kcf->cap_held = held; + kcf->cap_needed = *needed; + kcf->cap_held = *held; ktr_enqueuerequest(td, req); ktrace_exit(td); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 22fc1b7..1797ebc 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1726,6 +1726,7 @@ sys_pdkill(td, uap) { #ifdef PROCDESC struct proc *p; + cap_rights_t rights; int error; AUDIT_ARG_SIGNUM(uap->signum); @@ -1733,7 +1734,8 @@ sys_pdkill(td, uap) if ((u_int)uap->signum > _SIG_MAXSIG) return (EINVAL); - error = procdesc_find(td, uap->fd, CAP_PDKILL, &p); + error = procdesc_find(td, uap->fd, + cap_rights_init(&rights, CAP_PDKILL), &p); if (error) return (error); AUDIT_ARG_PROCESS(p); diff --git a/sys/kern/subr_capability.c b/sys/kern/subr_capability.c new file mode 100644 index 0000000..7043fe7 --- /dev/null +++ b/sys/kern/subr_capability.c @@ -0,0 +1,285 @@ +/*- + * Copyright (c) 2013 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#ifdef _KERNEL +#include +#include +#include + +#include +#else /* !_KERNEL */ +#include +#include + +#include +#include +#include +#include +#include +#endif + +#ifdef _KERNEL +#define assert(exp) KASSERT((exp), ("%s:%u", __func__, __LINE__)) +#endif + +static __inline unsigned int +right_to_index(uint64_t right) +{ + static const int bit2idx[] = { + -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, + 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + int idx; + + idx = CAPIDXBIT(right); + assert(idx == 1 || idx == 2 || idx == 4 || idx == 8 || idx == 16); + + idx = bit2idx[idx]; + assert(idx >= 0 && idx <= 4); + + return ((unsigned int)idx); +} + +static void +cap_rights_vset(cap_rights_t *rights, va_list ap) +{ + unsigned int i, n; + uint64_t right; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] |= right; + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static void +cap_rights_vclear(cap_rights_t *rights, va_list ap) +{ + unsigned int i, n; + uint64_t right; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static bool +cap_rights_is_vset(const cap_rights_t *rights, va_list ap) +{ + unsigned int i, n; + uint64_t right; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + if ((rights->cr_rights[i] & right) != right) + return (false); + } + + return (true); +} + +cap_rights_t * +__cap_rights_init(int version, cap_rights_t *rights, ...) +{ + unsigned int n; + va_list ap; + + assert(version == CAP_RIGHTS_VERSION_00); + + n = version + 2; + memset(rights->cr_rights, 0, sizeof(rights->cr_rights[0]) * n); + CAP_NONE(rights); + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); + + return (rights); +} + +void +__cap_rights_set(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); +} + +void +__cap_rights_clear(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vclear(rights, ap); + va_end(ap); +} + +bool +__cap_rights_is_set(const cap_rights_t *rights, ...) +{ + va_list ap; + bool ret; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + ret = cap_rights_is_vset(rights, ap); + va_end(ap); + + return (ret); +} + +bool +cap_rights_is_valid(const cap_rights_t *rights) +{ + cap_rights_t allrights; + unsigned int i, j; + + if (CAPVER(rights) != CAP_RIGHTS_VERSION_00) + return (false); + CAP_ALL(&allrights); + if (!cap_rights_contains(&allrights, rights)) + return (false); + for (i = 0; i < CAPARSIZE(rights); i++) { + j = right_to_index(rights->cr_rights[i]); + if (i != j) + return (false); + if (i > 0) { + if (CAPRVER(rights->cr_rights[i]) != 0) + return (false); + } + } + + return (true); +} + +void +cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + + for (i = 0; i < n; i++) + dst->cr_rights[i] |= src->cr_rights[i]; + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); +} + +void +cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + + for (i = 0; i < n; i++) { + dst->cr_rights[i] &= + ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL); + } + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); +} + +bool +cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little) +{ + unsigned int i, n; + + assert(CAPVER(big) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(little) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(big) == CAPVER(little)); + + n = CAPARSIZE(big); + + for (i = 0; i < n; i++) { + if ((big->cr_rights[i] & little->cr_rights[i]) != + little->cr_rights[i]) { + return (false); + } + } + + return (true); +} diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c index 224042e..456f7ac 100644 --- a/sys/kern/sys_capability.c +++ b/sys/kern/sys_capability.c @@ -148,16 +148,19 @@ FEATURE(security_capabilities, "Capsicum Capabilities"); MALLOC_DECLARE(M_FILECAPS); static inline int -_cap_check(cap_rights_t have, cap_rights_t need, enum ktr_cap_fail_type type) +_cap_check(const cap_rights_t *havep, const cap_rights_t *needp, + enum ktr_cap_fail_type type) { + int i; - - if ((need & ~have) != 0) { + for (i = 0; i < nitems(havep->cr_rights); i++) { + if (!cap_rights_contains(havep, needp)) { #ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(type, need, have); + if (KTRPOINT(curthread, KTR_CAPFAIL)) + ktrcapfail(type, needp, havep); #endif - return (ENOTCAPABLE); + return (ENOTCAPABLE); + } } return (0); } @@ -166,26 +169,26 @@ _cap_check(cap_rights_t have, cap_rights_t need, enum ktr_cap_fail_type type) * Test whether a capability grants the requested rights. */ int -cap_check(cap_rights_t have, cap_rights_t need) +cap_check(const cap_rights_t *havep, const cap_rights_t *needp) { - return (_cap_check(have, need, CAPFAIL_NOTCAPABLE)); + return (_cap_check(havep, needp, CAPFAIL_NOTCAPABLE)); } /* * Convert capability rights into VM access flags. */ u_char -cap_rights_to_vmprot(cap_rights_t have) +cap_rights_to_vmprot(cap_rights_t *havep) { u_char maxprot; maxprot = VM_PROT_NONE; - if (have & CAP_MMAP_R) + if (cap_rights_is_set(havep, CAP_MMAP_R)) maxprot |= VM_PROT_READ; - if (have & CAP_MMAP_W) + if (cap_rights_is_set(havep, CAP_MMAP_W)) maxprot |= VM_PROT_WRITE; - if (have & CAP_MMAP_X) + if (cap_rights_is_set(havep, CAP_MMAP_X)) maxprot |= VM_PROT_EXECUTE; return (maxprot); @@ -196,11 +199,11 @@ cap_rights_to_vmprot(cap_rights_t have) * any other way, as we want to keep all capability permission evaluation in * this one file. */ -cap_rights_t +cap_rights_t * cap_rights(struct filedesc *fdp, int fd) { - return (fdp->fd_ofiles[fd].fde_rights); + return (&fdp->fd_ofiles[fd].fde_rights); } /* @@ -211,32 +214,57 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) { struct filedesc *fdp; cap_rights_t rights; - int error, fd; + int error, fd, version; - fd = uap->fd; - rights = uap->rights; + cap_rights_init(&rights); - AUDIT_ARG_FD(fd); - AUDIT_ARG_RIGHTS(rights); + error = copyin(uap->rightsp, &rights, sizeof(rights.cr_rights[0])); + if (error != 0) + return (error); + version = CAPVER(&rights); + if (version != CAP_RIGHTS_VERSION_00) + return (EINVAL); - if ((rights & ~CAP_ALL) != 0) + error = copyin(uap->rightsp, &rights, + sizeof(rights.cr_rights[0]) * CAPARSIZE(&rights)); + if (error != 0) + return (error); + /* Check for race. */ + if (CAPVER(&rights) != version) return (EINVAL); + if (!cap_rights_is_valid(&rights)) + return (EINVAL); + + if (version != CAP_RIGHTS_VERSION) { + rights.cr_rights[0] &= ~(0x3ULL << 62); + rights.cr_rights[0] |= ((uint64_t)CAP_RIGHTS_VERSION << 62); + } +#ifdef KTRACE + if (KTRPOINT(td, KTR_STRUCT)) + ktrcaprights(&rights); +#endif + + fd = uap->fd; + + AUDIT_ARG_FD(fd); + AUDIT_ARG_RIGHTS(&rights); + fdp = td->td_proc->p_fd; FILEDESC_XLOCK(fdp); if (fget_locked(fdp, fd) == NULL) { FILEDESC_XUNLOCK(fdp); return (EBADF); } - error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE); + error = _cap_check(cap_rights(fdp, fd), &rights, CAPFAIL_INCREASE); if (error == 0) { fdp->fd_ofiles[fd].fde_rights = rights; - if ((rights & CAP_IOCTL) == 0) { + if (!cap_rights_is_set(&rights, CAP_IOCTL)) { free(fdp->fd_ofiles[fd].fde_ioctls, M_FILECAPS); fdp->fd_ofiles[fd].fde_ioctls = NULL; fdp->fd_ofiles[fd].fde_nioctls = 0; } - if ((rights & CAP_FCNTL) == 0) + if (!cap_rights_is_set(&rights, CAP_FCNTL)) fdp->fd_ofiles[fd].fde_fcntls = 0; } FILEDESC_XUNLOCK(fdp); @@ -247,11 +275,14 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) * System call to query the rights mask associated with a capability. */ int -sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) +sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap) { struct filedesc *fdp; cap_rights_t rights; - int fd; + int error, fd, i, n; + + if (uap->version != CAP_RIGHTS_VERSION_00) + return (EINVAL); fd = uap->fd; @@ -263,9 +294,26 @@ sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) FILEDESC_SUNLOCK(fdp); return (EBADF); } - rights = cap_rights(fdp, fd); + rights = *cap_rights(fdp, fd); FILEDESC_SUNLOCK(fdp); - return (copyout(&rights, uap->rightsp, sizeof(*uap->rightsp))); + n = uap->version + 2; + if (uap->version != CAPVER(&rights)) { + /* + * For older versions we need to check if the descriptor + * doesn't contain rights not understood by the caller. + * If it does, we have to return an error. + */ + for (i = n; i < CAPARSIZE(&rights); i++) { + if ((rights.cr_rights[i] & ~(0x7FULL << 57)) != 0) + return (EINVAL); + } + } + error = copyout(&rights, uap->rightsp, sizeof(rights.cr_rights[0]) * n); +#ifdef KTRACE + if (error == 0 && KTRPOINT(td, KTR_STRUCT)) + ktrcaprights(&rights); +#endif + return (error); } /* @@ -513,65 +561,6 @@ sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap) return (copyout(&rights, uap->fcntlrightsp, sizeof(rights))); } -/* - * For backward compatibility. - */ -int -sys_cap_new(struct thread *td, struct cap_new_args *uap) -{ - struct filedesc *fdp; - cap_rights_t rights; - register_t newfd; - int error, fd; - - fd = uap->fd; - rights = uap->rights; - - AUDIT_ARG_FD(fd); - AUDIT_ARG_RIGHTS(rights); - - if ((rights & ~CAP_ALL) != 0) - return (EINVAL); - - fdp = td->td_proc->p_fd; - FILEDESC_SLOCK(fdp); - if (fget_locked(fdp, fd) == NULL) { - FILEDESC_SUNLOCK(fdp); - return (EBADF); - } - error = _cap_check(cap_rights(fdp, fd), rights, CAPFAIL_INCREASE); - FILEDESC_SUNLOCK(fdp); - if (error != 0) - return (error); - - error = do_dup(td, 0, fd, 0, &newfd); - if (error != 0) - return (error); - - FILEDESC_XLOCK(fdp); - /* - * We don't really care about the race between checking capability - * rights for the source descriptor and now. If capability rights - * were ok at that earlier point, the process had this descriptor - * with those rights, so we don't increase them in security sense, - * the process might have done the cap_new(2) a bit earlier to get - * the same effect. - */ - fdp->fd_ofiles[newfd].fde_rights = rights; - if ((rights & CAP_IOCTL) == 0) { - free(fdp->fd_ofiles[newfd].fde_ioctls, M_FILECAPS); - fdp->fd_ofiles[newfd].fde_ioctls = NULL; - fdp->fd_ofiles[newfd].fde_nioctls = 0; - } - if ((rights & CAP_FCNTL) == 0) - fdp->fd_ofiles[newfd].fde_fcntls = 0; - FILEDESC_XUNLOCK(fdp); - - td->td_retval[0] = newfd; - - return (0); -} - #else /* !CAPABILITIES */ /* @@ -587,7 +576,7 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) } int -sys_cap_rights_get(struct thread *td, struct cap_rights_get_args *uap) +sys___cap_rights_get(struct thread *td, struct cap___rights_get_args *uap) { return (ENOSYS); @@ -621,11 +610,4 @@ sys_cap_fcntls_get(struct thread *td, struct cap_fcntls_get_args *uap) return (ENOSYS); } -int -sys_cap_new(struct thread *td, struct cap_new_args *uap) -{ - - return (ENOSYS); -} - #endif /* CAPABILITIES */ diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 44d1a89..5eaa695 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -243,9 +243,10 @@ int kern_readv(struct thread *td, int fd, struct uio *auio) { struct file *fp; + cap_rights_t rights; int error; - error = fget_read(td, fd, CAP_READ, &fp); + error = fget_read(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (error) return (error); error = dofileread(td, fd, fp, auio, (off_t)-1, 0); @@ -286,9 +287,10 @@ kern_preadv(td, fd, auio, offset) off_t offset; { struct file *fp; + cap_rights_t rights; int error; - error = fget_read(td, fd, CAP_PREAD, &fp); + error = fget_read(td, fd, cap_rights_init(&rights, CAP_PREAD), &fp); if (error) return (error); if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) @@ -452,9 +454,10 @@ int kern_writev(struct thread *td, int fd, struct uio *auio) { struct file *fp; + cap_rights_t rights; int error; - error = fget_write(td, fd, CAP_WRITE, &fp); + error = fget_write(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); if (error) return (error); error = dofilewrite(td, fd, fp, auio, (off_t)-1, 0); @@ -495,9 +498,10 @@ kern_pwritev(td, fd, auio, offset) off_t offset; { struct file *fp; + cap_rights_t rights; int error; - error = fget_write(td, fd, CAP_PWRITE, &fp); + error = fget_write(td, fd, cap_rights_init(&rights, CAP_PWRITE), &fp); if (error) return (error); if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) @@ -575,12 +579,13 @@ kern_ftruncate(td, fd, length) off_t length; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); if (length < 0) return (EINVAL); - error = fget(td, fd, CAP_FTRUNCATE, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp); if (error) return (error); AUDIT_ARG_FILE(td->td_proc, fp); @@ -705,6 +710,9 @@ kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) { struct file *fp; struct filedesc *fdp; +#ifndef CAPABILITIES + cap_rights_t rights; +#endif int error, tmp, locked; AUDIT_ARG_FD(fd); @@ -743,7 +751,8 @@ kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) locked = LA_UNLOCKED; } #else - if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0) { + error = fget(td, fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + if (error != 0) { fp = NULL; goto out; } @@ -1180,8 +1189,10 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events) static __inline int getselfd_cap(struct filedesc *fdp, int fd, struct file **fpp) { + cap_rights_t rights; - return (fget_unlocked(fdp, fd, CAP_POLL_EVENT, 0, fpp, NULL)); + return (fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_POLL_EVENT), + 0, fpp, NULL)); } /* @@ -1357,6 +1368,7 @@ pollrescan(struct thread *td) struct filedesc *fdp; struct file *fp; struct pollfd *fd; + cap_rights_t rights; int n; n = 0; @@ -1373,7 +1385,8 @@ pollrescan(struct thread *td) fp = fdp->fd_ofiles[fd->fd].fde_file; #ifdef CAPABILITIES if (fp == NULL || - cap_check(cap_rights(fdp, fd->fd), CAP_POLL_EVENT) != 0) + cap_check(cap_rights(fdp, fd->fd), + cap_rights_init(&rights, CAP_POLL_EVENT)) != 0) #else if (fp == NULL) #endif @@ -1431,6 +1444,7 @@ pollscan(td, fds, nfd) { struct filedesc *fdp = td->td_proc->p_fd; struct file *fp; + cap_rights_t rights; int i, n = 0; FILEDESC_SLOCK(fdp); @@ -1445,7 +1459,7 @@ pollscan(td, fds, nfd) #ifdef CAPABILITIES if (fp == NULL || cap_check(cap_rights(fdp, fds->fd), - CAP_POLL_EVENT) != 0) + cap_rights_init(&rights, CAP_POLL_EVENT)) != 0) #else if (fp == NULL) #endif diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c index bacaf18..4bafeab 100644 --- a/sys/kern/sys_procdesc.c +++ b/sys/kern/sys_procdesc.c @@ -138,14 +138,14 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, procdesc_init, NULL); * died. */ int -procdesc_find(struct thread *td, int fd, cap_rights_t rights, +procdesc_find(struct thread *td, int fd, cap_rights_t *rightsp, struct proc **p) { struct procdesc *pd; struct file *fp; int error; - error = fget(td, fd, rights, &fp); + error = fget(td, fd, rightsp, &fp); if (error) return (error); if (fp->f_type != DTYPE_PROCDESC) { @@ -185,12 +185,12 @@ procdesc_pid(struct file *fp_procdesc) * Retrieve the PID associated with a process descriptor. */ int -kern_pdgetpid(struct thread *td, int fd, cap_rights_t rights, pid_t *pidp) +kern_pdgetpid(struct thread *td, int fd, cap_rights_t *rightsp, pid_t *pidp) { struct file *fp; int error; - error = fget(td, fd, rights, &fp); + error = fget(td, fd, rightsp, &fp); if (error) return (error); if (fp->f_type != DTYPE_PROCDESC) { @@ -209,11 +209,13 @@ out: int sys_pdgetpid(struct thread *td, struct pdgetpid_args *uap) { + cap_rights_t rights; pid_t pid; int error; AUDIT_ARG_FD(uap->fd); - error = kern_pdgetpid(td, uap->fd, CAP_PDGETPID, &pid); + error = kern_pdgetpid(td, uap->fd, + cap_rights_init(&rights, CAP_PDGETPID), &pid); if (error == 0) error = copyout(&pid, uap->pidp, sizeof(pid)); return (error); diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 789f95a5..e19e310 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -917,9 +917,9 @@ 512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } 513 AUE_LPATHCONF STD { int lpathconf(char *path, int name); } -514 AUE_CAP_NEW STD { int cap_new(int fd, uint64_t rights); } -515 AUE_CAP_RIGHTS_GET STD { int cap_rights_get(int fd, \ - uint64_t *rightsp); } +514 AUE_NULL OBSOL cap_new +515 AUE_CAP_RIGHTS_GET STD { int __cap_rights_get(int version, \ + int fd, cap_rights_t *rightsp); } 516 AUE_CAP_ENTER STD { int cap_enter(void); } 517 AUE_CAP_GETMODE STD { int cap_getmode(u_int *modep); } 518 AUE_PDFORK STD { int pdfork(int *fdp, int flags); } @@ -957,7 +957,7 @@ struct __wrusage *wrusage, \ siginfo_t *info); } 533 AUE_CAP_RIGHTS_LIMIT STD { int cap_rights_limit(int fd, \ - uint64_t rights); } + cap_rights_t *rightsp); } 534 AUE_CAP_IOCTLS_LIMIT STD { int cap_ioctls_limit(int fd, \ const u_long *cmds, size_t ncmds); } 535 AUE_CAP_IOCTLS_GET STD { ssize_t cap_ioctls_get(int fd, \ diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 02eccd7..4fce607 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1837,11 +1837,13 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, struct cdev *dev; struct cdevsw *cdp; struct filedesc *fdp; + cap_rights_t rights; int error, ref; /* Validate the file descriptor. */ fdp = p->p_fd; - error = fget_unlocked(fdp, fd, CAP_TTYHOOK, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_TTYHOOK), + 0, &fp, NULL); if (error != 0) return (error); if (fp->f_ops == &badfileops) { diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 62c54d3..6a1bf76 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2086,19 +2086,19 @@ sys_kmq_unlink(struct thread *td, struct kmq_unlink_args *uap) return (error); } -typedef int (*_fgetf)(struct thread *, int, cap_rights_t, struct file **); +typedef int (*_fgetf)(struct thread *, int, cap_rights_t *, struct file **); /* * Get message queue by giving file slot */ static int -_getmq(struct thread *td, int fd, cap_rights_t rights, _fgetf func, +_getmq(struct thread *td, int fd, cap_rights_t *rightsp, _fgetf func, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { struct mqfs_node *pn; int error; - error = func(td, fd, rights, fpp); + error = func(td, fd, rightsp, fpp); if (error) return (error); if (&mqueueops != (*fpp)->f_ops) { @@ -2117,21 +2117,30 @@ static __inline int getmq(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_POLL_EVENT, fget, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_POLL_EVENT), fget, + fpp, ppn, pmq); } static __inline int getmq_read(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_READ, fget_read, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_READ), fget_read, + fpp, ppn, pmq); } static __inline int getmq_write(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn, struct mqueue **pmq) { - return _getmq(td, fd, CAP_WRITE, fget_write, fpp, ppn, pmq); + cap_rights_t rights; + + return _getmq(td, fd, cap_rights_init(&rights, CAP_WRITE), fget_write, + fpp, ppn, pmq); } static int @@ -2238,6 +2247,7 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap) static int kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev) { + cap_rights_t rights; struct filedesc *fdp; struct proc *p; struct mqueue *mq; @@ -2269,7 +2279,8 @@ again: goto out; } #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, mqd), CAP_POLL_EVENT); + error = cap_check(cap_rights(fdp, mqd), + cap_rights_init(&rights, CAP_POLL_EVENT)); if (error) { FILEDESC_SUNLOCK(fdp); goto out; diff --git a/sys/kern/uipc_sem.c b/sys/kern/uipc_sem.c index 8c86cc4..f641654 100644 --- a/sys/kern/uipc_sem.c +++ b/sys/kern/uipc_sem.c @@ -116,7 +116,7 @@ static int ksem_create(struct thread *td, const char *path, semid_t *semidp, mode_t mode, unsigned int value, int flags, int compat32); static void ksem_drop(struct ksem *ks); -static int ksem_get(struct thread *td, semid_t id, cap_rights_t rights, +static int ksem_get(struct thread *td, semid_t id, cap_rights_t *rightsp, struct file **fpp); static struct ksem *ksem_hold(struct ksem *ks); static void ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks); @@ -600,13 +600,14 @@ ksem_create(struct thread *td, const char *name, semid_t *semidp, mode_t mode, } static int -ksem_get(struct thread *td, semid_t id, cap_rights_t rights, struct file **fpp) +ksem_get(struct thread *td, semid_t id, cap_rights_t *rightsp, + struct file **fpp) { struct ksem *ks; struct file *fp; int error; - error = fget(td, id, rights, &fp); + error = fget(td, id, rightsp, &fp); if (error) return (EINVAL); if (fp->f_type != DTYPE_SEM) { @@ -720,11 +721,13 @@ struct ksem_post_args { int sys_ksem_post(struct thread *td, struct ksem_post_args *uap) { + cap_rights_t rights; struct file *fp; struct ksem *ks; int error; - error = ksem_get(td, uap->id, CAP_SEM_POST, &fp); + error = ksem_get(td, uap->id, + cap_rights_init(&rights, CAP_SEM_POST), &fp); if (error) return (error); ks = fp->f_data; @@ -809,12 +812,13 @@ kern_sem_wait(struct thread *td, semid_t id, int tryflag, { struct timespec ts1, ts2; struct timeval tv; + cap_rights_t rights; struct file *fp; struct ksem *ks; int error; DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid)); - error = ksem_get(td, id, CAP_SEM_WAIT, &fp); + error = ksem_get(td, id, cap_rights_init(&rights, CAP_SEM_WAIT), &fp); if (error) return (error); ks = fp->f_data; @@ -876,11 +880,13 @@ struct ksem_getvalue_args { int sys_ksem_getvalue(struct thread *td, struct ksem_getvalue_args *uap) { + cap_rights_t rights; struct file *fp; struct ksem *ks; int error, val; - error = ksem_get(td, uap->id, CAP_SEM_GETVALUE, &fp); + error = ksem_get(td, uap->id, + cap_rights_init(&rights, CAP_SEM_GETVALUE), &fp); if (error) return (error); ks = fp->f_data; diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 72663a2..7e25da8 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -164,13 +164,13 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW, * A reference on the file entry is held upon returning. */ static int -getsock_cap(struct filedesc *fdp, int fd, cap_rights_t rights, +getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp, u_int *fflagp) { struct file *fp; int error; - error = fget_unlocked(fdp, fd, rights, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); if (error != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { @@ -267,11 +267,13 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_BIND, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_BIND), &fp, NULL); if (error) return (error); so = fp->f_data; @@ -334,10 +336,12 @@ sys_listen(td, uap) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->s); - error = getsock_cap(td->td_proc->p_fd, uap->s, CAP_LISTEN, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, uap->s, + cap_rights_init(&rights, CAP_LISTEN), &fp, NULL); if (error == 0) { so = fp->f_data; #ifdef MAC @@ -419,6 +423,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, int error; struct socket *head, *so; int fd; + cap_rights_t rights; u_int fflag; pid_t pgid; int tmp; @@ -428,7 +433,8 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, AUDIT_ARG_FD(s); fdp = td->td_proc->p_fd; - error = getsock_cap(fdp, s, CAP_ACCEPT, &headfp, &fflag); + error = getsock_cap(fdp, s, cap_rights_init(&rights, CAP_ACCEPT), + &headfp, &fflag); if (error) return (error); head = headfp->f_data; @@ -629,12 +635,14 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; int interrupted = 0; AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_CONNECT, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_CONNECT), &fp, NULL); if (error) return (error); so = fp->f_data; @@ -898,12 +906,12 @@ kern_sendit(td, s, mp, flags, control, segflg) #endif AUDIT_ARG_FD(s); - rights = CAP_SEND; + cap_rights_init(&rights, CAP_SEND); if (mp->msg_name != NULL) { AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name); - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } - error = getsock_cap(td->td_proc->p_fd, s, rights, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, &rights, &fp, NULL); if (error) return (error); so = (struct socket *)fp->f_data; @@ -1099,6 +1107,7 @@ kern_recvit(td, s, mp, fromseg, controlp) struct file *fp; struct socket *so; struct sockaddr *fromsa = NULL; + cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif @@ -1107,7 +1116,8 @@ kern_recvit(td, s, mp, fromseg, controlp) *controlp = NULL; AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_RECV, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_RECV), &fp, NULL); if (error) return (error); so = fp->f_data; @@ -1420,11 +1430,12 @@ sys_shutdown(td, uap) { struct socket *so; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->s); - error = getsock_cap(td->td_proc->p_fd, uap->s, CAP_SHUTDOWN, &fp, - NULL); + error = getsock_cap(td->td_proc->p_fd, uap->s, + cap_rights_init(&rights, CAP_SHUTDOWN), &fp, NULL); if (error == 0) { so = fp->f_data; error = soshutdown(so, uap->how); @@ -1464,6 +1475,7 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) struct socket *so; struct file *fp; struct sockopt sopt; + cap_rights_t rights; if (val == NULL && valsize != 0) return (EFAULT); @@ -1487,7 +1499,8 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) } AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_SETSOCKOPT, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_SETSOCKOPT), &fp, NULL); if (error == 0) { so = fp->f_data; error = sosetopt(so, &sopt); @@ -1543,6 +1556,7 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) struct socket *so; struct file *fp; struct sockopt sopt; + cap_rights_t rights; if (val == NULL) *valsize = 0; @@ -1566,7 +1580,8 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) } AUDIT_ARG_FD(s); - error = getsock_cap(td->td_proc->p_fd, s, CAP_GETSOCKOPT, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, s, + cap_rights_init(&rights, CAP_GETSOCKOPT), &fp, NULL); if (error == 0) { so = fp->f_data; error = sogetopt(so, &sopt); @@ -1621,11 +1636,13 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, { struct socket *so; struct file *fp; + cap_rights_t rights; socklen_t len; int error; AUDIT_ARG_FD(fd); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_GETSOCKNAME, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_GETSOCKNAME), &fp, NULL); if (error) return (error); so = fp->f_data; @@ -1718,11 +1735,13 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, { struct socket *so; struct file *fp; + cap_rights_t rights; socklen_t len; int error; AUDIT_ARG_FD(fd); - error = getsock_cap(td->td_proc->p_fd, fd, CAP_GETPEERNAME, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_GETPEERNAME), &fp, NULL); if (error) return (error); so = fp->f_data; @@ -1907,6 +1926,7 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; struct file *fp; + cap_rights_t rights; int error; if (uap->offset < 0) @@ -1937,8 +1957,10 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) * sendfile(2) can start at any offset within a file so we require * CAP_READ+CAP_SEEK = CAP_PREAD. */ - if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { goto out; + } error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); @@ -1983,6 +2005,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct sf_buf *sf; struct vm_page *pg; struct vattr va; + cap_rights_t rights; off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0; int error, hdrlen = 0, mnw = 0; int bsize; @@ -2030,8 +2053,9 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, * The socket must be a stream socket and connected. * Remember if it a blocking or non-blocking socket. */ - if ((error = getsock_cap(td->td_proc->p_fd, sockfd, CAP_SEND, - &sock_fp, NULL)) != 0) + error = getsock_cap(td->td_proc->p_fd, sockfd, + cap_rights_init(&rights, CAP_SEND), &sock_fp, NULL); + if (error != 0) goto out; so = sock_fp->f_data; if (so->so_type != SOCK_STREAM) { @@ -2463,10 +2487,12 @@ sys_sctp_peeloff(td, uap) int error; struct socket *head, *so; int fd; + cap_rights_t rights; u_int fflag; AUDIT_ARG_FD(uap->sd); - error = fgetsock(td, uap->sd, CAP_PEELOFF, &head, &fflag); + error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), + &head, &fflag); if (error) goto done2; if (head->so_proto->pr_protocol != IPPROTO_SCTP) { @@ -2574,18 +2600,18 @@ sys_sctp_generic_sendmsg (td, uap) u_sinfo = &sinfo; } - rights = CAP_SEND; + cap_rights_init(&rights, CAP_SEND); if (uap->tolen) { error = getsockaddr(&to, uap->to, uap->tolen); if (error) { to = NULL; goto sctp_bad2; } - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, rights, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); if (error) goto sctp_bad; #ifdef KTRACE @@ -2685,18 +2711,18 @@ sys_sctp_generic_sendmsg_iov(td, uap) return (error); u_sinfo = &sinfo; } - rights = CAP_SEND; + cap_rights_init(&rights, CAP_SEND); if (uap->tolen) { error = getsockaddr(&to, uap->to, uap->tolen); if (error) { to = NULL; goto sctp_bad2; } - rights |= CAP_CONNECT; + cap_rights_set(&rights, CAP_CONNECT); } AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, rights, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); if (error) goto sctp_bad1; @@ -2804,12 +2830,14 @@ sys_sctp_generic_recvmsg(td, uap) ssize_t len; int i, msg_flags; int error = 0; + cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td->td_proc->p_fd, uap->sd, CAP_RECV, &fp, NULL); + error = getsock_cap(td->td_proc->p_fd, uap->sd, + cap_rights_init(&rights, CAP_RECV), &fp, NULL); if (error) { return (error); } diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 7a4db04..c0a5d2e 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -464,6 +464,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) struct unpcb *unp; struct vnode *vp; struct mount *mp; + cap_rights_t rights; char *buf; unp = sotounpcb(so); @@ -502,7 +503,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) restart: NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME, - UIO_SYSSPACE, buf, fd, CAP_BINDAT, td); + UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_BINDAT), td); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ error = namei(&nd); if (error) @@ -1276,10 +1277,11 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam, struct vnode *vp; struct socket *so2, *so3; struct unpcb *unp, *unp2, *unp3; - int error, len; struct nameidata nd; char buf[SOCK_MAXADDRLEN]; struct sockaddr *sa; + cap_rights_t rights; + int error, len; UNP_LINK_WLOCK_ASSERT(); @@ -1305,7 +1307,7 @@ unp_connectat(int fd, struct socket *so, struct sockaddr *nam, sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, - UIO_SYSSPACE, buf, fd, CAP_CONNECTAT, td); + UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_CONNECTAT), td); error = namei(&nd); if (error) vp = NULL; diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index 1c9923d..362792b 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -399,9 +399,11 @@ int sys___acl_get_fd(struct thread *td, struct __acl_get_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_GET, &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_GET), &fp); if (error == 0) { error = vacl_get_acl(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); @@ -416,9 +418,11 @@ int sys___acl_set_fd(struct thread *td, struct __acl_set_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_SET, &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_SET), &fp); if (error == 0) { error = vacl_set_acl(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); @@ -469,10 +473,11 @@ int sys___acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_DELETE, - &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_DELETE), &fp); if (error == 0) { error = vacl_delete(td, fp->f_vnode, uap->type); fdrop(fp, td); @@ -523,10 +528,11 @@ int sys___acl_aclcheck_fd(struct thread *td, struct __acl_aclcheck_fd_args *uap) { struct file *fp; + cap_rights_t rights; int error; - error = getvnode(td->td_proc->p_fd, uap->filedes, CAP_ACL_CHECK, - &fp); + error = getvnode(td->td_proc->p_fd, uap->filedes, + cap_rights_init(&rights, CAP_ACL_CHECK), &fp); if (error == 0) { error = vacl_aclcheck(td, fp->f_vnode, uap->type, uap->aclp); fdrop(fp, td); diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index a66f7c2..9f3adaf 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1567,6 +1567,7 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, int type, struct aiocb_ops *ops) { struct proc *p = td->td_proc; + cap_rights_t rights; struct file *fp; struct socket *so; struct aiocblist *aiocbe, *cb; @@ -1647,19 +1648,21 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, fd = aiocbe->uaiocb.aio_fildes; switch (opcode) { case LIO_WRITE: - error = fget_write(td, fd, CAP_PWRITE, &fp); + error = fget_write(td, fd, + cap_rights_init(&rights, CAP_PWRITE), &fp); break; case LIO_READ: - error = fget_read(td, fd, CAP_PREAD, &fp); + error = fget_read(td, fd, + cap_rights_init(&rights, CAP_PREAD), &fp); break; case LIO_SYNC: - error = fget(td, fd, CAP_FSYNC, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_FSYNC), &fp); break; case LIO_MLOCK: fp = NULL; break; case LIO_NOP: - error = fget(td, fd, CAP_NONE, &fp); + error = fget(td, fd, cap_rights_init(&rights), &fp); break; default: error = EINVAL; diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 700a70c..bc7b942 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -216,6 +216,7 @@ sys_extattr_set_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -225,7 +226,8 @@ sys_extattr_set_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_SET, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); if (error) return (error); @@ -389,6 +391,7 @@ sys_extattr_get_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -398,7 +401,8 @@ sys_extattr_get_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_GET, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_GET), &fp); if (error) return (error); @@ -531,6 +535,7 @@ sys_extattr_delete_fd(td, uap) { struct file *fp; char attrname[EXTATTR_MAXNAMELEN]; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); @@ -540,8 +545,8 @@ sys_extattr_delete_fd(td, uap) return (error); AUDIT_ARG_TEXT(attrname); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_DELETE, - &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_DELETE), &fp); if (error) return (error); @@ -687,11 +692,13 @@ sys_extattr_list_fd(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_VALUE(uap->attrnamespace); - error = getvnode(td->td_proc->p_fd, uap->fd, CAP_EXTATTR_LIST, &fp); + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_EXTATTR_LIST), &fp); if (error) return (error); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 7fe1908..d4d0166 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -222,20 +222,26 @@ namei(struct nameidata *ndp) dp = ndp->ni_startdir; error = 0; } else if (ndp->ni_dirfd != AT_FDCWD) { + cap_rights_t rights; + + rights = ndp->ni_rightsneeded; + cap_rights_set(&rights, CAP_LOOKUP); + if (cnp->cn_flags & AUDITVNODE1) AUDIT_ARG_ATFD1(ndp->ni_dirfd); if (cnp->cn_flags & AUDITVNODE2) AUDIT_ARG_ATFD2(ndp->ni_dirfd); error = fgetvp_rights(td, ndp->ni_dirfd, - ndp->ni_rightsneeded | CAP_LOOKUP, - &ndp->ni_filecaps, &dp); + &rights, &ndp->ni_filecaps, &dp); #ifdef CAPABILITIES /* * If file descriptor doesn't have all rights, * all lookups relative to it must also be * strictly relative. */ - if (ndp->ni_filecaps.fc_rights != CAP_ALL || + CAP_ALL(&rights); + if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, + &rights) || ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL || ndp->ni_filecaps.fc_nioctls != -1) { ndp->ni_strictrelative = 1; @@ -1059,6 +1065,27 @@ bad: return (error); } +void +NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, enum uio_seg segflg, + const char *namep, int dirfd, struct vnode *startdir, cap_rights_t *rightsp, + struct thread *td) +{ + + ndp->ni_cnd.cn_nameiop = op; + ndp->ni_cnd.cn_flags = flags; + ndp->ni_segflg = segflg; + ndp->ni_dirp = namep; + ndp->ni_dirfd = dirfd; + ndp->ni_startdir = startdir; + ndp->ni_strictrelative = 0; + if (rightsp != NULL) + ndp->ni_rightsneeded = *rightsp; + else + cap_rights_init(&ndp->ni_rightsneeded); + filecaps_init(&ndp->ni_filecaps); + ndp->ni_cnd.cn_thread = td; +} + /* * Free data allocated by namei(); see namei(9) for details. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2877ad2..7df315d 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -367,10 +367,12 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) struct mount *mp; struct statfs *sp, sb; struct vnode *vp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); - error = getvnode(td->td_proc->p_fd, fd, CAP_FSTATFS, &fp); + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_FSTATFS), &fp); if (error) return (error); vp = fp->f_vnode; @@ -730,10 +732,13 @@ sys_fchdir(td, uap) struct vnode *vp, *tdp, *vpold; struct mount *mp; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); - if ((error = getvnode(fdp, uap->fd, CAP_FCHDIR, &fp)) != 0) + error = getvnode(fdp, uap->fd, cap_rights_init(&rights, CAP_FCHDIR), + &fp); + if (error != 0) return (error); vp = fp->f_vnode; VREF(vp); @@ -954,42 +959,39 @@ change_root(vp, td) return (0); } -static __inline cap_rights_t -flags_to_rights(int flags) +static __inline void +flags_to_rights(int flags, cap_rights_t *rightsp) { - cap_rights_t rights = 0; if (flags & O_EXEC) { - rights |= CAP_FEXECVE; + cap_rights_set(rightsp, CAP_FEXECVE); } else { switch ((flags & O_ACCMODE)) { case O_RDONLY: - rights |= CAP_READ; + cap_rights_set(rightsp, CAP_READ); break; case O_RDWR: - rights |= CAP_READ; + cap_rights_set(rightsp, CAP_READ); /* FALLTHROUGH */ case O_WRONLY: - rights |= CAP_WRITE; + cap_rights_set(rightsp, CAP_WRITE); if (!(flags & (O_APPEND | O_TRUNC))) - rights |= CAP_SEEK; + cap_rights_set(rightsp, CAP_SEEK); break; } } if (flags & O_CREAT) - rights |= CAP_CREATE; + cap_rights_set(rightsp, CAP_CREATE); if (flags & O_TRUNC) - rights |= CAP_FTRUNCATE; + cap_rights_set(rightsp, CAP_FTRUNCATE); if (flags & (O_SYNC | O_FSYNC)) - rights |= CAP_FSYNC; + cap_rights_set(rightsp, CAP_FSYNC); if (flags & (O_EXLOCK | O_SHLOCK)) - rights |= CAP_FLOCK; - - return (rights); + cap_rights_set(rightsp, CAP_FLOCK); } /* @@ -1051,12 +1053,13 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int cmode; int indx = -1, error; struct nameidata nd; - cap_rights_t rights_needed = CAP_LOOKUP; + cap_rights_t rights; AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); /* XXX: audit dirfd */ - rights_needed |= flags_to_rights(flags); + cap_rights_init(&rights, CAP_LOOKUP); + flags_to_rights(flags, &rights); /* * Only one of the O_EXEC, O_RDONLY, O_WRONLY and O_RDWR flags * may be specified. @@ -1084,7 +1087,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, fp->f_flag = flags & FMASK; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, - rights_needed, td); + &rights, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, fp); if (error) { @@ -1258,6 +1261,7 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int error; int whiteout = 0; struct nameidata nd; + cap_rights_t rights; AUDIT_ARG_MODE(mode); AUDIT_ARG_DEV(dev); @@ -1285,7 +1289,7 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, CAP_MKNODAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT), td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -1398,6 +1402,7 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct mount *mp; struct vattr vattr; + cap_rights_t rights; int error; struct nameidata nd; @@ -1405,7 +1410,7 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - pathseg, path, fd, CAP_MKFIFOAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT), td); if ((error = namei(&nd)) != 0) return (error); if (nd.ni_vp != NULL) { @@ -1541,6 +1546,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, struct vnode *vp; struct mount *mp; struct nameidata nd; + cap_rights_t rights; int error; bwillwrite(); @@ -1559,7 +1565,7 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, return (error); } NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2, - segflg, path2, fd2, CAP_LINKAT, td); + segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT), td); if ((error = namei(&nd)) == 0) { if (nd.ni_vp != NULL) { if (nd.ni_dvp == nd.ni_vp) @@ -1640,6 +1646,7 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, char *syspath; int error; struct nameidata nd; + cap_rights_t rights; if (segflg == UIO_SYSSPACE) { syspath = path1; @@ -1652,7 +1659,7 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path2, fd, CAP_SYMLINKAT, td); + segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT), td); if ((error = namei(&nd)) != 0) goto out; if (nd.ni_vp) { @@ -1800,11 +1807,12 @@ kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int error; struct nameidata nd; struct stat sb; + cap_rights_t rights; restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1, - pathseg, path, fd, CAP_UNLINKAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td); if ((error = namei(&nd)) != 0) return (error == EINVAL ? EPERM : error); vp = nd.ni_vp; @@ -1880,10 +1888,12 @@ sys_lseek(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); - if ((error = fget(td, uap->fd, CAP_SEEK, &fp)) != 0) + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_SEEK), &fp); + if (error != 0) return (error); error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ? fo_seek(fp, uap->offset, uap->whence, td) : ESPIPE; @@ -2026,6 +2036,7 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct ucred *cred, *tmpcred; struct vnode *vp; struct nameidata nd; + cap_rights_t rights; int error; /* @@ -2042,7 +2053,8 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, cred = tmpcred = td->td_ucred; AUDIT_ARG_VALUE(amode); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | - AUDITVNODE1, pathseg, path, fd, CAP_FSTAT, td); + AUDITVNODE1, pathseg, path, fd, cap_rights_init(&rights, CAP_FSTAT), + td); if ((error = namei(&nd)) != 0) goto out1; vp = nd.ni_vp; @@ -2244,6 +2256,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, { struct nameidata nd; struct stat sb; + cap_rights_t rights; int error; if (flag & ~AT_SYMLINK_NOFOLLOW) @@ -2251,7 +2264,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, NDINIT_ATRIGHTS(&nd, LOOKUP, ((flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, - CAP_FSTAT, td); + cap_rights_init(&rights, CAP_FSTAT), td); if ((error = namei(&nd)) != 0) return (error); @@ -2663,12 +2676,13 @@ kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag) { struct nameidata nd; + cap_rights_t rights; int error, follow; AUDIT_ARG_FFLAGS(flags); follow = (atflag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHFLAGS, td); + cap_rights_init(&rights, CAP_FCHFLAGS), td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2695,12 +2709,14 @@ sys_fchflags(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_FFLAGS(uap->flags); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FCHFLAGS, - &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_FCHFLAGS), &fp); + if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); @@ -2820,11 +2836,12 @@ kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int error; struct nameidata nd; int follow; + cap_rights_t rights; AUDIT_ARG_MODE(mode); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHMOD, td); + cap_rights_init(&rights, CAP_FCHMOD), td); if ((error = namei(&nd)) != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); @@ -2846,12 +2863,13 @@ int sys_fchmod(struct thread *td, struct fchmod_args *uap) { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_MODE(uap->mode); - error = fget(td, uap->fd, CAP_FCHMOD, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHMOD), &fp); if (error != 0) return (error); error = fo_chmod(fp, uap->mode, td->td_ucred, td); @@ -2949,12 +2967,13 @@ kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int uid, int gid, int flag) { struct nameidata nd; + cap_rights_t rights; int error, follow; AUDIT_ARG_OWNER(uid, gid); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, pathseg, path, fd, - CAP_FCHOWN, td); + cap_rights_init(&rights, CAP_FCHOWN), td); if ((error = namei(&nd)) != 0) return (error); @@ -3016,11 +3035,12 @@ sys_fchown(td, uap) } */ *uap; { struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(uap->fd); AUDIT_ARG_OWNER(uap->uid, uap->gid); - error = fget(td, uap->fd, CAP_FCHOWN, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_FCHOWN), &fp); if (error != 0) return (error); error = fo_chown(fp, uap->uid, uap->gid, td->td_ucred, td); @@ -3155,12 +3175,13 @@ kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct nameidata nd; struct timespec ts[2]; + cap_rights_t rights; int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, - CAP_FUTIMES, td); + cap_rights_init(&rights, CAP_FUTIMES), td); if ((error = namei(&nd)) != 0) return (error); @@ -3238,12 +3259,15 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr, { struct timespec ts[2]; struct file *fp; + cap_rights_t rights; int error; AUDIT_ARG_FD(fd); if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); - if ((error = getvnode(td->td_proc->p_fd, fd, CAP_FUTIMES, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_FUTIMES), &fp); + if (error != 0) return (error); #ifdef AUDIT vn_lock(fp->f_vnode, LK_SHARED | LK_RETRY); @@ -3390,10 +3414,13 @@ sys_fsync(td, uap) struct vnode *vp; struct mount *mp; struct file *fp; + cap_rights_t rights; int error, lock_flags; AUDIT_ARG_FD(uap->fd); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_FSYNC, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_FSYNC), &fp); + if (error != 0) return (error); vp = fp->f_vnode; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) @@ -3472,15 +3499,17 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, struct mount *mp = NULL; struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; + cap_rights_t rights; int error; bwillwrite(); #ifdef MAC NDINIT_ATRIGHTS(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | - AUDITVNODE1, pathseg, old, oldfd, CAP_RENAMEAT, td); + AUDITVNODE1, pathseg, old, oldfd, + cap_rights_init(&rights, CAP_RENAMEAT), td); #else NDINIT_ATRIGHTS(&fromnd, DELETE, WANTPARENT | SAVESTART | AUDITVNODE1, - pathseg, old, oldfd, CAP_RENAMEAT, td); + pathseg, old, oldfd, cap_rights_init(&rights, CAP_RENAMEAT), td); #endif if ((error = namei(&fromnd)) != 0) @@ -3502,7 +3531,8 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, goto out1; } NDINIT_ATRIGHTS(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | - SAVESTART | AUDITVNODE2, pathseg, new, newfd, CAP_LINKAT, td); + SAVESTART | AUDITVNODE2, pathseg, new, newfd, + cap_rights_init(&rights, CAP_LINKAT), td); if (fromnd.ni_vp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { @@ -3531,8 +3561,8 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, * If the target already exists we require CAP_UNLINKAT * from 'newfd'. */ - error = cap_check(tond.ni_filecaps.fc_rights, - CAP_UNLINKAT); + error = cap_check(&tond.ni_filecaps.fc_rights, + cap_rights_init(&rights, CAP_UNLINKAT)); if (error != 0) goto out; } @@ -3630,6 +3660,7 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, struct mount *mp; struct vnode *vp; struct vattr vattr; + cap_rights_t rights; int error; struct nameidata nd; @@ -3637,7 +3668,7 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1, - segflg, path, fd, CAP_MKDIRAT, td); + segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT), td); nd.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&nd)) != 0) return (error); @@ -3715,13 +3746,14 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) { struct mount *mp; struct vnode *vp; + cap_rights_t rights; int error; struct nameidata nd; restart: bwillwrite(); NDINIT_ATRIGHTS(&nd, DELETE, LOCKPARENT | LOCKLEAF | AUDITVNODE1, - pathseg, path, fd, CAP_UNLINKAT, td); + pathseg, path, fd, cap_rights_init(&rights, CAP_UNLINKAT), td); if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; @@ -3806,6 +3838,7 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, struct uio auio, kuio; struct iovec aiov, kiov; struct dirent *dp, *edp; + cap_rights_t rights; caddr_t dirbuf; int error, eofflag, readcnt; long loff; @@ -3814,7 +3847,9 @@ kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, /* XXX arbitrary sanity limit on `count'. */ if (uap->count > 64 * 1024) return (EINVAL); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, uap->fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -3967,6 +4002,7 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, struct file *fp; struct uio auio; struct iovec aiov; + cap_rights_t rights; long loff; int error, eofflag; off_t foffset; @@ -3975,7 +4011,9 @@ kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, if (count > IOSIZE_MAX) return (EINVAL); auio.uio_resid = count; - if ((error = getvnode(td->td_proc->p_fd, fd, CAP_READ, &fp)) != 0) + error = getvnode(td->td_proc->p_fd, fd, + cap_rights_init(&rights, CAP_READ), &fp); + if (error != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -4138,12 +4176,12 @@ out: * entry is held upon returning. */ int -getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, struct file **fpp) +getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp) { struct file *fp; int error; - error = fget_unlocked(fdp, fd, rights, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, rightsp, 0, &fp, NULL); if (error != 0) return (error); @@ -4466,11 +4504,12 @@ kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) struct file *fp; struct mount *mp; struct vnode *vp; + cap_rights_t rights; off_t olen, ooffset; int error; fp = NULL; - error = fget(td, fd, CAP_WRITE, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); if (error != 0) goto out; @@ -4562,6 +4601,7 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, struct fadvise_info *fa, *new; struct file *fp; struct vnode *vp; + cap_rights_t rights; off_t end; int error; @@ -4582,7 +4622,7 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, return (EINVAL); } /* XXX: CAP_POSIX_FADVISE? */ - error = fget(td, fd, CAP_NONE, &fp); + error = fget(td, fd, cap_rights_init(&rights), &fp); if (error != 0) goto out; diff --git a/sys/netsmb/smb_dev.c b/sys/netsmb/smb_dev.c index 0efb282..279ae67 100644 --- a/sys/netsmb/smb_dev.c +++ b/sys/netsmb/smb_dev.c @@ -378,6 +378,7 @@ int smb_dev2share(int fd, int mode, struct smb_cred *scred, struct smb_share **sspp, struct smb_dev **ssdp) { + cap_rights_t rights; struct file *fp, *fptmp; struct smb_dev *sdp; struct smb_share *ssp; @@ -385,7 +386,7 @@ smb_dev2share(int fd, int mode, struct smb_cred *scred, int error; td = curthread; - error = fget(td, fd, CAP_READ, &fp); + error = fget(td, fd, cap_rights_init(&rights, CAP_READ), &fp); if (error) return (error); fptmp = td->td_fpop; diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c index db69df9..85003b7 100644 --- a/sys/nfsserver/nfs_srvkrpc.c +++ b/sys/nfsserver/nfs_srvkrpc.c @@ -168,6 +168,7 @@ nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) struct file *fp; struct nfsd_addsock_args addsockarg; struct nfsd_nfsd_args nfsdarg; + cap_rights_t rights; int error; if (uap->flag & NFSSVC_ADDSOCK) { @@ -175,7 +176,8 @@ nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) sizeof(addsockarg)); if (error) return (error); - error = fget(td, addsockarg.sock, CAP_SOCK_SERVER, &fp); + error = fget(td, addsockarg.sock, + cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); if (error) return (error); if (fp->f_type != DTYPE_SOCKET) { diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h index dd55875..559d571 100644 --- a/sys/security/audit/audit.h +++ b/sys/security/audit/audit.h @@ -114,7 +114,7 @@ void audit_arg_auditon(union auditon_udata *udata); void audit_arg_file(struct proc *p, struct file *fp); void audit_arg_argv(char *argv, int argc, int length); void audit_arg_envv(char *envv, int envc, int length); -void audit_arg_rights(cap_rights_t rights); +void audit_arg_rights(cap_rights_t *rightsp); void audit_arg_fcntl_rights(uint32_t fcntlrights); void audit_sysclose(struct thread *td, int fd); void audit_cred_copy(struct ucred *src, struct ucred *dest); diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c index 4927be0..2e86842 100644 --- a/sys/security/audit/audit_arg.c +++ b/sys/security/audit/audit_arg.c @@ -861,7 +861,7 @@ audit_arg_envv(char *envv, int envc, int length) } void -audit_arg_rights(cap_rights_t rights) +audit_arg_rights(cap_rights_t *rightsp) { struct kaudit_record *ar; @@ -869,7 +869,7 @@ audit_arg_rights(cap_rights_t rights) if (ar == NULL) return; - ar->k_ar.ar_arg_rights = rights; + ar->k_ar.ar_arg_rights = *rightsp; ARG_SET_VALID(ar, ARG_RIGHTS); } diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c index 03b3c23..9f29ece 100644 --- a/sys/security/audit/audit_bsm.c +++ b/sys/security/audit/audit_bsm.c @@ -1611,14 +1611,13 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) } break; - case AUE_CAP_NEW: case AUE_CAP_RIGHTS_LIMIT: /* * XXXRW/XXXJA: Would be nice to audit socket/etc information. */ FD_VNODE1_TOKENS; if (ARG_IS_VALID(kar, ARG_RIGHTS)) { - tok = au_to_arg64(2, "rights", ar->ar_arg_rights); + tok = au_to_rights(&ar->ar_arg_rights); kau_write(rec, tok); } break; diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h index e23ba08..b5c373a 100644 --- a/sys/security/audit/audit_private.h +++ b/sys/security/audit/audit_private.h @@ -41,6 +41,7 @@ #error "no user-serviceable parts inside" #endif +#include #include #include #include diff --git a/sys/security/audit/bsm_token.c b/sys/security/audit/bsm_token.c index 6d0d67f..763d597 100644 --- a/sys/security/audit/bsm_token.c +++ b/sys/security/audit/bsm_token.c @@ -835,6 +835,22 @@ au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, tid)); } +token_t * +au_to_rights(cap_rights_t *rightsp) +{ + token_t *t; + u_char *dptr; + int i; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(*rightsp)); + + ADD_U_CHAR(dptr, AUT_RIGHTS); + for (i = 0; i < nitems(rightsp->cr_rights); i++) + ADD_U_INT64(dptr, rightsp->cr_rights[i]); + + return (t); +} + /* * token ID 1 byte * error status 1 byte diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index ff55ec9..6405586 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -229,6 +229,7 @@ sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) struct vnode *vp; struct pipe *pipe; struct socket *so; + cap_rights_t rights; short label_type; int error; @@ -248,7 +249,7 @@ sys___mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = fget(td, uap->fd, CAP_MAC_GET, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_GET), &fp); if (error) goto out; @@ -425,6 +426,7 @@ sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) struct mount *mp; struct vnode *vp; struct mac mac; + cap_rights_t rights; char *buffer; int error; @@ -443,7 +445,7 @@ sys___mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) return (error); } - error = fget(td, uap->fd, CAP_MAC_SET, &fp); + error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_SET), &fp); if (error) goto out; diff --git a/sys/sys/_types.h b/sys/sys/_types.h index 34d1edb..ffef9d8 100644 --- a/sys/sys/_types.h +++ b/sys/sys/_types.h @@ -38,7 +38,6 @@ typedef __uint32_t __blksize_t; /* file block size */ typedef __int64_t __blkcnt_t; /* file block count */ typedef __int32_t __clockid_t; /* clock_gettime()... */ -typedef __uint64_t __cap_rights_t; /* capability rights */ typedef __uint32_t __fflags_t; /* file flags */ typedef __uint64_t __fsblkcnt_t; typedef __uint64_t __fsfilcnt_t; diff --git a/sys/sys/capability.h b/sys/sys/capability.h index ec63de7..e5b9ec7 100644 --- a/sys/sys/capability.h +++ b/sys/sys/capability.h @@ -42,9 +42,16 @@ #include #include +#include #include #include +#ifndef _KERNEL +#include +#endif + +#define CAPRIGHT(idx, bit) ((1ULL << (57 + (idx))) | (bit)) + /* * Possible rights on capabilities. * @@ -59,29 +66,31 @@ * involve reads or writes depending a great deal on context. */ -#define CAP_NONE 0x0000000000000000ULL +/* INDEX 0 */ /* * General file I/O. */ /* Allows for openat(O_RDONLY), read(2), readv(2). */ -#define CAP_READ 0x0000000000000001ULL +#define CAP_READ CAPRIGHT(0, 0x0000000000000001ULL) /* Allows for openat(O_WRONLY | O_APPEND), write(2), writev(2). */ -#define CAP_WRITE 0x0000000000000002ULL +#define CAP_WRITE CAPRIGHT(0, 0x0000000000000002ULL) +/* Allows for lseek(fd, 0, SEEK_CUR). */ +#define CAP_SEEK_TELL CAPRIGHT(0, 0x0000000000000004ULL) /* Allows for lseek(2). */ -#define CAP_SEEK 0x0000000000000080ULL +#define CAP_SEEK (CAP_SEEK_TELL | 0x0000000000000008ULL) /* Allows for pread(2), preadv(2). */ #define CAP_PREAD (CAP_SEEK | CAP_READ) /* Allows for openat(O_WRONLY) (without O_APPEND), pwrite(2), pwritev(2). */ #define CAP_PWRITE (CAP_SEEK | CAP_WRITE) /* Allows for mmap(PROT_NONE). */ -#define CAP_MMAP 0x0000000000000004ULL +#define CAP_MMAP CAPRIGHT(0, 0x0000000000000010ULL) /* Allows for mmap(PROT_READ). */ #define CAP_MMAP_R (CAP_MMAP | CAP_SEEK | CAP_READ) /* Allows for mmap(PROT_WRITE). */ #define CAP_MMAP_W (CAP_MMAP | CAP_SEEK | CAP_WRITE) /* Allows for mmap(PROT_EXEC). */ -#define CAP_MMAP_X (CAP_MMAP | CAP_SEEK | 0x0000000000000008ULL) +#define CAP_MMAP_X (CAP_MMAP | CAP_SEEK | 0x0000000000000020ULL) /* Allows for mmap(PROT_READ | PROT_WRITE). */ #define CAP_MMAP_RW (CAP_MMAP_R | CAP_MMAP_W) /* Allows for mmap(PROT_READ | PROT_EXEC). */ @@ -91,67 +100,67 @@ /* Allows for mmap(PROT_READ | PROT_WRITE | PROT_EXEC). */ #define CAP_MMAP_RWX (CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X) /* Allows for openat(O_CREAT). */ -#define CAP_CREATE 0x0000000000080000ULL +#define CAP_CREATE CAPRIGHT(0, 0x0000000000000040ULL) /* Allows for openat(O_EXEC) and fexecve(2) in turn. */ -#define CAP_FEXECVE 0x0000000000000010ULL +#define CAP_FEXECVE CAPRIGHT(0, 0x0000000000000080ULL) /* Allows for openat(O_SYNC), openat(O_FSYNC), fsync(2). */ -#define CAP_FSYNC 0x0000000000000020ULL +#define CAP_FSYNC CAPRIGHT(0, 0x0000000000000100ULL) /* Allows for openat(O_TRUNC), ftruncate(2). */ -#define CAP_FTRUNCATE 0x0000000000000040ULL - -/* VFS methods. */ -#define CAP_FCHDIR 0x0000000000000200ULL -#define CAP_FCHFLAGS 0x0000000000000100ULL -#define CAP_CHFLAGSAT CAP_FCHFLAGS -#define CAP_FCHMOD 0x0000000000000400ULL -#define CAP_FCHMODAT CAP_FCHMOD -#define CAP_FCHOWN 0x0000000000000800ULL -#define CAP_FCHOWNAT CAP_FCHOWN -#define CAP_FCNTL 0x0000000000001000ULL -#define CAP_FLOCK 0x0000000000004000ULL -#define CAP_FPATHCONF 0x0000000000002000ULL -#define CAP_FSCK 0x0000000000008000ULL -#define CAP_FSTAT 0x0000000000010000ULL -#define CAP_FSTATAT CAP_FSTAT -#define CAP_FSTATFS 0x0000000000020000ULL -#define CAP_FUTIMES 0x0000000000040000ULL -#define CAP_FUTIMESAT CAP_FUTIMES -#define CAP_LINKAT 0x0000000000400000ULL -#define CAP_MKDIRAT 0x0000000000200000ULL -#define CAP_MKFIFOAT 0x0000000000800000ULL -#define CAP_MKNODAT 0x0080000000000000ULL -#define CAP_RENAMEAT 0x0200000000000000ULL -#define CAP_SYMLINKAT 0x0100000000000000ULL -#define CAP_UNLINKAT 0x0000000000100000ULL +#define CAP_FTRUNCATE CAPRIGHT(0, 0x0000000000000200ULL) /* Lookups - used to constrain *at() calls. */ -#define CAP_LOOKUP 0x0000000001000000ULL +#define CAP_LOOKUP CAPRIGHT(0, 0x0000000000000400ULL) + +/* VFS methods. */ +#define CAP_FCHDIR CAPRIGHT(0, 0x0000000000000800ULL) +#define CAP_FCHFLAGS CAPRIGHT(0, 0x0000000000001000ULL) +#define CAP_CHFLAGSAT (CAP_FCHFLAGS | CAP_LOOKUP) +#define CAP_FCHMOD CAPRIGHT(0, 0x0000000000002000ULL) +#define CAP_FCHMODAT (CAP_FCHMOD | CAP_LOOKUP) +#define CAP_FCHOWN CAPRIGHT(0, 0x0000000000004000ULL) +#define CAP_FCHOWNAT (CAP_FCHOWN | CAP_LOOKUP) +#define CAP_FCNTL CAPRIGHT(0, 0x0000000000008000ULL) +#define CAP_FLOCK CAPRIGHT(0, 0x0000000000010000ULL) +#define CAP_FPATHCONF CAPRIGHT(0, 0x0000000000020000ULL) +#define CAP_FSCK CAPRIGHT(0, 0x0000000000040000ULL) +#define CAP_FSTAT CAPRIGHT(0, 0x0000000000080000ULL) +#define CAP_FSTATAT (CAP_FSTAT | CAP_LOOKUP) +#define CAP_FSTATFS CAPRIGHT(0, 0x0000000000100000ULL) +#define CAP_FUTIMES CAPRIGHT(0, 0x0000000000200000ULL) +#define CAP_FUTIMESAT (CAP_FUTIMES | CAP_LOOKUP) +#define CAP_LINKAT CAPRIGHT(0, 0x0000000000400000ULL) +#define CAP_MKDIRAT CAPRIGHT(0, 0x0000000000800000ULL) +#define CAP_MKFIFOAT CAPRIGHT(0, 0x0000000001000000ULL) +#define CAP_MKNODAT CAPRIGHT(0, 0x0000000002000000ULL) +#define CAP_RENAMEAT CAPRIGHT(0, 0x0000000004000000ULL) +#define CAP_SYMLINKAT CAPRIGHT(0, 0x0000000008000000ULL) +#define CAP_UNLINKAT CAPRIGHT(0, 0x0000000010000000ULL) /* Extended attributes. */ -#define CAP_EXTATTR_DELETE 0x0000000002000000ULL -#define CAP_EXTATTR_GET 0x0000000004000000ULL -#define CAP_EXTATTR_LIST 0x0000000008000000ULL -#define CAP_EXTATTR_SET 0x0000000010000000ULL +#define CAP_EXTATTR_DELETE CAPRIGHT(0, 0x0000000020000000ULL) +#define CAP_EXTATTR_GET CAPRIGHT(0, 0x0000000040000000ULL) +#define CAP_EXTATTR_LIST CAPRIGHT(0, 0x0000000080000000ULL) +#define CAP_EXTATTR_SET CAPRIGHT(0, 0x0000000100000000ULL) /* Access Control Lists. */ -#define CAP_ACL_CHECK 0x0000000020000000ULL -#define CAP_ACL_DELETE 0x0000000040000000ULL -#define CAP_ACL_GET 0x0000000080000000ULL -#define CAP_ACL_SET 0x0000000100000000ULL +#define CAP_ACL_CHECK CAPRIGHT(0, 0x0000000200000000ULL) +#define CAP_ACL_DELETE CAPRIGHT(0, 0x0000000400000000ULL) +#define CAP_ACL_GET CAPRIGHT(0, 0x0000000800000000ULL) +#define CAP_ACL_SET CAPRIGHT(0, 0x0000001000000000ULL) /* Socket operations. */ -#define CAP_ACCEPT 0x0000000200000000ULL -#define CAP_BIND 0x0000000400000000ULL -#define CAP_CONNECT 0x0000000800000000ULL -#define CAP_GETPEERNAME 0x0000001000000000ULL -#define CAP_GETSOCKNAME 0x0000002000000000ULL -#define CAP_GETSOCKOPT 0x0000004000000000ULL -#define CAP_LISTEN 0x0000008000000000ULL -#define CAP_PEELOFF 0x0000010000000000ULL +#define CAP_ACCEPT CAPRIGHT(0, 0x0000002000000000ULL) +#define CAP_BIND CAPRIGHT(0, 0x0000004000000000ULL) +#define CAP_CONNECT CAPRIGHT(0, 0x0000008000000000ULL) +#define CAP_GETPEERNAME CAPRIGHT(0, 0x0000010000000000ULL) +#define CAP_GETSOCKNAME CAPRIGHT(0, 0x0000020000000000ULL) +#define CAP_GETSOCKOPT CAPRIGHT(0, 0x0000040000000000ULL) +#define CAP_LISTEN CAPRIGHT(0, 0x0000080000000000ULL) +#define CAP_PEELOFF CAPRIGHT(0, 0x0000100000000000ULL) #define CAP_RECV CAP_READ #define CAP_SEND CAP_WRITE -#define CAP_SETSOCKOPT 0x0000020000000000ULL -#define CAP_SHUTDOWN 0x0000040000000000ULL +#define CAP_SETSOCKOPT CAPRIGHT(0, 0x0000200000000000ULL) +#define CAP_SHUTDOWN CAPRIGHT(0, 0x0000400000000000ULL) #define CAP_SOCK_CLIENT \ (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \ @@ -161,56 +170,69 @@ CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_RECV | CAP_SEND | \ CAP_SETSOCKOPT | CAP_SHUTDOWN) +/* All used bits for index 0. */ +#define CAP_ALL0 CAPRIGHT(0, 0x00007FFFFFFFFFFFULL) + +/* Available bits for index 0. */ +#define CAP_UNUSED0_48 CAPRIGHT(0, 0x0000800000000000ULL) +/* ... */ +#define CAP_UNUSED0_57 CAPRIGHT(0, 0x0100000000000000ULL) + +/* INDEX 1 */ + /* Mandatory Access Control. */ -#define CAP_MAC_GET 0x0000080000000000ULL -#define CAP_MAC_SET 0x0000100000000000ULL +#define CAP_MAC_GET CAPRIGHT(1, 0x0000000000000001ULL) +#define CAP_MAC_SET CAPRIGHT(1, 0x0000000000000002ULL) /* Methods on semaphores. */ -#define CAP_SEM_GETVALUE 0x0000200000000000ULL -#define CAP_SEM_POST 0x0000400000000000ULL -#define CAP_SEM_WAIT 0x0000800000000000ULL +#define CAP_SEM_GETVALUE CAPRIGHT(1, 0x0000000000000004ULL) +#define CAP_SEM_POST CAPRIGHT(1, 0x0000000000000008ULL) +#define CAP_SEM_WAIT CAPRIGHT(1, 0x0000000000000010ULL) /* kqueue events. */ -#define CAP_POLL_EVENT 0x0001000000000000ULL -#define CAP_POST_EVENT 0x0002000000000000ULL +#define CAP_POLL_EVENT CAPRIGHT(1, 0x0000000000000020ULL) +#define CAP_POST_EVENT CAPRIGHT(1, 0x0000000000000040ULL) /* Strange and powerful rights that should not be given lightly. */ -#define CAP_IOCTL 0x0004000000000000ULL -#define CAP_TTYHOOK 0x0008000000000000ULL +#define CAP_IOCTL CAPRIGHT(1, 0x0000000000000080ULL) +#define CAP_TTYHOOK CAPRIGHT(1, 0x0000000000000100ULL) /* Process management via process descriptors. */ -#define CAP_PDGETPID 0x0010000000000000ULL -#define CAP_PDWAIT 0x0020000000000000ULL -#define CAP_PDKILL 0x0040000000000000ULL +#define CAP_PDGETPID CAPRIGHT(1, 0x0000000000000200ULL) +#define CAP_PDWAIT CAPRIGHT(1, 0x0000000000000400ULL) +#define CAP_PDKILL CAPRIGHT(1, 0x0000000000000800ULL) /* * Rights that allow to use bindat(2) and connectat(2) syscalls on a * directory descriptor. */ -#define CAP_BINDAT 0x0400000000000000ULL -#define CAP_CONNECTAT 0x0800000000000000ULL - -/* The mask of all valid method rights. */ -#define CAP_MASK_VALID 0x0fffffffffffffffULL -#define CAP_ALL CAP_MASK_VALID - -/* Available bits. */ -#define CAP_UNUSED3 0x1000000000000000ULL -#define CAP_UNUSED2 0x2000000000000000ULL -#define CAP_UNUSED1 0x4000000000000000ULL -#define CAP_UNUSED0 0x8000000000000000ULL - -/* - * The following defines are provided for backward API compatibility and - * should not be used in new code. - */ -#define CAP_MAPEXEC CAP_MMAP_X -#define CAP_DELETE CAP_UNLINKAT -#define CAP_MKDIR CAP_MKDIRAT -#define CAP_RMDIR CAP_UNLINKAT -#define CAP_MKFIFO CAP_MKFIFOAT -#define CAP_MKNOD CAP_MKNODAT -#define CAP_SOCK_ALL (CAP_SOCK_CLIENT | CAP_SOCK_SERVER) +#define CAP_BINDAT CAPRIGHT(1, 0x0000000000001000ULL) +#define CAP_CONNECTAT CAPRIGHT(1, 0x0000000000002000ULL) + +/* All used bits for index 1. */ +#define CAP_ALL1 CAPRIGHT(1, 0x0000000000003FFFULL) + +/* Available bits for index 1. */ +#define CAP_UNUSED1_15 CAPRIGHT(1, 0x0000000000004000ULL) +/* ... */ +#define CAP_UNUSED1_57 CAPRIGHT(1, 0x0100000000000000ULL) + +#define CAP_ALL(rights) do { \ + (rights)->cr_rights[0] = \ + ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAP_ALL0; \ + (rights)->cr_rights[1] = CAP_ALL1; \ +} while (0) + +#define CAP_NONE(rights) do { \ + (rights)->cr_rights[0] = \ + ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAPRIGHT(0, 0ULL); \ + (rights)->cr_rights[1] = CAPRIGHT(1, 0ULL); \ +} while (0) + +#define CAPRVER(right) ((int)((right) >> 62)) +#define CAPVER(rights) CAPRVER((rights)->cr_rights[0]) +#define CAPARSIZE(rights) (CAPVER(rights) + 2) +#define CAPIDXBIT(right) ((int)(((right) >> 57) & 0x1F)) /* * Allowed fcntl(2) commands. @@ -230,6 +252,27 @@ #define CAP_IOCTLS_ALL SSIZE_MAX +#define cap_rights_init(...) \ + __cap_rights_init(CAP_RIGHTS_VERSION, __VA_ARGS__, 0ULL) +cap_rights_t *__cap_rights_init(int version, cap_rights_t *rights, ...); + +#define cap_rights_set(rights, ...) \ + __cap_rights_set((rights), __VA_ARGS__, 0ULL) +void __cap_rights_set(cap_rights_t *rights, ...); + +#define cap_rights_clear(rights, ...) \ + __cap_rights_clear((rights), __VA_ARGS__, 0ULL) +void __cap_rights_clear(cap_rights_t *rights, ...); + +#define cap_rights_is_set(rights, ...) \ + __cap_rights_is_set((rights), __VA_ARGS__, 0ULL) +bool __cap_rights_is_set(const cap_rights_t *rights, ...); + +bool cap_rights_is_valid(const cap_rights_t *rights); +void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src); +void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src); +bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little); + #ifdef _KERNEL #include @@ -241,17 +284,17 @@ struct filedesc; /* * Test whether a capability grants the requested rights. */ -int cap_check(cap_rights_t have, cap_rights_t need); +int cap_check(const cap_rights_t *havep, const cap_rights_t *needp); /* * Convert capability rights into VM access flags. */ -u_char cap_rights_to_vmprot(cap_rights_t have); +u_char cap_rights_to_vmprot(cap_rights_t *havep); /* * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to * extract the rights from a capability. */ -cap_rights_t cap_rights(struct filedesc *fdp, int fd); +cap_rights_t *cap_rights(struct filedesc *fdp, int fd); int cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd); int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); @@ -259,18 +302,11 @@ int cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); #else /* !_KERNEL */ __BEGIN_DECLS -#include - /* * cap_enter(): Cause the process to enter capability mode, which will * prevent it from directly accessing global namespaces. System calls will * be limited to process-local, process-inherited, or file descriptor * operations. If already in capability mode, a no-op. - * - * Currently, process-inherited operations are not properly handled -- in - * particular, we're interested in things like waitpid(2), kill(2), etc, - * being properly constrained. One possible solution is to introduce process - * descriptors. */ int cap_enter(void); @@ -288,11 +324,12 @@ int cap_getmode(u_int *modep); /* * Limits capability rights for the given descriptor (CAP_*). */ -int cap_rights_limit(int fd, cap_rights_t rights); +int cap_rights_limit(int fd, const cap_rights_t *rights); /* - * Returns bitmask of capability rights for the given descriptor. + * Returns capability rights for the given descriptor. */ -int cap_rights_get(int fd, cap_rights_t *rightsp); +#define cap_rights_get(fd, rights) __cap_rights_get(CAP_RIGHTS_VERSION, (fd), (rights)) +int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); /* * Limits allowed ioctls for the given descriptor. */ @@ -312,10 +349,6 @@ int cap_fcntls_limit(int fd, uint32_t fcntlrights); */ int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); -/* For backward compatibility. */ -int cap_new(int fd, cap_rights_t rights); -#define cap_getrights(fd, rightsp) cap_rights_get((fd), (rightsp)) - __END_DECLS #endif /* !_KERNEL */ diff --git a/sys/sys/caprights.h b/sys/sys/caprights.h new file mode 100644 index 0000000..eb8e454 --- /dev/null +++ b/sys/sys/caprights.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2013 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_CAPRIGHTS_H_ +#define _SYS_CAPRIGHTS_H_ + +/* + * The top two bits in the first element of the cr_rights[] array contain + * total number of elements in the array - 2. This means if those two bits are + * equal to 0, we have 2 array elements. + * The top two bits in all remaining array elements should be 0. + * The next five bits contain array index. Only one bit is used and bit position + * in this five-bits range defines array index. This means there can be at most + * five array elements. + */ +#define CAP_RIGHTS_VERSION_00 0 +/* +#define CAP_RIGHTS_VERSION_01 1 +#define CAP_RIGHTS_VERSION_02 2 +#define CAP_RIGHTS_VERSION_03 3 +*/ +#define CAP_RIGHTS_VERSION CAP_RIGHTS_VERSION_00 + +struct cap_rights { + uint64_t cr_rights[CAP_RIGHTS_VERSION + 2]; +}; + +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +typedef struct cap_rights cap_rights_t; +#endif + +#endif /* !_SYS_CAPRIGHTS_H_ */ diff --git a/sys/sys/file.h b/sys/sys/file.h index 72c512f..7b373f0 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -217,12 +217,12 @@ extern int maxfiles; /* kernel limit on number of open files */ extern int maxfilesperproc; /* per process limit on number of open files */ extern volatile int openfiles; /* actual number of open files */ -int fget(struct thread *td, int fd, cap_rights_t rights, struct file **fpp); -int fget_mmap(struct thread *td, int fd, cap_rights_t rights, +int fget(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); +int fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, u_char *maxprotp, struct file **fpp); -int fget_read(struct thread *td, int fd, cap_rights_t rights, +int fget_read(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); -int fget_write(struct thread *td, int fd, cap_rights_t rights, +int fget_write(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp); int _fdrop(struct file *fp, struct thread *td); @@ -248,17 +248,18 @@ fo_sendfile_t vn_sendfile; fo_seek_t vn_seek; void finit(struct file *, u_int, short, void *, struct fileops *); -int fgetvp(struct thread *td, int fd, cap_rights_t rights, struct vnode **vpp); -int fgetvp_exec(struct thread *td, int fd, cap_rights_t rights, +int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetvp_rights(struct thread *td, int fd, cap_rights_t need, +int fgetvp_exec(struct thread *td, int fd, cap_rights_t *rightsp, + struct vnode **vpp); +int fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, struct filecaps *havecaps, struct vnode **vpp); -int fgetvp_read(struct thread *td, int fd, cap_rights_t rights, +int fgetvp_read(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetvp_write(struct thread *td, int fd, cap_rights_t rights, +int fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, struct vnode **vpp); -int fgetsock(struct thread *td, int fd, cap_rights_t rights, +int fgetsock(struct thread *td, int fd, cap_rights_t *rightsp, struct socket **spp, u_int *fflagp); void fputsock(struct socket *sp); diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 9f73915..968ceff 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -33,6 +33,7 @@ #ifndef _SYS_FILEDESC_H_ #define _SYS_FILEDESC_H_ +#include #include #include #include @@ -108,10 +109,6 @@ struct filedesc_to_leader { #ifdef _KERNEL -#include /* CTASSERT() */ - -CTASSERT(sizeof(cap_rights_t) == sizeof(uint64_t)); - /* Flags for do_dup() */ #define DUP_FIXED 0x1 /* Force fixed allocation. */ #define DUP_FCNTL 0x2 /* fcntl()-style errors. */ @@ -163,13 +160,13 @@ struct filedesc *fdshare(struct filedesc *fdp); struct filedesc_to_leader * filedesc_to_leader_alloc(struct filedesc_to_leader *old, struct filedesc *fdp, struct proc *leader); -int getvnode(struct filedesc *fdp, int fd, cap_rights_t rights, +int getvnode(struct filedesc *fdp, int fd, cap_rights_t *rightsp, struct file **fpp); void mountcheckdirs(struct vnode *olddp, struct vnode *newdp); void setugidsafety(struct thread *td); /* Return a referenced file from an unlocked descriptor. */ -int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t needrights, +int fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, int needfcntl, struct file **fpp, cap_rights_t *haverightsp); /* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */ diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index b3e6be8..e9cfa6e 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -33,6 +33,8 @@ #ifndef _SYS_KTRACE_H_ #define _SYS_KTRACE_H_ +#include + /* * operations to ktrace system call (KTROP(op)) */ @@ -264,7 +266,10 @@ void ktrprocexit(struct thread *); void ktrprocfork(struct proc *, struct proc *); void ktruserret(struct thread *); void ktrstruct(const char *, void *, size_t); -void ktrcapfail(enum ktr_cap_fail_type, cap_rights_t, cap_rights_t); +void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *, + const cap_rights_t *); +#define ktrcaprights(s) \ + ktrstruct("caprights", (s), sizeof(cap_rights_t)) #define ktrsockaddr(s) \ ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len) #define ktrstat(s) \ diff --git a/sys/sys/namei.h b/sys/sys/namei.h index a9992f4..f1b1223 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -33,6 +33,7 @@ #ifndef _SYS_NAMEI_H_ #define _SYS_NAMEI_H_ +#include #include #include #include @@ -158,32 +159,14 @@ struct nameidata { NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, 0, td) #define NDINIT_AT(ndp, op, flags, segflg, namep, dirfd, td) \ NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, 0, td) -#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rights, td) \ - NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rights, td) +#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rightsp, td) \ + NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp, td) #define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp, td) \ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, 0, td) -static __inline void -NDINIT_ALL(struct nameidata *ndp, - u_long op, u_long flags, - enum uio_seg segflg, - const char *namep, - int dirfd, - struct vnode *startdir, - cap_rights_t rights, - struct thread *td) -{ - ndp->ni_cnd.cn_nameiop = op; - ndp->ni_cnd.cn_flags = flags; - ndp->ni_segflg = segflg; - ndp->ni_dirp = namep; - ndp->ni_dirfd = dirfd; - ndp->ni_startdir = startdir; - ndp->ni_strictrelative = 0; - ndp->ni_rightsneeded = rights; - filecaps_init(&ndp->ni_filecaps); - ndp->ni_cnd.cn_thread = td; -} +void NDINIT_ALL(struct nameidata *ndp, u_long op, u_long flags, + enum uio_seg segflg, const char *namep, int dirfd, struct vnode *startdir, + cap_rights_t *rightsp, struct thread *td); #define NDF_NO_DVP_RELE 0x00000001 #define NDF_NO_DVP_UNLOCK 0x00000002 diff --git a/sys/sys/procdesc.h b/sys/sys/procdesc.h index cc8b716..4d77a05 100644 --- a/sys/sys/procdesc.h +++ b/sys/sys/procdesc.h @@ -92,8 +92,8 @@ struct procdesc { * In-kernel interfaces to process descriptors. */ int procdesc_exit(struct proc *); -int procdesc_find(struct thread *, int fd, cap_rights_t, struct proc **); -int kern_pdgetpid(struct thread *, int fd, cap_rights_t, pid_t *pidp); +int procdesc_find(struct thread *, int fd, cap_rights_t *, struct proc **); +int kern_pdgetpid(struct thread *, int fd, cap_rights_t *, pid_t *pidp); void procdesc_new(struct proc *, int); void procdesc_finit(struct procdesc *, struct file *); pid_t procdesc_pid(struct file *); diff --git a/sys/sys/types.h b/sys/sys/types.h index cc0bca8..03eaa60 100644 --- a/sys/sys/types.h +++ b/sys/sys/types.h @@ -88,8 +88,6 @@ typedef __blkcnt_t blkcnt_t; #define _BLKCNT_T_DECLARED #endif -typedef __cap_rights_t cap_rights_t; - #ifndef _CLOCK_T_DECLARED typedef __clock_t clock_t; #define _CLOCK_T_DECLARED @@ -234,6 +232,13 @@ typedef __useconds_t useconds_t; /* microseconds (unsigned) */ #define _USECONDS_T_DECLARED #endif +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +struct cap_rights; + +typedef struct cap_rights cap_rights_t; +#endif + typedef __vm_offset_t vm_offset_t; typedef __vm_ooffset_t vm_ooffset_t; typedef __vm_paddr_t vm_paddr_t; diff --git a/sys/sys/user.h b/sys/sys/user.h index 9389e55..349003d 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -61,6 +61,7 @@ #ifndef _SYS_SOCKET_VAR_H_ #include #endif +#include /* * KERN_PROC subtype ops return arrays of selected proc structure entries: @@ -318,7 +319,7 @@ struct kinfo_ofile { }; #if defined(__amd64__) || defined(__i386__) -#define KINFO_FILE_SIZE 1392 +#define KINFO_FILE_SIZE 1424 #endif struct kinfo_file { @@ -389,6 +390,7 @@ struct kinfo_file { uint16_t kf_pad1; /* Round to 32 bit alignment. */ int _kf_ispare0; /* Space for more stuff. */ cap_rights_t kf_cap_rights; /* Capability rights. */ + uint64_t _kf_cap_spare[3]; /* Space for future cap_rights_t. */ int _kf_ispare[4]; /* Space for more stuff. */ /* Truncated before copyout in sysctl */ char kf_path[PATH_MAX]; /* Path to file, if any. */ diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 3063ade..19e880c 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -2709,6 +2709,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) long blkcnt, blksize; struct filedesc *fdp; struct file *fp, *vfp; + cap_rights_t rights; int filetype, error; static struct fileops *origops, bufferedops; @@ -2718,8 +2719,8 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) return (error); if (cmd.version != FFS_CMD_VERSION) return (ERPCMISMATCH); - if ((error = getvnode(td->td_proc->p_fd, cmd.handle, CAP_FSCK, - &fp)) != 0) + if ((error = getvnode(td->td_proc->p_fd, cmd.handle, + cap_rights_init(&rights, CAP_FSCK), &fp)) != 0) return (error); vp = fp->f_data; if (vp->v_type != VREG && vp->v_type != VDIR) { @@ -3033,7 +3034,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) } #endif /* DEBUG */ if ((error = getvnode(td->td_proc->p_fd, cmd.value, - CAP_FSCK, &vfp)) != 0) + cap_rights_init(&rights, CAP_FSCK), &vfp)) != 0) break; if (vfp->f_vnode->v_type != VCHR) { fdrop(vfp, td); diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 53a7be5..77f64f4 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -311,17 +311,17 @@ sys_mmap(td, uap) * rights, but also return the maximum rights to be combined * with maxprot later. */ - rights = CAP_MMAP; + cap_rights_init(&rights, CAP_MMAP); if (prot & PROT_READ) - rights |= CAP_MMAP_R; + cap_rights_set(&rights, CAP_MMAP_R); if ((flags & MAP_SHARED) != 0) { if (prot & PROT_WRITE) - rights |= CAP_MMAP_W; + cap_rights_set(&rights, CAP_MMAP_W); } if (prot & PROT_EXEC) - rights |= CAP_MMAP_X; - if ((error = fget_mmap(td, uap->fd, rights, &cap_maxprot, - &fp)) != 0) + cap_rights_set(&rights, CAP_MMAP_X); + error = fget_mmap(td, uap->fd, &rights, &cap_maxprot, &fp); + if (error != 0) goto done; if (fp->f_type == DTYPE_SHM) { handle = fp->f_data; -- cgit v1.1 From d1a65cb7ef2fa0cefbf00f16367a7ba99edc0457 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 00:11:59 +0000 Subject: Regenerate after r255219. Sponsored by: The FreeBSD Foundation --- sys/compat/freebsd32/freebsd32_proto.h | 17 +---- sys/compat/freebsd32/freebsd32_syscall.h | 9 +-- sys/compat/freebsd32/freebsd32_syscalls.c | 9 +-- sys/compat/freebsd32/freebsd32_sysent.c | 9 +-- sys/compat/freebsd32/freebsd32_systrace_args.c | 102 +++++-------------------- sys/kern/init_sysent.c | 6 +- sys/kern/syscalls.c | 6 +- sys/kern/systrace_args.c | 48 ++++-------- sys/sys/syscall.h | 6 +- sys/sys/syscall.mk | 5 +- sys/sys/sysproto.h | 19 ++--- 11 files changed, 65 insertions(+), 171 deletions(-) (limited to 'sys') diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index 363aad3..96b9b37 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -627,12 +627,6 @@ struct freebsd32_wait6_args { char wrusage_l_[PADL_(struct wrusage32 *)]; struct wrusage32 * wrusage; char wrusage_r_[PADR_(struct wrusage32 *)]; char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)]; }; -struct freebsd32_cap_rights_limit_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)]; - char rights1_l_[PADL_(uint32_t)]; uint32_t rights1; char rights1_r_[PADR_(uint32_t)]; - char rights2_l_[PADL_(uint32_t)]; uint32_t rights2; char rights2_r_[PADR_(uint32_t)]; -}; #else struct freebsd32_posix_fallocate_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -658,11 +652,6 @@ struct freebsd32_wait6_args { char wrusage_l_[PADL_(struct wrusage32 *)]; struct wrusage32 * wrusage; char wrusage_r_[PADR_(struct wrusage32 *)]; char info_l_[PADL_(siginfo_t *)]; siginfo_t * info; char info_r_[PADR_(siginfo_t *)]; }; -struct freebsd32_cap_rights_limit_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights1_l_[PADL_(uint32_t)]; uint32_t rights1; char rights1_r_[PADR_(uint32_t)]; - char rights2_l_[PADL_(uint32_t)]; uint32_t rights2; char rights2_r_[PADR_(uint32_t)]; -}; #endif struct freebsd32_cap_ioctls_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -795,12 +784,10 @@ int freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *); int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *); int freebsd32_posix_fadvise(struct thread *, struct freebsd32_posix_fadvise_args *); int freebsd32_wait6(struct thread *, struct freebsd32_wait6_args *); -int freebsd32_cap_rights_limit(struct thread *, struct freebsd32_cap_rights_limit_args *); #else int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *); int freebsd32_posix_fadvise(struct thread *, struct freebsd32_posix_fadvise_args *); int freebsd32_wait6(struct thread *, struct freebsd32_wait6_args *); -int freebsd32_cap_rights_limit(struct thread *, struct freebsd32_cap_rights_limit_args *); #endif int freebsd32_cap_ioctls_limit(struct thread *, struct freebsd32_cap_ioctls_limit_args *); int freebsd32_cap_ioctls_get(struct thread *, struct freebsd32_cap_ioctls_get_args *); @@ -1199,11 +1186,9 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_ #define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_posix_fadvise AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_wait6 AUE_WAIT6 -#define FREEBSD32_SYS_AUE_freebsd32_cap_rights_limit AUE_CAP_RIGHTS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_posix_fadvise AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_wait6 AUE_WAIT6 -#define FREEBSD32_SYS_AUE_freebsd32_cap_rights_limit AUE_CAP_RIGHTS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_cap_ioctls_limit AUE_CAP_IOCTLS_LIMIT #define FREEBSD32_SYS_AUE_freebsd32_cap_ioctls_get AUE_CAP_IOCTLS_GET #define FREEBSD32_SYS_AUE_freebsd32_aio_mlock AUE_NULL diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 8568201..dbbee5b 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #define FREEBSD32_SYS_syscall 0 @@ -420,8 +420,8 @@ #define FREEBSD32_SYS_freebsd32_msgctl 511 #define FREEBSD32_SYS_freebsd32_shmctl 512 #define FREEBSD32_SYS_lpathconf 513 -#define FREEBSD32_SYS_cap_new 514 -#define FREEBSD32_SYS_cap_rights_get 515 + /* 514 is obsolete cap_new */ +#define FREEBSD32_SYS___cap_rights_get 515 #define FREEBSD32_SYS_cap_enter 516 #define FREEBSD32_SYS_cap_getmode 517 #define FREEBSD32_SYS_pdfork 518 @@ -438,11 +438,10 @@ #define FREEBSD32_SYS_freebsd32_posix_fallocate 530 #define FREEBSD32_SYS_freebsd32_posix_fadvise 531 #define FREEBSD32_SYS_freebsd32_wait6 532 -#define FREEBSD32_SYS_freebsd32_cap_rights_limit 533 #define FREEBSD32_SYS_freebsd32_posix_fallocate 530 #define FREEBSD32_SYS_freebsd32_posix_fadvise 531 #define FREEBSD32_SYS_freebsd32_wait6 532 -#define FREEBSD32_SYS_freebsd32_cap_rights_limit 533 +#define FREEBSD32_SYS_cap_rights_limit 533 #define FREEBSD32_SYS_freebsd32_cap_ioctls_limit 534 #define FREEBSD32_SYS_freebsd32_cap_ioctls_get 535 #define FREEBSD32_SYS_cap_fcntls_limit 536 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 734b9fd..3f6cbfc 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ const char *freebsd32_syscallnames[] = { @@ -537,8 +537,8 @@ const char *freebsd32_syscallnames[] = { "freebsd32_msgctl", /* 511 = freebsd32_msgctl */ "freebsd32_shmctl", /* 512 = freebsd32_shmctl */ "lpathconf", /* 513 = lpathconf */ - "cap_new", /* 514 = cap_new */ - "cap_rights_get", /* 515 = cap_rights_get */ + "obs_cap_new", /* 514 = obsolete cap_new */ + "__cap_rights_get", /* 515 = __cap_rights_get */ "cap_enter", /* 516 = cap_enter */ "cap_getmode", /* 517 = cap_getmode */ "pdfork", /* 518 = pdfork */ @@ -557,13 +557,12 @@ const char *freebsd32_syscallnames[] = { "freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */ "freebsd32_posix_fadvise", /* 531 = freebsd32_posix_fadvise */ "freebsd32_wait6", /* 532 = freebsd32_wait6 */ - "freebsd32_cap_rights_limit", /* 533 = freebsd32_cap_rights_limit */ #else "freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */ "freebsd32_posix_fadvise", /* 531 = freebsd32_posix_fadvise */ "freebsd32_wait6", /* 532 = freebsd32_wait6 */ - "freebsd32_cap_rights_limit", /* 533 = freebsd32_cap_rights_limit */ #endif + "cap_rights_limit", /* 533 = cap_rights_limit */ "freebsd32_cap_ioctls_limit", /* 534 = freebsd32_cap_ioctls_limit */ "freebsd32_cap_ioctls_get", /* 535 = freebsd32_cap_ioctls_get */ "cap_fcntls_limit", /* 536 = cap_fcntls_limit */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 1c82a00..00b4153 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 254491 2013-08-18 13:37:54Z pjd + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #include "opt_compat.h" @@ -574,8 +574,8 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 511 = freebsd32_msgctl */ { AS(freebsd32_shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 512 = freebsd32_shmctl */ { AS(lpathconf_args), (sy_call_t *)sys_lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 513 = lpathconf */ - { AS(cap_new_args), (sy_call_t *)sys_cap_new, AUE_CAP_NEW, NULL, 0, 0, 0, SY_THR_STATIC }, /* 514 = cap_new */ - { AS(cap_rights_get_args), (sy_call_t *)sys_cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = cap_rights_get */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 514 = obsolete cap_new */ + { AS(__cap_rights_get_args), (sy_call_t *)sys___cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = __cap_rights_get */ { 0, (sy_call_t *)sys_cap_enter, AUE_CAP_ENTER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 516 = cap_enter */ { AS(cap_getmode_args), (sy_call_t *)sys_cap_getmode, AUE_CAP_GETMODE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 517 = cap_getmode */ { AS(pdfork_args), (sy_call_t *)sys_pdfork, AUE_PDFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 518 = pdfork */ @@ -594,13 +594,12 @@ struct sysent freebsd32_sysent[] = { { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ - { AS(freebsd32_cap_rights_limit_args), (sy_call_t *)freebsd32_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_cap_rights_limit */ #else { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */ { AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */ - { AS(freebsd32_cap_rights_limit_args), (sy_call_t *)freebsd32_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_cap_rights_limit */ #endif + { AS(cap_rights_limit_args), (sy_call_t *)sys_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = cap_rights_limit */ { AS(freebsd32_cap_ioctls_limit_args), (sy_call_t *)freebsd32_cap_ioctls_limit, AUE_CAP_IOCTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = freebsd32_cap_ioctls_limit */ { AS(freebsd32_cap_ioctls_get_args), (sy_call_t *)freebsd32_cap_ioctls_get, AUE_CAP_IOCTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 535 = freebsd32_cap_ioctls_get */ { AS(cap_fcntls_limit_args), (sy_call_t *)sys_cap_fcntls_limit, AUE_CAP_FCNTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 536 = cap_fcntls_limit */ diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index 94ff863..7146ee4 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -2990,20 +2990,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } - /* cap_new */ - case 514: { - struct cap_new_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ - *n_args = 2; - break; - } - /* cap_rights_get */ + /* __cap_rights_get */ case 515: { - struct cap_rights_get_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */ - *n_args = 2; + struct __cap_rights_get_args *p = params; + iarg[0] = p->version; /* int */ + iarg[1] = p->fd; /* int */ + uarg[2] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 3; break; } /* cap_enter */ @@ -3159,16 +3152,6 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 8; break; } - /* freebsd32_cap_rights_limit */ - case 533: { - struct freebsd32_cap_rights_limit_args *p = params; - iarg[0] = p->fd; /* int */ - iarg[1] = p->pad; /* int */ - uarg[2] = p->rights1; /* uint32_t */ - uarg[3] = p->rights2; /* uint32_t */ - *n_args = 4; - break; - } #else /* freebsd32_posix_fallocate */ case 530: { @@ -3206,16 +3189,15 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 7; break; } - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: { - struct freebsd32_cap_rights_limit_args *p = params; + struct cap_rights_limit_args *p = params; iarg[0] = p->fd; /* int */ - uarg[1] = p->rights1; /* uint32_t */ - uarg[2] = p->rights2; /* uint32_t */ - *n_args = 3; + uarg[1] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 2; break; } -#endif /* freebsd32_cap_ioctls_limit */ case 534: { struct freebsd32_cap_ioctls_limit_args *p = params; @@ -8277,27 +8259,17 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cap_new */ - case 514: + /* __cap_rights_get */ + case 515: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint64_t"; - break; - default: - break; - }; - break; - /* cap_rights_get */ - case 515: - switch(ndx) { - case 0: p = "int"; break; - case 1: - p = "uint64_t *"; + case 2: + p = "cap_rights_t *"; break; default: break; @@ -8583,25 +8555,6 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* freebsd32_cap_rights_limit */ - case 533: - switch(ndx) { - case 0: - p = "int"; - break; - case 1: - p = "int"; - break; - case 2: - p = "uint32_t"; - break; - case 3: - p = "uint32_t"; - break; - default: - break; - }; - break; #else /* freebsd32_posix_fallocate */ case 530: @@ -8678,23 +8631,20 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint32_t"; - break; - case 2: - p = "uint32_t"; + p = "cap_rights_t *"; break; default: break; }; break; -#endif /* freebsd32_cap_ioctls_limit */ case 534: switch(ndx) { @@ -10567,12 +10517,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* cap_new */ - case 514: - if (ndx == 0 || ndx == 1) - p = "int"; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: if (ndx == 0 || ndx == 1) p = "int"; @@ -10655,11 +10600,6 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* freebsd32_cap_rights_limit */ - case 533: - if (ndx == 0 || ndx == 1) - p = "int"; - break; #else /* freebsd32_posix_fallocate */ case 530: @@ -10676,12 +10616,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* freebsd32_cap_rights_limit */ +#endif + /* cap_rights_limit */ case 533: if (ndx == 0 || ndx == 1) p = "int"; break; -#endif /* freebsd32_cap_ioctls_limit */ case 534: if (ndx == 0 || ndx == 1) diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 0fcb9df..64b0201 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #include "opt_compat.h" @@ -548,8 +548,8 @@ struct sysent sysent[] = { { AS(msgctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 511 = msgctl */ { AS(shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 512 = shmctl */ { AS(lpathconf_args), (sy_call_t *)sys_lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 513 = lpathconf */ - { AS(cap_new_args), (sy_call_t *)sys_cap_new, AUE_CAP_NEW, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 514 = cap_new */ - { AS(cap_rights_get_args), (sy_call_t *)sys_cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 515 = cap_rights_get */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 514 = obsolete cap_new */ + { AS(__cap_rights_get_args), (sy_call_t *)sys___cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 515 = __cap_rights_get */ { 0, (sy_call_t *)sys_cap_enter, AUE_CAP_ENTER, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 516 = cap_enter */ { AS(cap_getmode_args), (sy_call_t *)sys_cap_getmode, AUE_CAP_GETMODE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 517 = cap_getmode */ { AS(pdfork_args), (sy_call_t *)sys_pdfork, AUE_PDFORK, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 518 = pdfork */ diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 17f5448..f330879 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ const char *syscallnames[] = { @@ -521,8 +521,8 @@ const char *syscallnames[] = { "msgctl", /* 511 = msgctl */ "shmctl", /* 512 = shmctl */ "lpathconf", /* 513 = lpathconf */ - "cap_new", /* 514 = cap_new */ - "cap_rights_get", /* 515 = cap_rights_get */ + "obs_cap_new", /* 514 = obsolete cap_new */ + "__cap_rights_get", /* 515 = __cap_rights_get */ "cap_enter", /* 516 = cap_enter */ "cap_getmode", /* 517 = cap_getmode */ "pdfork", /* 518 = pdfork */ diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index 59e046b..0a6bae4 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3126,20 +3126,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } - /* cap_new */ - case 514: { - struct cap_new_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ - *n_args = 2; - break; - } - /* cap_rights_get */ + /* __cap_rights_get */ case 515: { - struct cap_rights_get_args *p = params; - iarg[0] = p->fd; /* int */ - uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */ - *n_args = 2; + struct __cap_rights_get_args *p = params; + iarg[0] = p->version; /* int */ + iarg[1] = p->fd; /* int */ + uarg[2] = (intptr_t) p->rightsp; /* cap_rights_t * */ + *n_args = 3; break; } /* cap_enter */ @@ -3290,7 +3283,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) case 533: { struct cap_rights_limit_args *p = params; iarg[0] = p->fd; /* int */ - uarg[1] = p->rights; /* uint64_t */ + uarg[1] = (intptr_t) p->rightsp; /* cap_rights_t * */ *n_args = 2; break; } @@ -8561,27 +8554,17 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; - /* cap_new */ - case 514: + /* __cap_rights_get */ + case 515: switch(ndx) { case 0: p = "int"; break; case 1: - p = "uint64_t"; - break; - default: - break; - }; - break; - /* cap_rights_get */ - case 515: - switch(ndx) { - case 0: p = "int"; break; - case 1: - p = "uint64_t *"; + case 2: + p = "cap_rights_t *"; break; default: break; @@ -8849,7 +8832,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "int"; break; case 1: - p = "uint64_t"; + p = "cap_rights_t *"; break; default: break; @@ -10818,12 +10801,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; - /* cap_new */ - case 514: - if (ndx == 0 || ndx == 1) - p = "int"; - break; - /* cap_rights_get */ + /* __cap_rights_get */ case 515: if (ndx == 0 || ndx == 1) p = "int"; diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index b321416..ad3c73a 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #define SYS_syscall 0 @@ -434,8 +434,8 @@ #define SYS_msgctl 511 #define SYS_shmctl 512 #define SYS_lpathconf 513 -#define SYS_cap_new 514 -#define SYS_cap_rights_get 515 + /* 514 is obsolete cap_new */ +#define SYS___cap_rights_get 515 #define SYS_cap_enter 516 #define SYS_cap_getmode 517 #define SYS_pdfork 518 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index df7d19f..eaf7378 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius +# created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd MIASM = \ syscall.o \ exit.o \ @@ -383,8 +383,7 @@ MIASM = \ msgctl.o \ shmctl.o \ lpathconf.o \ - cap_new.o \ - cap_rights_get.o \ + __cap_rights_get.o \ cap_enter.o \ cap_getmode.o \ pdfork.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6a54152..5f8a217 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 251526 2013-06-08 13:27:57Z glebius + * created from FreeBSD: head/sys/kern/syscalls.master 255219 2013-09-05 00:09:56Z pjd */ #ifndef _SYS_SYSPROTO_H_ @@ -1672,13 +1672,10 @@ struct lpathconf_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char name_l_[PADL_(int)]; int name; char name_r_[PADR_(int)]; }; -struct cap_new_args { +struct __cap_rights_get_args { + char version_l_[PADL_(int)]; int version; char version_r_[PADR_(int)]; char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights_l_[PADL_(uint64_t)]; uint64_t rights; char rights_r_[PADR_(uint64_t)]; -}; -struct cap_rights_get_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rightsp_l_[PADL_(uint64_t *)]; uint64_t * rightsp; char rightsp_r_[PADR_(uint64_t *)]; + char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)]; }; struct cap_enter_args { register_t dummy; @@ -1764,7 +1761,7 @@ struct wait6_args { }; struct cap_rights_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char rights_l_[PADL_(uint64_t)]; uint64_t rights; char rights_r_[PADR_(uint64_t)]; + char rightsp_l_[PADL_(cap_rights_t *)]; cap_rights_t * rightsp; char rightsp_r_[PADR_(cap_rights_t *)]; }; struct cap_ioctls_limit_args { char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; @@ -2179,8 +2176,7 @@ int sys___semctl(struct thread *, struct __semctl_args *); int sys_msgctl(struct thread *, struct msgctl_args *); int sys_shmctl(struct thread *, struct shmctl_args *); int sys_lpathconf(struct thread *, struct lpathconf_args *); -int sys_cap_new(struct thread *, struct cap_new_args *); -int sys_cap_rights_get(struct thread *, struct cap_rights_get_args *); +int sys___cap_rights_get(struct thread *, struct __cap_rights_get_args *); int sys_cap_enter(struct thread *, struct cap_enter_args *); int sys_cap_getmode(struct thread *, struct cap_getmode_args *); int sys_pdfork(struct thread *, struct pdfork_args *); @@ -2886,8 +2882,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_msgctl AUE_MSGCTL #define SYS_AUE_shmctl AUE_SHMCTL #define SYS_AUE_lpathconf AUE_LPATHCONF -#define SYS_AUE_cap_new AUE_CAP_NEW -#define SYS_AUE_cap_rights_get AUE_CAP_RIGHTS_GET +#define SYS_AUE___cap_rights_get AUE_CAP_RIGHTS_GET #define SYS_AUE_cap_enter AUE_CAP_ENTER #define SYS_AUE_cap_getmode AUE_CAP_GETMODE #define SYS_AUE_pdfork AUE_PDFORK -- cgit v1.1 From 36e3a50584a7948b7e90616632ffe89dcc07a5a4 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 00:17:38 +0000 Subject: Style fixes. Most fixes are about not treating integers and pointers as booleans. --- sys/kern/uipc_syscalls.c | 302 +++++++++++++++++++++-------------------------- 1 file changed, 137 insertions(+), 165 deletions(-) (limited to 'sys') diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 7e25da8..8229390 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -220,16 +220,16 @@ sys_socket(td, uap) #ifdef MAC error = mac_socket_check_create(td->td_ucred, uap->domain, type, uap->protocol); - if (error) + if (error != 0) return (error); #endif error = falloc(td, &fp, &fd, oflag); - if (error) + if (error != 0) return (error); /* An extra reference on `fp' has been held for us by falloc(). */ error = socreate(uap->domain, &so, type, uap->protocol, td->td_ucred, td); - if (error) { + if (error != 0) { fdclose(td->td_proc->p_fd, fp, fd, td); } else { finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops); @@ -274,7 +274,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_BIND), &fp, NULL); - if (error) + if (error != 0) return (error); so = fp->f_data; #ifdef KTRACE @@ -374,7 +374,7 @@ accept1(td, s, uname, anamelen, flags) return (kern_accept4(td, s, NULL, NULL, flags, NULL)); error = copyin(anamelen, &namelen, sizeof (namelen)); - if (error) + if (error != 0) return (error); error = kern_accept4(td, s, &name, &namelen, flags, &fp); @@ -383,7 +383,7 @@ accept1(td, s, uname, anamelen, flags) * return a namelen of zero for older code which might * ignore the return value from accept. */ - if (error) { + if (error != 0) { (void) copyout(&namelen, anamelen, sizeof(*anamelen)); return (error); } @@ -399,7 +399,7 @@ accept1(td, s, uname, anamelen, flags) if (error == 0) error = copyout(&namelen, anamelen, sizeof(namelen)); - if (error) + if (error != 0) fdclose(td->td_proc->p_fd, fp, td->td_retval[0], td); fdrop(fp, td); free(name, M_SONAME); @@ -420,22 +420,20 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, struct filedesc *fdp; struct file *headfp, *nfp = NULL; struct sockaddr *sa = NULL; - int error; struct socket *head, *so; - int fd; cap_rights_t rights; u_int fflag; pid_t pgid; - int tmp; + int error, fd, tmp; - if (name) + if (name != NULL) *name = NULL; AUDIT_ARG_FD(s); fdp = td->td_proc->p_fd; error = getsock_cap(fdp, s, cap_rights_init(&rights, CAP_ACCEPT), &headfp, &fflag); - if (error) + if (error != 0) return (error); head = headfp->f_data; if ((head->so_options & SO_ACCEPTCONN) == 0) { @@ -448,7 +446,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, goto done; #endif error = falloc(td, &nfp, &fd, (flags & SOCK_CLOEXEC) ? O_CLOEXEC : 0); - if (error) + if (error != 0) goto done; ACCEPT_LOCK(); if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { @@ -463,7 +461,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, } error = msleep(&head->so_timeo, &accept_mtx, PSOCK | PCATCH, "accept", 0); - if (error) { + if (error != 0) { ACCEPT_UNLOCK(); goto noconnection; } @@ -522,7 +520,7 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, (void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td); sa = 0; error = soaccept(so, &sa); - if (error) { + if (error != 0) { /* * return a namelen of zero for older code which might * ignore the return value from accept. @@ -549,14 +547,13 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, sa = NULL; } noconnection: - if (sa) - free(sa, M_SONAME); + free(sa, M_SONAME); /* * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ - if (error) + if (error != 0) fdclose(fdp, nfp, fd, td); /* @@ -591,6 +588,7 @@ sys_accept4(td, uap) struct thread *td; struct accept4_args *uap; { + if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) return (EINVAL); @@ -636,14 +634,13 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) struct socket *so; struct file *fp; cap_rights_t rights; - int error; - int interrupted = 0; + int error, interrupted = 0; AUDIT_ARG_FD(fd); AUDIT_ARG_SOCKADDR(td, dirfd, sa); error = getsock_cap(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_CONNECT), &fp, NULL); - if (error) + if (error != 0) return (error); so = fp->f_data; if (so->so_state & SS_ISCONNECTING) { @@ -656,14 +653,14 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) #endif #ifdef MAC error = mac_socket_check_connect(td->td_ucred, so, sa); - if (error) + if (error != 0) goto bad; #endif if (dirfd == AT_FDCWD) error = soconnect(so, sa, td); else error = soconnectat(dirfd, so, sa, td); - if (error) + if (error != 0) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EINPROGRESS; @@ -673,7 +670,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { error = msleep(&so->so_timeo, SOCK_MTX(so), PSOCK | PCATCH, "connec", 0); - if (error) { + if (error != 0) { if (error == EINTR || error == ERESTART) interrupted = 1; break; @@ -748,35 +745,35 @@ kern_socketpair(struct thread *td, int domain, int type, int protocol, /* We might want to have a separate check for socket pairs. */ error = mac_socket_check_create(td->td_ucred, domain, type, protocol); - if (error) + if (error != 0) return (error); #endif error = socreate(domain, &so1, type, protocol, td->td_ucred, td); - if (error) + if (error != 0) return (error); error = socreate(domain, &so2, type, protocol, td->td_ucred, td); - if (error) + if (error != 0) goto free1; /* On success extra reference to `fp1' and 'fp2' is set by falloc. */ error = falloc(td, &fp1, &fd, oflag); - if (error) + if (error != 0) goto free2; rsv[0] = fd; fp1->f_data = so1; /* so1 already has ref count */ error = falloc(td, &fp2, &fd, oflag); - if (error) + if (error != 0) goto free3; fp2->f_data = so2; /* so2 already has ref count */ rsv[1] = fd; error = soconnect2(so1, so2); - if (error) + if (error != 0) goto free4; if (type == SOCK_DGRAM) { /* * Datagram socket connection is asymmetric. */ error = soconnect2(so2, so1); - if (error) + if (error != 0) goto free4; } finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data, @@ -812,10 +809,10 @@ sys_socketpair(struct thread *td, struct socketpair_args *uap) error = kern_socketpair(td, uap->domain, uap->type, uap->protocol, sv); - if (error) + if (error != 0) return (error); error = copyout(sv, uap->rsv, 2 * sizeof(int)); - if (error) { + if (error != 0) { (void)kern_close(td, sv[0]); (void)kern_close(td, sv[1]); } @@ -840,7 +837,7 @@ sendit(td, s, mp, flags) if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); - if (error) { + if (error != 0) { to = NULL; goto bad; } @@ -860,7 +857,7 @@ sendit(td, s, mp, flags) } error = sockargs(&control, mp->msg_control, mp->msg_controllen, MT_CONTROL); - if (error) + if (error != 0) goto bad; #ifdef COMPAT_OLDSOCK if (mp->msg_flags == MSG_COMPAT) { @@ -880,8 +877,7 @@ sendit(td, s, mp, flags) error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE); bad: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); } @@ -898,12 +894,12 @@ kern_sendit(td, s, mp, flags, control, segflg) struct uio auio; struct iovec *iov; struct socket *so; - int i, error; - ssize_t len; cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int i, error; AUDIT_ARG_FD(s); cap_rights_init(&rights, CAP_SEND); @@ -912,7 +908,7 @@ kern_sendit(td, s, mp, flags, control, segflg) cap_rights_set(&rights, CAP_CONNECT); } error = getsock_cap(td->td_proc->p_fd, s, &rights, &fp, NULL); - if (error) + if (error != 0) return (error); so = (struct socket *)fp->f_data; @@ -924,11 +920,11 @@ kern_sendit(td, s, mp, flags, control, segflg) if (mp->msg_name != NULL) { error = mac_socket_check_connect(td->td_ucred, so, mp->msg_name); - if (error) + if (error != 0) goto bad; } error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto bad; #endif @@ -952,7 +948,7 @@ kern_sendit(td, s, mp, flags, control, segflg) #endif len = auio.uio_resid; error = sosend(so, mp->msg_name, &auio, 0, control, flags, td); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -991,7 +987,6 @@ sys_sendto(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = uap->to; msg.msg_namelen = uap->tolen; @@ -1003,8 +998,7 @@ sys_sendto(td, uap) #endif aiov.iov_base = uap->buf; aiov.iov_len = uap->len; - error = sendit(td, uap->s, &msg, uap->flags); - return (error); + return (sendit(td, uap->s, &msg, uap->flags)); } #ifdef COMPAT_OLDSOCK @@ -1020,7 +1014,6 @@ osend(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = 0; msg.msg_namelen = 0; @@ -1030,8 +1023,7 @@ osend(td, uap) aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = 0; - error = sendit(td, uap->s, &msg, uap->flags); - return (error); + return (sendit(td, uap->s, &msg, uap->flags)); } int @@ -1048,10 +1040,10 @@ osendmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_iov = iov; msg.msg_flags = MSG_COMPAT; @@ -1075,10 +1067,10 @@ sys_sendmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (msg)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_iov = iov; #ifdef COMPAT_OLDSOCK @@ -1099,9 +1091,6 @@ kern_recvit(td, s, mp, fromseg, controlp) { struct uio auio; struct iovec *iov; - int i; - ssize_t len; - int error; struct mbuf *m, *control = NULL; caddr_t ctlbuf; struct file *fp; @@ -1111,6 +1100,8 @@ kern_recvit(td, s, mp, fromseg, controlp) #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int error, i; if (controlp != NULL) *controlp = NULL; @@ -1118,13 +1109,13 @@ kern_recvit(td, s, mp, fromseg, controlp) AUDIT_ARG_FD(s); error = getsock_cap(td->td_proc->p_fd, s, cap_rights_init(&rights, CAP_RECV), &fp, NULL); - if (error) + if (error != 0) return (error); so = fp->f_data; #ifdef MAC error = mac_socket_check_receive(td->td_ucred, so); - if (error) { + if (error != 0) { fdrop(fp, td); return (error); } @@ -1152,7 +1143,7 @@ kern_recvit(td, s, mp, fromseg, controlp) error = soreceive(so, &fromsa, &auio, NULL, (mp->msg_control || controlp) ? &control : NULL, &mp->msg_flags); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -1165,7 +1156,7 @@ kern_recvit(td, s, mp, fromseg, controlp) ktrgenio(s, UIO_READ, ktruio, error); } #endif - if (error) + if (error != 0) goto out; td->td_retval[0] = len - auio.uio_resid; if (mp->msg_name) { @@ -1183,7 +1174,7 @@ kern_recvit(td, s, mp, fromseg, controlp) if (fromseg == UIO_USERSPACE) { error = copyout(fromsa, mp->msg_name, (unsigned)len); - if (error) + if (error != 0) goto out; } else bcopy(fromsa, mp->msg_name, len); @@ -1242,8 +1233,7 @@ out: if (fromsa && KTRPOINT(td, KTR_STRUCT)) ktrsockaddr(fromsa); #endif - if (fromsa) - free(fromsa, M_SONAME); + free(fromsa, M_SONAME); if (error == 0 && controlp != NULL) *controlp = control; @@ -1263,9 +1253,9 @@ recvit(td, s, mp, namelenp) int error; error = kern_recvit(td, s, mp, UIO_USERSPACE, NULL); - if (error) + if (error != 0) return (error); - if (namelenp) { + if (namelenp != NULL) { error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t)); #ifdef COMPAT_OLDSOCK if (mp->msg_flags & MSG_COMPAT) @@ -1294,7 +1284,7 @@ sys_recvfrom(td, uap) if (uap->fromlenaddr) { error = copyin(uap->fromlenaddr, &msg.msg_namelen, sizeof (msg.msg_namelen)); - if (error) + if (error != 0) goto done2; } else { msg.msg_namelen = 0; @@ -1308,7 +1298,7 @@ sys_recvfrom(td, uap) msg.msg_flags = uap->flags; error = recvit(td, uap->s, &msg, uap->fromlenaddr); done2: - return(error); + return (error); } #ifdef COMPAT_OLDSOCK @@ -1336,7 +1326,6 @@ orecv(td, uap) { struct msghdr msg; struct iovec aiov; - int error; msg.msg_name = 0; msg.msg_namelen = 0; @@ -1346,8 +1335,7 @@ orecv(td, uap) aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = uap->flags; - error = recvit(td, uap->s, &msg, NULL); - return (error); + return (recvit(td, uap->s, &msg, NULL)); } /* @@ -1369,10 +1357,10 @@ orecvmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_flags = uap->flags | MSG_COMPAT; msg.msg_iov = iov; @@ -1399,10 +1387,10 @@ sys_recvmsg(td, uap) int error; error = copyin(uap->msg, &msg, sizeof (msg)); - if (error) + if (error != 0) return (error); error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) return (error); msg.msg_flags = uap->flags; #ifdef COMPAT_OLDSOCK @@ -1471,11 +1459,11 @@ kern_setsockopt(td, s, level, name, val, valseg, valsize) enum uio_seg valseg; socklen_t valsize; { - int error; struct socket *so; struct file *fp; struct sockopt sopt; cap_rights_t rights; + int error; if (val == NULL && valsize != 0) return (EFAULT); @@ -1522,11 +1510,11 @@ sys_getsockopt(td, uap) } */ *uap; { socklen_t valsize; - int error; + int error; if (uap->val) { error = copyin(uap->avalsize, &valsize, sizeof (valsize)); - if (error) + if (error != 0) return (error); } @@ -1552,11 +1540,11 @@ kern_getsockopt(td, s, level, name, val, valseg, valsize) enum uio_seg valseg; socklen_t *valsize; { - int error; - struct socket *so; + struct socket *so; struct file *fp; - struct sockopt sopt; + struct sockopt sopt; cap_rights_t rights; + int error; if (val == NULL) *valsize = 0; @@ -1610,11 +1598,11 @@ getsockname1(td, uap, compat) int error; error = copyin(uap->alen, &len, sizeof(len)); - if (error) + if (error != 0) return (error); error = kern_getsockname(td, uap->fdes, &sa, &len); - if (error) + if (error != 0) return (error); if (len != 0) { @@ -1643,14 +1631,14 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, AUDIT_ARG_FD(fd); error = getsock_cap(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_GETSOCKNAME), &fp, NULL); - if (error) + if (error != 0) return (error); so = fp->f_data; *sa = NULL; CURVNET_SET(so->so_vnet); error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa); CURVNET_RESTORE(); - if (error) + if (error != 0) goto bad; if (*sa == NULL) len = 0; @@ -1663,7 +1651,7 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, #endif bad: fdrop(fp, td); - if (error && *sa) { + if (error != 0 && *sa != NULL) { free(*sa, M_SONAME); *sa = NULL; } @@ -1709,11 +1697,11 @@ getpeername1(td, uap, compat) int error; error = copyin(uap->alen, &len, sizeof (len)); - if (error) + if (error != 0) return (error); error = kern_getpeername(td, uap->fdes, &sa, &len); - if (error) + if (error != 0) return (error); if (len != 0) { @@ -1742,7 +1730,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, AUDIT_ARG_FD(fd); error = getsock_cap(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_GETPEERNAME), &fp, NULL); - if (error) + if (error != 0) return (error); so = fp->f_data; if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { @@ -1753,7 +1741,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, CURVNET_SET(so->so_vnet); error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa); CURVNET_RESTORE(); - if (error) + if (error != 0) goto bad; if (*sa == NULL) len = 0; @@ -1765,7 +1753,7 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, ktrsockaddr(*sa); #endif bad: - if (error && *sa) { + if (error != 0 && *sa != NULL) { free(*sa, M_SONAME); *sa = NULL; } @@ -1817,7 +1805,7 @@ sockargs(mp, buf, buflen, type) m = m_get2(buflen, M_WAITOK, type, 0); m->m_len = buflen; error = copyin(buf, mtod(m, caddr_t), (u_int)buflen); - if (error) + if (error != 0) (void) m_free(m); else { *mp = m; @@ -1849,7 +1837,7 @@ getsockaddr(namp, uaddr, len) return (EINVAL); sa = malloc(len, M_SONAME, M_WAITOK); error = copyin(uaddr, sa, len); - if (error) { + if (error != 0) { free(sa, M_SONAME); } else { #if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN @@ -1936,16 +1924,16 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); - if (error) + if (error != 0) goto out; if (hdtr.headers != NULL) { error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); - if (error) + if (error != 0) goto out; } if (hdtr.trailers != NULL) { error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); - if (error) + if (error != 0) goto out; } @@ -1967,10 +1955,8 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) fdrop(fp, td); out: - if (hdr_uio) - free(hdr_uio, M_IOV); - if (trl_uio) - free(trl_uio, M_IOV); + free(hdr_uio, M_IOV); + free(trl_uio, M_IOV); return (error); } @@ -2005,11 +1991,10 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct sf_buf *sf; struct vm_page *pg; struct vattr va; + struct sendfile_sync *sfs = NULL; cap_rights_t rights; off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0; - int error, hdrlen = 0, mnw = 0; - int bsize; - struct sendfile_sync *sfs = NULL; + int bsize, error, hdrlen = 0, mnw = 0; vn_lock(vp, LK_SHARED | LK_RETRY); if (vp->v_type == VREG) { @@ -2082,7 +2067,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto out; #endif @@ -2197,7 +2182,7 @@ retry_space: * been interrupted by a signal. If we've sent anything * then return bytes sent, otherwise return the error. */ - if (error) { + if (error != 0) { SOCKBUF_UNLOCK(&so->so_snd); goto done; } @@ -2289,10 +2274,10 @@ retry_space: IO_VMIO | ((readahead / bsize) << IO_SEQSHIFT), td->td_ucred, NOCRED, &resid, td); SFSTAT_INC(sf_iocnt); - if (error) + if (error != 0) VM_OBJECT_WLOCK(obj); } - if (error) { + if (error != 0) { vm_page_lock(pg); vm_page_unwire(pg, 0); /* @@ -2417,7 +2402,7 @@ retry_space: /* Quit outer loop on error or when we're done. */ if (done) break; - if (error) + if (error != 0) goto done; } @@ -2484,23 +2469,22 @@ sys_sctp_peeloff(td, uap) { #if (defined(INET) || defined(INET6)) && defined(SCTP) struct file *nfp = NULL; - int error; struct socket *head, *so; - int fd; cap_rights_t rights; u_int fflag; + int error, fd; AUDIT_ARG_FD(uap->sd); error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), &head, &fflag); - if (error) + if (error != 0) goto done2; if (head->so_proto->pr_protocol != IPPROTO_SCTP) { error = EOPNOTSUPP; goto done; } error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name); - if (error) + if (error != 0) goto done; /* * At this point we know we do have a assoc to pull @@ -2509,7 +2493,7 @@ sys_sctp_peeloff(td, uap) */ error = falloc(td, &nfp, &fd, 0); - if (error) + if (error != 0) goto done; td->td_retval[0] = fd; @@ -2539,7 +2523,7 @@ sys_sctp_peeloff(td, uap) ACCEPT_UNLOCK(); finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name); - if (error) + if (error != 0) goto noconnection; if (head->so_sigio != NULL) fsetown(fgetown(&head->so_sigio), &so->so_sigio); @@ -2549,7 +2533,7 @@ noconnection: * close the new descriptor, assuming someone hasn't ripped it * out from under us. */ - if (error) + if (error != 0) fdclose(td->td_proc->p_fd, nfp, fd, td); /* @@ -2584,7 +2568,6 @@ sys_sctp_generic_sendmsg (td, uap) struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; struct socket *so; struct file *fp = NULL; - int error = 0, len; struct sockaddr *to = NULL; #ifdef KTRACE struct uio *ktruio = NULL; @@ -2592,18 +2575,19 @@ sys_sctp_generic_sendmsg (td, uap) struct uio auio; struct iovec iov[1]; cap_rights_t rights; + int error = 0, len; - if (uap->sinfo) { + if (uap->sinfo != NULL) { error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); - if (error) + if (error != 0) return (error); u_sinfo = &sinfo; } cap_rights_init(&rights, CAP_SEND); - if (uap->tolen) { + if (uap->tolen != 0) { error = getsockaddr(&to, uap->to, uap->tolen); - if (error) { + if (error != 0) { to = NULL; goto sctp_bad2; } @@ -2612,7 +2596,7 @@ sys_sctp_generic_sendmsg (td, uap) AUDIT_ARG_FD(uap->sd); error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); - if (error) + if (error != 0) goto sctp_bad; #ifdef KTRACE if (to && (KTRPOINT(td, KTR_STRUCT))) @@ -2629,7 +2613,7 @@ sys_sctp_generic_sendmsg (td, uap) } #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto sctp_bad; #endif /* MAC */ @@ -2642,11 +2626,10 @@ sys_sctp_generic_sendmsg (td, uap) auio.uio_resid = 0; len = auio.uio_resid = uap->mlen; CURVNET_SET(so->so_vnet); - error = sctp_lower_sosend(so, to, &auio, - (struct mbuf *)NULL, (struct mbuf *)NULL, - uap->flags, u_sinfo, td); + error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL, + (struct mbuf *)NULL, uap->flags, u_sinfo, td); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2667,11 +2650,10 @@ sys_sctp_generic_sendmsg (td, uap) } #endif /* KTRACE */ sctp_bad: - if (fp) + if (fp != NULL) fdrop(fp, td); sctp_bad2: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); #else /* SCTP */ return (EOPNOTSUPP); @@ -2695,8 +2677,6 @@ sys_sctp_generic_sendmsg_iov(td, uap) struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL; struct socket *so; struct file *fp = NULL; - int error=0, i; - ssize_t len; struct sockaddr *to = NULL; #ifdef KTRACE struct uio *ktruio = NULL; @@ -2704,17 +2684,19 @@ sys_sctp_generic_sendmsg_iov(td, uap) struct uio auio; struct iovec *iov, *tiov; cap_rights_t rights; + ssize_t len; + int error, i; - if (uap->sinfo) { + if (uap->sinfo != NULL) { error = copyin(uap->sinfo, &sinfo, sizeof (sinfo)); - if (error) + if (error != 0) return (error); u_sinfo = &sinfo; } cap_rights_init(&rights, CAP_SEND); - if (uap->tolen) { + if (uap->tolen != 0) { error = getsockaddr(&to, uap->to, uap->tolen); - if (error) { + if (error != 0) { to = NULL; goto sctp_bad2; } @@ -2723,7 +2705,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) AUDIT_ARG_FD(uap->sd); error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL); - if (error) + if (error != 0) goto sctp_bad1; #ifdef COMPAT_FREEBSD32 @@ -2733,7 +2715,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) else #endif error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) goto sctp_bad1; #ifdef KTRACE if (to && (KTRPOINT(td, KTR_STRUCT))) @@ -2747,7 +2729,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) } #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); - if (error) + if (error != 0) goto sctp_bad; #endif /* MAC */ @@ -2771,7 +2753,7 @@ sys_sctp_generic_sendmsg_iov(td, uap) (struct mbuf *)NULL, (struct mbuf *)NULL, uap->flags, u_sinfo, td); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2794,11 +2776,10 @@ sys_sctp_generic_sendmsg_iov(td, uap) sctp_bad: free(iov, M_IOV); sctp_bad1: - if (fp) + if (fp != NULL) fdrop(fp, td); sctp_bad2: - if (to) - free(to, M_SONAME); + free(to, M_SONAME); return (error); #else /* SCTP */ return (EOPNOTSUPP); @@ -2826,21 +2807,18 @@ sys_sctp_generic_recvmsg(td, uap) struct socket *so; struct file *fp = NULL; struct sockaddr *fromsa; - int fromlen; - ssize_t len; - int i, msg_flags; - int error = 0; cap_rights_t rights; #ifdef KTRACE struct uio *ktruio = NULL; #endif + ssize_t len; + int error, fromlen, i, msg_flags; AUDIT_ARG_FD(uap->sd); error = getsock_cap(td->td_proc->p_fd, uap->sd, cap_rights_init(&rights, CAP_RECV), &fp, NULL); - if (error) { + if (error != 0) return (error); - } #ifdef COMPAT_FREEBSD32 if (SV_CURPROC_FLAG(SV_ILP32)) error = freebsd32_copyiniov((struct iovec32 *)uap->iov, @@ -2848,7 +2826,7 @@ sys_sctp_generic_recvmsg(td, uap) else #endif error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE); - if (error) + if (error != 0) goto out1; so = fp->f_data; @@ -2858,25 +2836,21 @@ sys_sctp_generic_recvmsg(td, uap) } #ifdef MAC error = mac_socket_check_receive(td->td_ucred, so); - if (error) { + if (error != 0) goto out; - } #endif /* MAC */ - if (uap->fromlenaddr) { - error = copyin(uap->fromlenaddr, - &fromlen, sizeof (fromlen)); - if (error) { + if (uap->fromlenaddr != NULL) { + error = copyin(uap->fromlenaddr, &fromlen, sizeof (fromlen)); + if (error != 0) goto out; - } } else { fromlen = 0; } if (uap->msg_flags) { error = copyin(uap->msg_flags, &msg_flags, sizeof (int)); - if (error) { + if (error != 0) goto out; - } } else { msg_flags = 0; } @@ -2907,7 +2881,7 @@ sys_sctp_generic_recvmsg(td, uap) fromsa, fromlen, &msg_flags, (struct sctp_sndrcvinfo *)&sinfo, 1); CURVNET_RESTORE(); - if (error) { + if (error != 0) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -2921,7 +2895,7 @@ sys_sctp_generic_recvmsg(td, uap) ktrgenio(uap->sd, UIO_READ, ktruio, error); } #endif /* KTRACE */ - if (error) + if (error != 0) goto out; td->td_retval[0] = len - auio.uio_resid; @@ -2932,13 +2906,12 @@ sys_sctp_generic_recvmsg(td, uap) else { len = MIN(len, fromsa->sa_len); error = copyout(fromsa, uap->from, (size_t)len); - if (error) + if (error != 0) goto out; } error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t)); - if (error) { + if (error != 0) goto out; - } } #ifdef KTRACE if (KTRPOINT(td, KTR_STRUCT)) @@ -2946,14 +2919,13 @@ sys_sctp_generic_recvmsg(td, uap) #endif if (uap->msg_flags) { error = copyout(&msg_flags, uap->msg_flags, sizeof (int)); - if (error) { + if (error != 0) goto out; - } } out: free(iov, M_IOV); out1: - if (fp) + if (fp != NULL) fdrop(fp, td); return (error); -- cgit v1.1 From add7315b85a7e9779ecb55391e2df6aae019b8f2 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 00:19:30 +0000 Subject: Style fixes. --- sys/kern/vfs_syscalls.c | 244 ++++++++++++++++++++++++------------------------ 1 file changed, 122 insertions(+), 122 deletions(-) (limited to 'sys') diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 7df315d..062d261 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -181,8 +181,8 @@ sys_quotactl(td, uap) } */ *uap; { struct mount *mp; - int error; struct nameidata nd; + int error; AUDIT_ARG_CMD(uap->cmd); AUDIT_ARG_UID(uap->uid); @@ -198,7 +198,7 @@ sys_quotactl(td, uap) vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg); @@ -291,13 +291,13 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, { struct mount *mp; struct statfs *sp, sb; - int error; struct nameidata nd; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); error = namei(&nd); - if (error) + if (error != 0) return (error); mp = nd.ni_vp->v_mount; vfs_ref(mp); @@ -305,11 +305,11 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, vput(nd.ni_vp); error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* @@ -320,7 +320,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); - if (error) + if (error != 0) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); @@ -373,7 +373,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) AUDIT_ARG_FD(fd); error = getvnode(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_FSTATFS), &fp); - if (error) + if (error != 0) return (error); vp = fp->f_vnode; vn_lock(vp, LK_SHARED | LK_RETRY); @@ -391,11 +391,11 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) } error = vfs_busy(mp, 0); vfs_rel(mp); - if (error) + if (error != 0) return (error); #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* @@ -406,7 +406,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; error = VFS_STATFS(mp, sp); - if (error) + if (error != 0) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); @@ -525,7 +525,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, bcopy(sp, sfsp, sizeof(*sp)); else /* if (bufseg == UIO_USERSPACE) */ { error = copyout(sp, sfsp, sizeof(*sp)); - if (error) { + if (error != 0) { vfs_unbusy(mp); return (error); } @@ -570,7 +570,7 @@ freebsd4_statfs(td, uap) int error; error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -598,7 +598,7 @@ freebsd4_fstatfs(td, uap) int error; error = kern_fstatfs(td, uap->fd, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -669,10 +669,10 @@ freebsd4_fhstatfs(td, uap) int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); - if (error) + if (error != 0) return (error); error = kern_fhstatfs(td, fh, &sf); - if (error) + if (error != 0) return (error); cvtstatfs(&sf, &osb); return (copyout(&osb, uap->buf, sizeof(osb))); @@ -751,12 +751,12 @@ sys_fchdir(td, uap) continue; error = VFS_ROOT(mp, LK_SHARED, &tdp); vfs_unbusy(mp); - if (error) + if (error != 0) break; vput(vp); vp = tdp; } - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -792,9 +792,9 @@ int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg) { register struct filedesc *fdp = td->td_proc->p_fd; - int error; struct nameidata nd; struct vnode *vp; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, td); @@ -871,21 +871,23 @@ sys_chroot(td, uap) char *path; } */ *uap; { - int error; struct nameidata nd; + int error; error = priv_check(td, PRIV_VFS_CHROOT); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); - if (error) + if (error != 0) goto error; - if ((error = change_dir(nd.ni_vp, td)) != 0) + error = change_dir(nd.ni_vp, td); + if (error != 0) goto e_vunlock; #ifdef MAC - if ((error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp))) + error = mac_vnode_check_chroot(td->td_ucred, nd.ni_vp); + if (error != 0) goto e_vunlock; #endif VOP_UNLOCK(nd.ni_vp, 0); @@ -909,18 +911,19 @@ change_dir(vp, td) struct vnode *vp; struct thread *td; { +#ifdef MAC int error; +#endif ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked"); if (vp->v_type != VDIR) return (ENOTDIR); #ifdef MAC error = mac_vnode_check_chdir(td->td_ucred, vp); - if (error) + if (error == 0) return (error); #endif - error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td); - return (error); + return (VOP_ACCESS(vp, VEXEC, td->td_ucred, td)); } /* @@ -942,7 +945,7 @@ change_root(vp, td) if (chroot_allow_open_directories == 0 || (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) { error = chroot_refuse_vdir_fds(fdp); - if (error) { + if (error != 0) { FILEDESC_XUNLOCK(fdp); return (error); } @@ -1050,10 +1053,11 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct filedesc *fdp = p->p_fd; struct file *fp; struct vnode *vp; - int cmode; - int indx = -1, error; struct nameidata nd; cap_rights_t rights; + int cmode, error, indx; + + indx = -1; AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); @@ -1077,7 +1081,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, * Allocate the file descriptor, but don't install a descriptor yet. */ error = falloc_noinstall(td, &fp); - if (error) + if (error != 0) return (error); /* * An extra reference on `fp' has been held for us by @@ -1085,12 +1089,12 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, */ /* Set the flags early so the finit in devfs can pick them up. */ fp->f_flag = flags & FMASK; - cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; + cmode = ((mode & ~fdp->fd_cmask) & ALLPERMS) & ~S_ISTXT; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, fd, &rights, td); td->td_dupfd = -1; /* XXX check for fdopen */ error = vn_open(&nd, &flags, cmode, fp); - if (error) { + if (error != 0) { /* * If the vn_open replaced the method vector, something * wonderous happened deep below and we just pass it up @@ -1134,14 +1138,14 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, if (fp->f_ops == &badfileops) { KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); fp->f_seqcount = 1; - finit(fp, (flags & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, - vp, &vnops); + finit(fp, (flags & FMASK) | (fp->f_flag & FHASLOCK), + DTYPE_VNODE, vp, &vnops); } VOP_UNLOCK(vp, 0); if (flags & O_TRUNC) { error = fo_truncate(fp, 0, td->td_ucred, td); - if (error) + if (error != 0) goto bad; } success: @@ -1258,10 +1262,9 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct vnode *vp; struct mount *mp; struct vattr vattr; - int error; - int whiteout = 0; struct nameidata nd; cap_rights_t rights; + int error, whiteout = 0; AUDIT_ARG_MODE(mode); AUDIT_ARG_DEV(dev); @@ -1284,7 +1287,7 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, error = EINVAL; break; } - if (error) + if (error != 0) return (error); restart: bwillwrite(); @@ -1337,7 +1340,7 @@ restart: error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif - if (!error) { + if (error == 0) { if (whiteout) error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); else { @@ -1402,9 +1405,9 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct mount *mp; struct vattr vattr; + struct nameidata nd; cap_rights_t rights; int error; - struct nameidata nd; AUDIT_ARG_MODE(mode); restart: @@ -1435,7 +1438,7 @@ restart: #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out; #endif error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); @@ -1519,13 +1522,13 @@ can_hardlink(struct vnode *vp, struct ucred *cred) if (hardlink_check_uid && cred->cr_uid != va.va_uid) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); - if (error) + if (error != 0) return (error); } if (hardlink_check_gid && !groupmember(va.va_gid, cred)) { error = priv_check_cred(cred, PRIV_VFS_LINK, 0); - if (error) + if (error != 0) return (error); } @@ -1644,8 +1647,8 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, struct mount *mp; struct vattr vattr; char *syspath; - int error; struct nameidata nd; + int error; cap_rights_t rights; if (segflg == UIO_SYSSPACE) { @@ -1685,7 +1688,7 @@ restart: vattr.va_type = VLNK; error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out2; #endif error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath); @@ -1713,16 +1716,16 @@ sys_undelete(td, uap) char *path; } */ *uap; { - int error; struct mount *mp; struct nameidata nd; + int error; restart: bwillwrite(); NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | AUDITVNODE1, UIO_USERSPACE, uap->path, td); error = namei(&nd); - if (error) + if (error != 0) return (error); if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { @@ -1804,10 +1807,10 @@ kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, { struct mount *mp; struct vnode *vp; - int error; struct nameidata nd; struct stat sb; cap_rights_t rights; + int error; restart: bwillwrite(); @@ -1847,7 +1850,7 @@ restart: #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); - if (error) + if (error != 0) goto out; #endif vfs_notify_upper(vp, VFS_NOTIFY_UPPER_UNLINK); @@ -1959,8 +1962,8 @@ vn_access(vp, user_flags, cred, td) struct ucred *cred; struct thread *td; { - int error; accmode_t accmode; + int error; /* Flags == 0 means only check for existence. */ error = 0; @@ -1974,7 +1977,7 @@ vn_access(vp, user_flags, cred, td) accmode |= VEXEC; #ifdef MAC error = mac_vnode_check_access(cred, vp, accmode); - if (error) + if (error != 0) return (error); #endif if ((accmode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) @@ -2121,11 +2124,10 @@ ostat(td, uap) int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtstat(&sb, &osb); - error = copyout(&osb, uap->ub, sizeof (osb)); - return (error); + return (copyout(&osb, uap->ub, sizeof (osb))); } /* @@ -2150,11 +2152,10 @@ olstat(td, uap) int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtstat(&sb, &osb); - error = copyout(&osb, uap->ub, sizeof (osb)); - return (error); + return (copyout(&osb, uap->ub, sizeof (osb))); } /* @@ -2269,7 +2270,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, if ((error = namei(&nd)) != 0) return (error); error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); - if (!error) { + if (error == 0) { SDT_PROBE(vfs, , stat, mode, path, sb.st_mode, 0, 0, 0); if (S_ISREG(sb.st_mode)) SDT_PROBE(vfs, , stat, reg, path, pathseg, 0, 0, 0); @@ -2278,7 +2279,7 @@ kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, } NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_vp); - if (error) + if (error != 0) return (error); *sbp = sb; #ifdef KTRACE @@ -2330,6 +2331,7 @@ cvtnstat(sb, nsb) struct stat *sb; struct nstat *nsb; { + bzero(nsb, sizeof *nsb); nsb->st_dev = sb->st_dev; nsb->st_ino = sb->st_ino; @@ -2368,11 +2370,10 @@ sys_nstat(td, uap) int error; error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtnstat(&sb, &nsb); - error = copyout(&nsb, uap->ub, sizeof (nsb)); - return (error); + return (copyout(&nsb, uap->ub, sizeof (nsb))); } /* @@ -2397,11 +2398,10 @@ sys_nlstat(td, uap) int error; error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); - if (error) + if (error != 0) return (error); cvtnstat(&sb, &nsb); - error = copyout(&nsb, uap->ub, sizeof (nsb)); - return (error); + return (copyout(&nsb, uap->ub, sizeof (nsb))); } /* @@ -2521,8 +2521,8 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct vnode *vp; struct iovec aiov; struct uio auio; - int error; struct nameidata nd; + int error; if (count > IOSIZE_MAX) return (EINVAL); @@ -2536,7 +2536,7 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, vp = nd.ni_vp; #ifdef MAC error = mac_vnode_check_readlink(td->td_ucred, vp); - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -2569,9 +2569,9 @@ setfflags(td, vp, flags) struct vnode *vp; u_long flags; { - int error; struct mount *mp; struct vattr vattr; + int error; /* We can't support the value matching VNOVAL. */ if (flags == VNOVAL) @@ -2585,7 +2585,7 @@ setfflags(td, vp, flags) */ if (vp->v_type == VCHR || vp->v_type == VBLK) { error = priv_check(td, PRIV_VFS_CHFLAGS_DEV); - if (error) + if (error != 0) return (error); } @@ -2738,9 +2738,9 @@ setfmode(td, cred, vp, mode) struct vnode *vp; int mode; { - int error; struct mount *mp; struct vattr vattr; + int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -2833,10 +2833,9 @@ int kern_fchmodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, mode_t mode, int flag) { - int error; struct nameidata nd; - int follow; cap_rights_t rights; + int error, follow; AUDIT_ARG_MODE(mode); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; @@ -2888,9 +2887,9 @@ setfown(td, cred, vp, uid, gid) uid_t uid; gid_t gid; { - int error; struct mount *mp; struct vattr vattr; + int error; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -3093,9 +3092,9 @@ setutimes(td, vp, ts, numtimes, nullflag) int numtimes; int nullflag; { - int error, setbirthtime; struct mount *mp; struct vattr vattr; + int error, setbirthtime; if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); @@ -3218,8 +3217,8 @@ kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { struct timespec ts[2]; - int error; struct nameidata nd; + int error; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); @@ -3263,7 +3262,8 @@ kern_futimes(struct thread *td, int fd, struct timeval *tptr, int error; AUDIT_ARG_FD(fd); - if ((error = getutimes(tptr, tptrseg, ts)) != 0) + error = getutimes(tptr, tptrseg, ts); + if (error != 0) return (error); error = getvnode(td->td_proc->p_fd, fd, cap_rights_init(&rights, CAP_FUTIMES), &fp); @@ -3423,7 +3423,8 @@ sys_fsync(td, uap) if (error != 0) return (error); vp = fp->f_vnode; - if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) + error = vn_start_write(vp, &mp, V_WAIT | PCATCH); + if (error != 0) goto drop; if (MNT_SHARED_WRITES(mp) || ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { @@ -3584,15 +3585,15 @@ kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); #endif out: - if (!error) { + if (error == 0) { error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); + tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); } else { NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); - if (tvp) + if (tvp != NULL) vput(tvp); if (tdvp == tvp) vrele(tdvp); @@ -3660,9 +3661,9 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, struct mount *mp; struct vnode *vp; struct vattr vattr; + struct nameidata nd; cap_rights_t rights; int error; - struct nameidata nd; AUDIT_ARG_MODE(mode); restart: @@ -3700,7 +3701,7 @@ restart: #ifdef MAC error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); - if (error) + if (error != 0) goto out; #endif error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); @@ -3709,7 +3710,7 @@ out: #endif NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); - if (!error) + if (error == 0) vput(nd.ni_vp); vn_finished_write(mp); return (error); @@ -3746,9 +3747,9 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg) { struct mount *mp; struct vnode *vp; + struct nameidata nd; cap_rights_t rights; int error; - struct nameidata nd; restart: bwillwrite(); @@ -3778,7 +3779,7 @@ restart: #ifdef MAC error = mac_vnode_check_unlink(td->td_ucred, nd.ni_dvp, vp, &nd.ni_cnd); - if (error) + if (error != 0) goto out; #endif if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { @@ -3875,7 +3876,7 @@ unionread: loff = auio.uio_offset = foffset; #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); foffset_unlock(fp, foffset, FOF_NOUPDATE); fdrop(fp, td); @@ -3933,7 +3934,7 @@ unionread: } free(dirbuf, M_TEMP); } - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); foffset_unlock(fp, foffset, 0); fdrop(fp, td); @@ -3987,7 +3988,7 @@ sys_getdirentries(td, uap) error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, NULL, UIO_USERSPACE); - if (error) + if (error != 0) return (error); if (uap->basep != NULL) error = copyout(&base, uap->basep, sizeof(long)); @@ -4043,7 +4044,7 @@ unionread: error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); foffset = auio.uio_offset; - if (error) { + if (error != 0) { VOP_UNLOCK(vp, 0); goto fail; } @@ -4051,6 +4052,7 @@ unionread: (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; + vp = vp->v_mount->mnt_vnodecovered; VREF(vp); fp->f_vnode = vp; @@ -4087,6 +4089,7 @@ sys_getdents(td, uap) } */ *uap; { struct getdirentries_args ap; + ap.fd = uap->fd; ap.buf = uap->buf; ap.count = uap->count; @@ -4137,8 +4140,8 @@ sys_revoke(td, uap) { struct vnode *vp; struct vattr vattr; - int error; struct nameidata nd; + int error; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->path, td); @@ -4152,15 +4155,15 @@ sys_revoke(td, uap) } #ifdef MAC error = mac_vnode_check_revoke(td->td_ucred, vp); - if (error) + if (error != 0) goto out; #endif error = VOP_GETATTR(vp, &vattr, td->td_ucred); - if (error) + if (error != 0) goto out; if (td->td_ucred->cr_uid != vattr.va_uid) { error = priv_check(td, PRIV_VFS_ADMIN); - if (error) + if (error != 0) goto out; } if (vcount(vp) > 1) @@ -4226,12 +4229,12 @@ sys_lgetfh(td, uap) int error; error = priv_check(td, PRIV_VFS_GETFH); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); - if (error) + if (error != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; @@ -4239,9 +4242,8 @@ sys_lgetfh(td, uap) fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error) - return (error); - error = copyout(&fh, uap->fhp, sizeof (fh)); + if (error == 0) + error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } @@ -4262,12 +4264,12 @@ sys_getfh(td, uap) int error; error = priv_check(td, PRIV_VFS_GETFH); - if (error) + if (error != 0) return (error); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE, uap->fname, td); error = namei(&nd); - if (error) + if (error != 0) return (error); NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; @@ -4275,9 +4277,8 @@ sys_getfh(td, uap) fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; error = VOP_VPTOFH(vp, &fh.fh_fid); vput(vp); - if (error) - return (error); - error = copyout(&fh, uap->fhp, sizeof (fh)); + if (error == 0) + error = copyout(&fh, uap->fhp, sizeof (fh)); return (error); } @@ -4310,7 +4311,7 @@ sys_fhopen(td, uap) int indx; error = priv_check(td, PRIV_VFS_FHOPEN); - if (error) + if (error != 0) return (error); indx = -1; fmode = FFLAGS(uap->flags); @@ -4318,7 +4319,7 @@ sys_fhopen(td, uap) if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT)) return (EINVAL); error = copyin(uap->u_fhp, &fhp, sizeof(fhp)); - if (error) + if (error != 0) return(error); /* find the mount point */ mp = vfs_busyfs(&fhp.fh_fsid); @@ -4327,11 +4328,11 @@ sys_fhopen(td, uap) /* now give me my vnode, it gets returned to me locked */ error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); - if (error) + if (error != 0) return (error); error = falloc_noinstall(td, &fp); - if (error) { + if (error != 0) { vput(vp); return (error); } @@ -4344,7 +4345,7 @@ sys_fhopen(td, uap) td->td_dupfd = -1; #endif error = vn_open_vnode(vp, fmode, td->td_ucred, td, fp); - if (error) { + if (error != 0) { KASSERT(fp->f_ops == &badfileops, ("VOP_OPEN in fhopen() set f_ops")); KASSERT(td->td_dupfd < 0, @@ -4361,9 +4362,9 @@ sys_fhopen(td, uap) finit(fp, (fmode & FMASK) | (fp->f_flag & FHASLOCK), DTYPE_VNODE, vp, &vnops); VOP_UNLOCK(vp, 0); - if (fmode & O_TRUNC) { + if ((fmode & O_TRUNC) != 0) { error = fo_truncate(fp, 0, td->td_ucred, td); - if (error) + if (error != 0) goto bad; } @@ -4399,9 +4400,8 @@ sys_fhstat(td, uap) if (error != 0) return (error); error = kern_fhstat(td, fh, &sb); - if (error != 0) - return (error); - error = copyout(&sb, uap->sb, sizeof(sb)); + if (error == 0) + error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } @@ -4413,13 +4413,13 @@ kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb) int error; error = priv_check(td, PRIV_VFS_FHSTAT); - if (error) + if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); - if (error) + if (error != 0) return (error); error = vn_stat(vp, sb, td->td_ucred, NOCRED, td); vput(vp); @@ -4448,10 +4448,10 @@ sys_fhstatfs(td, uap) int error; error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); - if (error) + if (error != 0) return (error); error = kern_fhstatfs(td, fh, &sf); - if (error) + if (error != 0) return (error); return (copyout(&sf, uap->buf, sizeof(sf))); } @@ -4465,22 +4465,22 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) int error; error = priv_check(td, PRIV_VFS_FHSTATFS); - if (error) + if (error != 0) return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); - if (error) { + if (error != 0) { vfs_unbusy(mp); return (error); } vput(vp); error = prison_canseemount(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #ifdef MAC error = mac_mount_check_stat(td->td_ucred, mp); - if (error) + if (error != 0) goto out; #endif /* -- cgit v1.1 From 58db73786bebc44342321a87e1bf763b4d3d9cfc Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 00:53:01 +0000 Subject: Add sysctl/tunables for various metaslab variables. --- .../opensolaris/uts/common/fs/zfs/metaslab.c | 37 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c index f2f7139..50a1e82 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c @@ -32,6 +32,9 @@ #include #include +SYSCTL_DECL(_vfs_zfs); +SYSCTL_NODE(_vfs_zfs, OID_AUTO, metaslab, CTLFLAG_RW, 0, "ZFS metaslab"); + /* * Allow allocations to switch to gang blocks quickly. We do this to * avoid having to load lots of space_maps in a given txg. There are, @@ -46,6 +49,10 @@ uint64_t metaslab_aliquot = 512ULL << 10; uint64_t metaslab_gang_bang = SPA_MAXBLOCKSIZE + 1; /* force gang blocks */ +TUNABLE_QUAD("vfs.zfs.metaslab.gang_bang", &metaslab_gang_bang); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, gang_bang, CTLFLAG_RWTUN, + &metaslab_gang_bang, 0, + "Force gang block allocation for blocks larger than or equal to this value"); /* * The in-core space map representation is more compact than its on-disk form. @@ -61,17 +68,19 @@ int zfs_condense_pct = 200; * allocations on that device. */ int zfs_mg_alloc_failures = 0; - -SYSCTL_DECL(_vfs_zfs); -SYSCTL_INT(_vfs_zfs, OID_AUTO, mg_alloc_failures, CTLFLAG_RDTUN, +TUNABLE_INT("vfs.zfs.mg_alloc_failures", &zfs_mg_alloc_failures); +SYSCTL_INT(_vfs_zfs, OID_AUTO, mg_alloc_failures, CTLFLAG_RWTUN, &zfs_mg_alloc_failures, 0, "Number of allowed allocation failures per vdev"); -TUNABLE_INT("vfs.zfs.mg_alloc_failures", &zfs_mg_alloc_failures); /* * Metaslab debugging: when set, keeps all space maps in core to verify frees. */ static int metaslab_debug = 0; +TUNABLE_INT("vfs.zfs.metaslab.debug", &metaslab_debug); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, debug, CTLFLAG_RWTUN, &metaslab_debug, + 0, + "Metaslab debugging: when set, keeps all space maps in core to verify frees"); /* * Minimum size which forces the dynamic allocator to change @@ -80,6 +89,11 @@ static int metaslab_debug = 0; * aggressive strategy (i.e search by size rather than offset). */ uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE; +TUNABLE_QUAD("vfs.zfs.metaslab.df_alloc_threshold", + &metaslab_df_alloc_threshold); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, df_alloc_threshold, CTLFLAG_RWTUN, + &metaslab_df_alloc_threshold, 0, + "Minimum size which forces the dynamic allocator to change it's allocation strategy"); /* * The minimum free space, in percent, which must be available @@ -88,22 +102,37 @@ uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE; * switch to using best-fit allocations. */ int metaslab_df_free_pct = 4; +TUNABLE_INT("vfs.zfs.metaslab.df_free_pct", &metaslab_df_free_pct); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, df_free_pct, CTLFLAG_RWTUN, + &metaslab_df_free_pct, 0, + "The minimum free space, in percent, which must be available in a space map to continue allocations in a first-fit fashion"); /* * A metaslab is considered "free" if it contains a contiguous * segment which is greater than metaslab_min_alloc_size. */ uint64_t metaslab_min_alloc_size = DMU_MAX_ACCESS; +TUNABLE_QUAD("vfs.zfs.metaslab.min_alloc_size", + &metaslab_min_alloc_size); +SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, min_alloc_size, CTLFLAG_RWTUN, + &metaslab_min_alloc_size, 0, + "A metaslab is considered \"free\" if it contains a contiguous segment which is greater than vfs.zfs.metaslab.min_alloc_size"); /* * Max number of space_maps to prefetch. */ int metaslab_prefetch_limit = SPA_DVAS_PER_BP; +TUNABLE_INT("vfs.zfs.metaslab.prefetch_limit", &metaslab_prefetch_limit); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, prefetch_limit, CTLFLAG_RWTUN, + &metaslab_prefetch_limit, 0, "Maximum number of space_maps to prefetch"); /* * Percentage bonus multiplier for metaslabs that are in the bonus area. */ int metaslab_smo_bonus_pct = 150; +TUNABLE_INT("vfs.zfs.metaslab.smo_bonus_pct", &metaslab_smo_bonus_pct); +SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, smo_bonus_pct, CTLFLAG_RWTUN, + &metaslab_smo_bonus_pct, 0, "Maximum number of space_maps to prefetch"); /* * Should we be willing to write data to degraded vdevs? -- cgit v1.1 From 2764ddeb0a39604889df9ed6b6c661e319bab0ed Mon Sep 17 00:00:00 2001 From: jhibbits Date: Thu, 5 Sep 2013 01:13:26 +0000 Subject: Fix the build. --- sys/dev/hwpmc/hwpmc_powerpc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c index c7d8f3d..25a32fa 100644 --- a/sys/dev/hwpmc/hwpmc_powerpc.c +++ b/sys/dev/hwpmc/hwpmc_powerpc.c @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \ ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS) +struct powerpc_cpu **powerpc_pcpu; + int pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) -- cgit v1.1 From c1754372ea9df69d05902cf55ba2e06becff9476 Mon Sep 17 00:00:00 2001 From: sbruno Date: Thu, 5 Sep 2013 03:36:57 +0000 Subject: This looks like a typo that breaks the build. Yell at me if this isn't the intended declaration. --- sys/kern/sys_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c index 456f7ac..7a82017 100644 --- a/sys/kern/sys_capability.c +++ b/sys/kern/sys_capability.c @@ -576,7 +576,7 @@ sys_cap_rights_limit(struct thread *td, struct cap_rights_limit_args *uap) } int -sys___cap_rights_get(struct thread *td, struct cap___rights_get_args *uap) +sys___cap_rights_get(struct thread *td, struct __cap_rights_get_args *uap) { return (ENOSYS); -- cgit v1.1 From bf3232d8bba436553c7aaba2fe78952c25c7dfa1 Mon Sep 17 00:00:00 2001 From: sbruno Date: Thu, 5 Sep 2013 03:46:44 +0000 Subject: Restore builds on architectures that don't support CAPABILITIES (mips). --- sys/kern/sys_generic.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sys') diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 5eaa695..d4d6293 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1368,7 +1368,9 @@ pollrescan(struct thread *td) struct filedesc *fdp; struct file *fp; struct pollfd *fd; +#ifdef CAPABILITIES cap_rights_t rights; +#endif int n; n = 0; @@ -1444,7 +1446,9 @@ pollscan(td, fds, nfd) { struct filedesc *fdp = td->td_proc->p_fd; struct file *fp; +#ifdef CAPABILITIES cap_rights_t rights; +#endif int i, n = 0; FILEDESC_SLOCK(fdp); -- cgit v1.1 From 0a28609aca2b7931b3b642e4db74a766d9c43839 Mon Sep 17 00:00:00 2001 From: ae Date: Thu, 5 Sep 2013 08:12:36 +0000 Subject: Remove unused code and sort variables declarations. PR: kern/181822 MFC after: 1 week --- sys/netinet/ip_mroute.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 23f1be7..6d3f990 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -704,10 +704,9 @@ ip_mrouter_init(struct socket *so, int version) static int X_ip_mrouter_done(void) { - vifi_t vifi; - int i; struct ifnet *ifp; - struct ifreq ifr; + int i; + vifi_t vifi; MROUTER_LOCK(); @@ -732,11 +731,6 @@ X_ip_mrouter_done(void) for (vifi = 0; vifi < V_numvifs; vifi++) { if (!in_nullhost(V_viftable[vifi].v_lcl_addr) && !(V_viftable[vifi].v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) { - struct sockaddr_in *so = (struct sockaddr_in *)&(ifr.ifr_addr); - - so->sin_len = sizeof(struct sockaddr_in); - so->sin_family = AF_INET; - so->sin_addr.s_addr = INADDR_ANY; ifp = V_viftable[vifi].v_ifp; if_allmulti(ifp, 0); } -- cgit v1.1 From ad93dafc6a662451c8ced5b1da54db7df3396355 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 09:36:19 +0000 Subject: Correct the logic broken in my last commit. Reported by: tijl --- sys/kern/vfs_syscalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 062d261..4b82df8 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -920,7 +920,7 @@ change_dir(vp, td) return (ENOTDIR); #ifdef MAC error = mac_vnode_check_chdir(td->td_ucred, vp); - if (error == 0) + if (error != 0) return (error); #endif return (VOP_ACCESS(vp, VEXEC, td->td_ucred, td)); -- cgit v1.1 From 7f30f5be1c870382ca2617bd46a119c43d667b7a Mon Sep 17 00:00:00 2001 From: ae Date: Thu, 5 Sep 2013 09:44:09 +0000 Subject: Remove stub implementation. MFC after: 1 week --- sys/geom/part/g_part_ldm.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sys') diff --git a/sys/geom/part/g_part_ldm.c b/sys/geom/part/g_part_ldm.c index 81abc84..40c2eb8 100644 --- a/sys/geom/part/g_part_ldm.c +++ b/sys/geom/part/g_part_ldm.c @@ -339,8 +339,6 @@ static int g_part_ldm_read(struct g_part_table *, struct g_consumer *); static const char *g_part_ldm_type(struct g_part_table *, struct g_part_entry *, char *, size_t); static int g_part_ldm_write(struct g_part_table *, struct g_consumer *); -static int g_part_ldm_resize(struct g_part_table *, struct g_part_entry *, - struct g_part_parms *); static kobj_method_t g_part_ldm_methods[] = { KOBJMETHOD(g_part_add, g_part_ldm_add), @@ -350,7 +348,6 @@ static kobj_method_t g_part_ldm_methods[] = { KOBJMETHOD(g_part_dumpconf, g_part_ldm_dumpconf), KOBJMETHOD(g_part_dumpto, g_part_ldm_dumpto), KOBJMETHOD(g_part_modify, g_part_ldm_modify), - KOBJMETHOD(g_part_resize, g_part_ldm_resize), KOBJMETHOD(g_part_name, g_part_ldm_name), KOBJMETHOD(g_part_probe, g_part_ldm_probe), KOBJMETHOD(g_part_read, g_part_ldm_read), @@ -1206,14 +1203,6 @@ g_part_ldm_modify(struct g_part_table *basetable, return (ENOSYS); } -static int -g_part_ldm_resize(struct g_part_table *basetable, - struct g_part_entry *baseentry, struct g_part_parms *gpp) -{ - - return (ENOSYS); -} - static const char * g_part_ldm_name(struct g_part_table *table, struct g_part_entry *baseentry, char *buf, size_t bufsz) -- cgit v1.1 From 71ada8a9acb20be675e9c8879ed61b743960a44f Mon Sep 17 00:00:00 2001 From: br Date: Thu, 5 Sep 2013 10:09:24 +0000 Subject: Add support for DLINK DWA-127 Wireless Adapter Approved by: cognet (mentor) --- sys/dev/usb/usbdevs | 1 + sys/dev/usb/wlan/if_run.c | 1 + 2 files changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 3074530..e6a32ae 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1547,6 +1547,7 @@ product DLINK DWLG122 0x3c00 DWL-G122 b1 Wireless Adapter product DLINK DUBE100B1 0x3c05 DUB-E100 rev B1 product DLINK RT2870 0x3c09 RT2870 product DLINK RT3072 0x3c0a RT3072 +product DLINK DWA127 0x3c1b DWA-127 Wireless Adapter product DLINK DSB650C 0x4000 10Mbps Ethernet product DLINK DSB650TX1 0x4001 10/100 Ethernet product DLINK DSB650TX 0x4002 10/100 Ethernet diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index aed07a2..5b4587f 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -171,6 +171,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = { RUN_DEV(CYBERTAN, RT2870), RUN_DEV(DLINK, RT2870), RUN_DEV(DLINK, RT3072), + RUN_DEV(DLINK, DWA127), RUN_DEV(DLINK2, DWA130), RUN_DEV(DLINK2, RT2870_1), RUN_DEV(DLINK2, RT2870_2), -- cgit v1.1 From 12cfeea19a8d4e0050ea00927229c9f934e11828 Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 5 Sep 2013 10:24:09 +0000 Subject: Fix !CAPABILITIES build. --- sys/kern/uipc_mqueue.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 6a1bf76..fe7e886 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2247,7 +2247,9 @@ sys_kmq_timedsend(struct thread *td, struct kmq_timedsend_args *uap) static int kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev) { +#ifdef CAPABILITIES cap_rights_t rights; +#endif struct filedesc *fdp; struct proc *p; struct mqueue *mq; -- cgit v1.1 From 1c7defb76e774a54509fd6d99f3b65eec088b4e9 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 11:58:12 +0000 Subject: Handle cases where capability rights are not provided. Reported by: kib --- sys/cddl/compat/opensolaris/sys/file.h | 2 +- sys/dev/aacraid/aacraid_linux.c | 13 ++++++++++--- sys/fs/fdescfs/fdesc_vnops.c | 2 +- sys/kern/kern_descrip.c | 33 ++++++++++++++++++++------------- sys/ofed/include/linux/file.h | 12 +++++++++--- sys/security/audit/audit_bsm_klib.c | 2 +- 6 files changed, 42 insertions(+), 22 deletions(-) (limited to 'sys') diff --git a/sys/cddl/compat/opensolaris/sys/file.h b/sys/cddl/compat/opensolaris/sys/file.h index a1c1d45..5f83082 100644 --- a/sys/cddl/compat/opensolaris/sys/file.h +++ b/sys/cddl/compat/opensolaris/sys/file.h @@ -54,7 +54,7 @@ releasef(int fd) struct file *fp; /* No CAP_ rights required, as we're only releasing. */ - if (fget(curthread, fd, 0, &fp) == 0) { + if (fget(curthread, fd, NULL, &fp) == 0) { fdrop(fp, curthread); fdrop(fp, curthread); } diff --git a/sys/dev/aacraid/aacraid_linux.c b/sys/dev/aacraid/aacraid_linux.c index 3d85445..e58d0a4 100644 --- a/sys/dev/aacraid/aacraid_linux.c +++ b/sys/dev/aacraid/aacraid_linux.c @@ -34,6 +34,9 @@ __FBSDID("$FreeBSD$"); */ #include +#if __FreeBSD_version >= 900000 +#include +#endif #include #include #include @@ -77,15 +80,19 @@ static int aacraid_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { struct file *fp; +#if __FreeBSD_version >= 900000 + cap_rights_t rights; +#endif u_long cmd; int error; + if ((error = fget(td, args->fd, #if __FreeBSD_version >= 900000 - if ((error = fget(td, args->fd, 0, &fp)) != 0) -#else - if ((error = fget(td, args->fd, &fp)) != 0) + cap_rights_init(&rights, CAP_IOCTL), #endif + &fp)) != 0) { return (error); + } cmd = args->cmd; /* diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index fe939b1..b976504 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -309,7 +309,7 @@ fdesc_lookup(ap) /* * No rights to check since 'fp' isn't actually used. */ - if ((error = fget(td, fd, 0, &fp)) != 0) + if ((error = fget(td, fd, NULL, &fp)) != 0) goto bad; /* Check if we're looking up ourselves. */ diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index a0545e1..9e9010f 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -586,8 +586,8 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) case F_SETLK: do_setlk: - error = fget_unlocked(fdp, fd, - cap_rights_init(&rights, CAP_FLOCK), 0, &fp, NULL); + cap_rights_init(&rights, CAP_FLOCK); + error = fget_unlocked(fdp, fd, &rights, 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -676,7 +676,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) * that the closing thread was a bit slower and that the * advisory lock succeeded before the close. */ - error = fget_unlocked(fdp, fd, 0, 0, &fp2, NULL); + error = fget_unlocked(fdp, fd, &rights, 0, &fp2, NULL); if (error != 0) { fdrop(fp, td); break; @@ -733,7 +733,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) arg = arg ? 128 * 1024: 0; /* FALLTHROUGH */ case F_READAHEAD: - error = fget_unlocked(fdp, fd, 0, 0, &fp, NULL); + error = fget_unlocked(fdp, fd, NULL, 0, &fp, NULL); if (error != 0) break; if (fp->f_type != DTYPE_VNODE) { @@ -2324,13 +2324,15 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp, return (EBADF); #ifdef CAPABILITIES haverights = *cap_rights(fdp, fd); - error = cap_check(&haverights, needrightsp); - if (error != 0) - return (error); - if (cap_rights_is_set(needrightsp, CAP_FCNTL)) { - error = cap_fcntl_check(fdp, fd, needfcntl); + if (needrightsp != NULL) { + error = cap_check(&haverights, needrightsp); if (error != 0) return (error); + if (cap_rights_is_set(needrightsp, CAP_FCNTL)) { + error = cap_fcntl_check(fdp, fd, needfcntl); + if (error != 0) + return (error); + } } #endif count = fp->f_count; @@ -2382,7 +2384,10 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, *fpp = NULL; if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) return (EBADF); - needrights = *needrightsp; + if (needrightsp != NULL) + needrights = *needrightsp; + else + cap_rights_init(&needrights); if (maxprotp != NULL) cap_rights_set(&needrights, CAP_MMAP); error = fget_unlocked(fdp, fd, &needrights, 0, &fp, &haverights); @@ -2517,9 +2522,11 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, return (EBADF); #ifdef CAPABILITIES - error = cap_check(cap_rights(fdp, fd), needrightsp); - if (error != 0) - return (error); + if (needrightsp != NULL) { + error = cap_check(cap_rights(fdp, fd), needrightsp); + if (error != 0) + return (error); + } #endif if (fp->f_vnode == NULL) diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h index b9bd8b1..bb9d58d 100644 --- a/sys/ofed/include/linux/file.h +++ b/sys/ofed/include/linux/file.h @@ -47,8 +47,10 @@ linux_fget(unsigned int fd) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { return (NULL); + } return (struct linux_file *)file->f_data; } @@ -70,8 +72,10 @@ put_unused_fd(unsigned int fd) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { return; + } fdclose(curthread->td_proc->p_fd, file, fd, curthread); } @@ -80,8 +84,10 @@ fd_install(unsigned int fd, struct linux_file *filp) { struct file *file; - if (fget_unlocked(curthread->td_proc->p_fd, fd, 0, 0, &file, NULL) != 0) + if (fget_unlocked(curthread->td_proc->p_fd, fd, NULL, 0, &file, + NULL) != 0) { file = NULL; + } filp->_file = file; finit(file, filp->f_mode, DTYPE_DEV, filp, &linuxfileops); } diff --git a/sys/security/audit/audit_bsm_klib.c b/sys/security/audit/audit_bsm_klib.c index 5f5d58b..d06c770 100644 --- a/sys/security/audit/audit_bsm_klib.c +++ b/sys/security/audit/audit_bsm_klib.c @@ -496,7 +496,7 @@ audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath) vhold(cvnp); } else { /* XXX: fgetvp() that vhold()s vnode instead of vref()ing it would be better */ - error = fgetvp(td, dirfd, 0, &cvnp); + error = fgetvp(td, dirfd, NULL, &cvnp); if (error) { cpath[0] = '\0'; if (rvnp != NULL) -- cgit v1.1 From e6563595d7cfad99895776be3e9ec77fdea16e84 Mon Sep 17 00:00:00 2001 From: pjd Date: Thu, 5 Sep 2013 11:59:23 +0000 Subject: The fget() function now takes pointer to cap_rights_t, so change 0 to NULL. --- sys/kern/vfs_aio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 9f3adaf..7f9f881 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -2050,7 +2050,7 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap) struct vnode *vp; /* Lookup file object. */ - error = fget(td, uap->fd, 0, &fp); + error = fget(td, uap->fd, NULL, &fp); if (error) return (error); -- cgit v1.1 From 7ab18d4990d80767c250514df82b25bd076c5801 Mon Sep 17 00:00:00 2001 From: kib Date: Thu, 5 Sep 2013 12:54:40 +0000 Subject: The vm_page_trysbusy() should not fail when shared busy counter or VPB_BIT_WAITERS flag were changed between reading of busy_lock and the cas. The vm_page_sbusy(), which is the only user of vm_page_trysbusy() in the tree, panics on the failure, which in these cases is transient and do not mean that the current page state prevents sbusying. Retry the operation inside vm_page_trysbusy() if cas failed, only return a failure when VPB_BIT_SHARED is cleared. Reported and tested by: pho Reviewed by: attilio Sponsored by: The FreeBSD Foundation --- sys/vm/vm_page.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 7b4b57c..53ffc72 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -602,9 +602,13 @@ vm_page_trysbusy(vm_page_t m) { u_int x; - x = m->busy_lock; - return ((x & VPB_BIT_SHARED) != 0 && - atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER)); + for (;;) { + x = m->busy_lock; + if ((x & VPB_BIT_SHARED) == 0) + return (0); + if (atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER)) + return (1); + } } /* -- cgit v1.1 From a08e5f97bc360935cbcff202e45eb4b92ececf39 Mon Sep 17 00:00:00 2001 From: kib Date: Thu, 5 Sep 2013 12:56:08 +0000 Subject: The vm_pageout_flush() functions sbusies pages in the passed pages run. After that, the pager put method is called, usually translated to VOP_WRITE(). For the filesystems which use buffer cache, bufwrite() sbusies the buffer pages again, waiting for the xbusy state to drain. The later is done in vfs_drain_busy_pages(), which is called with the buffer pages already sbusied (by vm_pageout_flush()). Since vfs_drain_busy_pages() can only wait for one page at the time, and during the wait, the object lock is dropped, previous pages in the buffer must be protected from other threads busying them. Up to the moment, it was done by xbusying the pages, that is incompatible with the sbusy state in the new implementation of busy. Switch to sbusy. Reported and tested by: pho Sponsored by: The FreeBSD Foundation --- sys/kern/vfs_bio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 04eab14..37ef663 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3994,7 +3994,7 @@ vfs_drain_busy_pages(struct buf *bp) m = bp->b_pages[i]; if (vm_page_xbusied(m)) { for (; last_busied < i; last_busied++) - vm_page_xbusy(bp->b_pages[last_busied]); + vm_page_sbusy(bp->b_pages[last_busied]); while (vm_page_xbusied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); @@ -4004,7 +4004,7 @@ vfs_drain_busy_pages(struct buf *bp) } } for (i = 0; i < last_busied; i++) - vm_page_xunbusy(bp->b_pages[i]); + vm_page_sunbusy(bp->b_pages[i]); } /* -- cgit v1.1 From 2260c8f4ea78c4431274c66a82768cb069ad231f Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 5 Sep 2013 13:46:30 +0000 Subject: Fix build. counter.h requires systm.h --- sys/sys/sf_buf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/sys/sf_buf.h b/sys/sys/sf_buf.h index 4c37e00..61643b0 100644 --- a/sys/sys/sf_buf.h +++ b/sys/sys/sf_buf.h @@ -54,6 +54,7 @@ struct sfstat { /* sendfile statistics */ #ifdef _KERNEL #include +#include #include struct mbuf; /* for sf_buf_mext() */ -- cgit v1.1 From 84626a2dc579eaf7b15be8df1efb74c26c778208 Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 5 Sep 2013 13:53:25 +0000 Subject: Fix build. --- sys/conf/files.powerpc | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 5808d85..fc0663e 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -30,6 +30,7 @@ dev/agp/agp_apple.c optional agp powermac dev/fb/fb.c optional sc dev/fdt/fdt_powerpc.c optional fdt dev/hwpmc/hwpmc_powerpc.c optional hwpmc +dev/hwpmc/hwpmc_mpc7xxx.c optional hwpmc dev/iicbus/ad7417.c optional ad7417 powermac dev/iicbus/ds1631.c optional ds1631 powermac dev/iicbus/ds1775.c optional ds1775 powermac -- cgit v1.1 From 057d03f1deec896feae9a7bfe79a5f8905997f06 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 5 Sep 2013 14:16:37 +0000 Subject: Use an unsigned long when indexing into mfchashtbl[] and mf6ctable[]. This matches the types used when computing hash indices and the type of the maximum size of mfchashtbl[]. PR: kern/181821 Submitted by: Sven-Thorsten Dietrich (IPv4) MFC after: 1 week --- sys/netinet/ip_mroute.c | 8 ++++---- sys/netinet6/ip6_mroute.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 6d3f990..d490bbe 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -609,7 +609,7 @@ static void if_detached_event(void *arg __unused, struct ifnet *ifp) { vifi_t vifi; - int i; + u_long i; MROUTER_LOCK(); @@ -705,7 +705,7 @@ static int X_ip_mrouter_done(void) { struct ifnet *ifp; - int i; + u_long i; vifi_t vifi; MROUTER_LOCK(); @@ -797,7 +797,7 @@ set_assert(int i) int set_api_config(uint32_t *apival) { - int i; + u_long i; /* * We can set the API capabilities only if it is the first operation @@ -1433,7 +1433,7 @@ non_fatal: static void expire_upcalls(void *arg) { - int i; + u_long i; CURVNET_SET((struct vnet *) arg); diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 9634636..36d0d6f 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -576,7 +576,7 @@ int X_ip6_mrouter_done(void) { mifi_t mifi; - int i; + u_long i; struct mf6c *rt; struct rtdetq *rte; @@ -1341,7 +1341,7 @@ expire_upcalls(void *unused) { struct rtdetq *rte; struct mf6c *mfc, **nptr; - int i; + u_long i; MFC6_LOCK(); for (i = 0; i < MF6CTBLSIZ; i++) { -- cgit v1.1 From 42eb0e69b4a01ca059fa4db4d572fa4154de4bb7 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 5 Sep 2013 14:26:37 +0000 Subject: Use LIST_FOREACH_SAFE() instead of doing it by hand. --- sys/netinet/ip_mroute.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index d490bbe..3a03def 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -634,8 +634,8 @@ if_detached_event(void *arg __unused, struct ifnet *ifp) continue; for (i = 0; i < mfchashsize; i++) { struct mfc *rt, *nrt; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); + + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { if (rt->mfc_parent == vifi) { expire_mfc(rt); } @@ -753,8 +753,8 @@ X_ip_mrouter_done(void) */ for (i = 0; i < mfchashsize; i++) { struct mfc *rt, *nrt; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); + + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { expire_mfc(rt); } } @@ -1445,9 +1445,7 @@ expire_upcalls(void *arg) if (V_nexpire[i] == 0) continue; - for (rt = LIST_FIRST(&V_mfchashtbl[i]); rt; rt = nrt) { - nrt = LIST_NEXT(rt, mfc_hash); - + LIST_FOREACH_SAFE(rt, &V_mfchashtbl[i], mfc_hash, nrt) { if (TAILQ_EMPTY(&rt->mfc_stall)) continue; -- cgit v1.1 From 48389c2d4751a6f9788e7acfb45a1ec1775f9628 Mon Sep 17 00:00:00 2001 From: sbruno Date: Thu, 5 Sep 2013 16:38:26 +0000 Subject: Minor printf nit to keep out clean --- sys/dev/gpio/gpiobus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c index d61f7aa..6abb10c 100644 --- a/sys/dev/gpio/gpiobus.c +++ b/sys/dev/gpio/gpiobus.c @@ -131,7 +131,7 @@ gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask) } if (npins == 0) { - device_printf(child, "empty pin mask"); + device_printf(child, "empty pin mask\n"); return (EINVAL); } -- cgit v1.1 From 04932445481c2cb89ff69a83b961bdef3d64757e Mon Sep 17 00:00:00 2001 From: hiren Date: Thu, 5 Sep 2013 18:18:23 +0000 Subject: Fixing a small typo. Reviewed by: gjb Approved by: sbruno (mentor) --- sys/kern/kern_mbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 4d45553..5d58942 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -106,7 +106,7 @@ int nmbjumbo16; /* limits number of 16k jumbo clusters */ static quad_t maxmbufmem; /* overall real memory limit for all mbufs */ SYSCTL_QUAD(_kern_ipc, OID_AUTO, maxmbufmem, CTLFLAG_RDTUN, &maxmbufmem, 0, - "Maximum real memory allocateable to various mbuf types"); + "Maximum real memory allocatable to various mbuf types"); /* * tunable_mbinit() has to be run before any mbuf allocations are done. -- cgit v1.1 From 75c7fb01d06cc21692c9eb0543738c53428a57e7 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 22:46:48 +0000 Subject: Add some logging to ntb link up. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/if_ntb/if_ntb.c | 15 ++++++++++++++- sys/dev/ntb/ntb_hw/ntb_hw.c | 6 ++++++ sys/dev/ntb/ntb_hw/ntb_hw.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 55b19c5..58a72dc 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -475,8 +475,11 @@ ntb_transport_init(struct ntb_softc *ntb) if (rc != 0) goto err; - if (ntb_query_link_status(ntb)) + if (ntb_query_link_status(ntb)) { + if (bootverbose) + device_printf(ntb_get_device(ntb), "link up\n"); callout_reset(&nt->link_work, 0, ntb_transport_link_work, nt); + } return (0); @@ -673,6 +676,8 @@ ntb_transport_link_up(struct ntb_transport_qp *qp) return; qp->client_ready = NTB_LINK_UP; + if (bootverbose) + device_printf(ntb_get_device(qp->ntb), "qp client ready\n"); if (qp->transport->transport_link == NTB_LINK_UP) callout_reset(&qp->link_work, 0, ntb_qp_link_work, qp); @@ -988,9 +993,13 @@ ntb_transport_event_callback(void *data, enum ntb_hw_event event) switch (event) { case NTB_EVENT_HW_LINK_UP: + if (bootverbose) + device_printf(ntb_get_device(nt->ntb), "HW link up\n"); callout_reset(&nt->link_work, 0, ntb_transport_link_work, nt); break; case NTB_EVENT_HW_LINK_DOWN: + if (bootverbose) + device_printf(ntb_get_device(nt->ntb), "HW link down\n"); ntb_transport_link_cleanup(nt); break; default: @@ -1071,6 +1080,8 @@ ntb_transport_link_work(void *arg) return; nt->transport_link = NTB_LINK_UP; + if (bootverbose) + device_printf(ntb_get_device(ntb), "transport link up\n"); for (i = 0; i < nt->max_qps; i++) { qp = &nt->qps[i]; @@ -1176,6 +1187,8 @@ ntb_qp_link_work(void *arg) qp->qp_link = NTB_LINK_UP; if (qp->event_handler != NULL) qp->event_handler(qp->cb_data, NTB_LINK_UP); + if (bootverbose) + device_printf(ntb_get_device(ntb), "qp link up\n"); } else if (nt->transport_link == NTB_LINK_UP) { callout_reset(&qp->link_work, NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_qp_link_work, qp); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 72314dd..2f1d65d 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -1286,3 +1286,9 @@ is_bar_for_data_transfer(int bar_num) else return false; } + +device_t ntb_get_device(struct ntb_softc *ntb) +{ + + return (ntb->device); +} diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.h b/sys/dev/ntb/ntb_hw/ntb_hw.h index 4f44031..c6c1274 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.h +++ b/sys/dev/ntb/ntb_hw/ntb_hw.h @@ -69,5 +69,6 @@ u_long ntb_get_mw_size(struct ntb_softc *ntb, unsigned int mw); void ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr); void ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db); bool ntb_query_link_status(struct ntb_softc *ntb); +device_t ntb_get_device(struct ntb_softc *ntb); #endif /* _NTB_HW_H_ */ -- cgit v1.1 From 78e005b631e1f4e22450fb705e1f37798b062aee Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 22:52:40 +0000 Subject: Throw a bit to enable the link to come up on Xeon. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 2f1d65d..cf5eb63 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -637,6 +637,10 @@ ntb_setup_xeon(struct ntb_softc *ntb) /* Enable Bus Master and Memory Space on the secondary side */ ntb_write_2(ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + /* Enable link training */ + ntb_write_4(ntb->reg_ofs.lnk_cntl, + NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); return (0); } -- cgit v1.1 From 03afdcfdc4ee03e6e3ca37aff3d6a1c3896fdb8d Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 22:56:52 +0000 Subject: Fix name change from ntb_transport to if_ntb. A few places were overlooked. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/if_ntb/if_ntb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 58a72dc..510bd75 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -279,14 +279,14 @@ ntb_handle_module_events(struct module *m, int what, void *arg) return (err); } -static moduledata_t ntb_transport_mod = { - "ntb_transport", +static moduledata_t if_ntb_mod = { + "if_ntb", ntb_handle_module_events, NULL }; -DECLARE_MODULE(ntb_transport, ntb_transport_mod, SI_SUB_KLD, SI_ORDER_ANY); -MODULE_DEPEND(ntb_transport, ntb_hw, 1, 1, 1); +DECLARE_MODULE(if_ntb, if_ntb_mod, SI_SUB_KLD, SI_ORDER_ANY); +MODULE_DEPEND(if_ntb, ntb_hw, 1, 1, 1); static int ntb_setup_interface() -- cgit v1.1 From 3186588c66b80d165e89fc5c9baf5c4f797dbbf3 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 22:59:18 +0000 Subject: Restructure the PCI bar initialization code in anticipation of upcoming bug fixes. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 146 ++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 53 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index cf5eb63..9f57d6e 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -161,10 +161,18 @@ struct ntb_softc { #define ntb_write_4(offset, val) ntb_reg_write(4, (offset), (val)) #define ntb_write_8(offset, val) ntb_reg_write(8, (offset), (val)) +typedef int (*bar_map_strategy)(struct ntb_softc *ntb, + struct ntb_pci_bar_info *bar); + static int ntb_probe(device_t device); static int ntb_attach(device_t device); static int ntb_detach(device_t device); -static int ntb_map_pci_bar(struct ntb_softc *ntb); +static int ntb_map_pci_bars(struct ntb_softc *ntb); +static int map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, + struct ntb_pci_bar_info *bar); +static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); +static int map_memory_window_bar(struct ntb_softc *ntb, + struct ntb_pci_bar_info *bar); static void ntb_unmap_pci_bar(struct ntb_softc *ntb); static int ntb_setup_interrupts(struct ntb_softc *ntb); static void ntb_teardown_interrupts(struct ntb_softc *ntb); @@ -250,7 +258,7 @@ ntb_attach(device_t device) callout_init(&ntb->heartbeat_timer, CALLOUT_MPSAFE); callout_init(&ntb->lr_timer, CALLOUT_MPSAFE); - DETACH_ON_ERROR(ntb_map_pci_bar(ntb)); + DETACH_ON_ERROR(ntb_map_pci_bars(ntb)); DETACH_ON_ERROR(ntb_initialize_hw(ntb)); DETACH_ON_ERROR(ntb_setup_interrupts(ntb)); @@ -273,59 +281,84 @@ ntb_detach(device_t device) } static int -ntb_map_pci_bar(struct ntb_softc *ntb) +ntb_map_pci_bars(struct ntb_softc *ntb) { - struct ntb_pci_bar_info *current_bar; - int rc, i; + int rc; ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); + rc = map_pci_bar(ntb, map_mmr_bar, &ntb->bar_info[NTB_CONFIG_BAR]); + if (rc != 0) + return rc; + ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2); + rc = map_pci_bar(ntb, map_memory_window_bar, + &ntb->bar_info[NTB_B2B_BAR_1]); + if (rc != 0) + return rc; + ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); + rc = map_pci_bar(ntb, map_memory_window_bar, + &ntb->bar_info[NTB_B2B_BAR_2]); + if (rc != 0) + return rc; + + return (0); +} - for (i = 0; i< NTB_MAX_BARS; i++) { - current_bar = &ntb->bar_info[i]; - current_bar->pci_resource = - bus_alloc_resource(ntb->device, - SYS_RES_MEMORY, - ¤t_bar->pci_resource_id, 0, ~0, 1, +static int +map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, + struct ntb_pci_bar_info *bar) +{ + int rc; + + rc = strategy(ntb, bar); + if (rc != 0) { + device_printf(ntb->device, + "unable to allocate pci resource\n"); + } else { + device_printf(ntb->device, + "Bar size = %lx, v %p, p %p\n", + bar->size, bar->vbase, + (void *)(bar->pbase)); + } + return (rc); +} + +static int +map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + + bar->pci_resource = bus_alloc_resource(ntb->device, SYS_RES_MEMORY, + &bar->pci_resource_id, 0, ~0, 1, RF_ACTIVE); + + if (bar->pci_resource == NULL) + return (ENXIO); + else { + save_bar_parameters(bar); + return (0); + } +} + +static int +map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + int rc; + + bar->pci_resource = bus_alloc_resource(ntb->device, + SYS_RES_MEMORY, &bar->pci_resource_id, 0, ~0, 1, RF_ACTIVE); - if (current_bar->pci_resource == NULL) { - device_printf(ntb->device, - "unable to allocate pci resource\n"); - return (ENXIO); - } - else { - current_bar->pci_bus_tag = - rman_get_bustag(current_bar->pci_resource); - current_bar->pci_bus_handle = - rman_get_bushandle(current_bar->pci_resource); - current_bar->pbase = - rman_get_start(current_bar->pci_resource); - current_bar->size = - rman_get_size(current_bar->pci_resource); - current_bar->vbase = - rman_get_virtual(current_bar->pci_resource); - if (is_bar_for_data_transfer(i)) { - /* - * Mark bar region as write combining to improve - * performance. - */ - rc = pmap_change_attr( - (vm_offset_t)current_bar->vbase, - current_bar->size, - VM_MEMATTR_WRITE_COMBINING); - if (rc != 0) { - device_printf(ntb->device, - "Couldn't mark bar as" - " WRITE_COMBINING\n"); - return (rc); - } - } - device_printf(ntb->device, - "Bar size = %lx, v %p, p %p\n", - current_bar->size, current_bar->vbase, - (void *)(current_bar->pbase)); + if (bar->pci_resource == NULL) + return (ENXIO); + else { + save_bar_parameters(bar); + /* Mark bar region as write combining to improve performance. */ + rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, + VM_MEMATTR_WRITE_COMBINING); + if (rc != 0) { + device_printf(ntb->device, "unable to mark bar as" + " WRITE_COMBINING\n"); + return (rc); } } return (0); @@ -1282,13 +1315,20 @@ ntb_query_link_status(struct ntb_softc *ntb) return (ntb->link_status == NTB_LINK_UP); } -static bool -is_bar_for_data_transfer(int bar_num) +static void +save_bar_parameters(struct ntb_pci_bar_info *bar) { - if ((bar_num > NTB_CONFIG_BAR) && (bar_num < NTB_MAX_BARS)) - return true; - else - return false; + bar->pci_bus_tag = + rman_get_bustag(bar->pci_resource); + bar->pci_bus_handle = + rman_get_bushandle(bar->pci_resource); + bar->pbase = + rman_get_start(bar->pci_resource); + bar->size = + rman_get_size(bar->pci_resource); + bar->vbase = + rman_get_virtual(bar->pci_resource); + } device_t ntb_get_device(struct ntb_softc *ntb) -- cgit v1.1 From 4a4705a68f34369a392b078ab713a3e44a50a512 Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Thu, 5 Sep 2013 23:00:24 +0000 Subject: Align stacks of kernel threads correctly at 16-byte boundaries rather than making sure they are all misaligned at +8 bytes. This fixes clang builds of powerpc64 kernels (aside from a required increase in KSTACK_PAGES which will come later). This commit from FreeBSD/powerpc64 with a clang-built kernel. MFC after: 2 weeks --- sys/powerpc/aim/vm_machdep.c | 1 + sys/powerpc/include/frame.h | 1 + 2 files changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index 2deb4cb..1790ce3 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -187,6 +187,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) cf->cf_arg1 = (register_t)tf; pcb->pcb_sp = (register_t)cf; + KASSERT(pcb->pcb_sp % 16 == 0, ("stack misaligned")); #ifdef __powerpc64__ pcb->pcb_lr = ((register_t *)fork_trampoline)[0]; pcb->pcb_toc = ((register_t *)fork_trampoline)[1]; diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 196cb6f..092827d 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -94,6 +94,7 @@ struct callframe { register_t cf_func; register_t cf_arg0; register_t cf_arg1; + register_t _padding; /* Maintain 16-byte alignment */ }; #else struct callframe { -- cgit v1.1 From e892e8d51e841ee04f52e130b4326671b2f3362c Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:00:59 +0000 Subject: Add support for per device features and workarounds. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 9f57d6e..3605045 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -76,10 +76,18 @@ enum ntb_device_type { NTB_SOC }; +/* Device features and workarounds */ +#define HAS_FEATURE(feature) \ + ((ntb->features & (feature)) != 0) + +#define NTB_BAR_SIZE_4K (1 << 0) +#define NTB_REGS_THRU_MW (1 << 1) + struct ntb_hw_info { uint32_t device_id; - enum ntb_device_type type; const char *desc; + enum ntb_device_type type; + uint64_t features; }; struct ntb_pci_bar_info { @@ -108,6 +116,7 @@ struct ntb_db_cb { struct ntb_softc { device_t device; enum ntb_device_type type; + uint64_t features; struct ntb_pci_bar_info bar_info[NTB_MAX_BARS]; struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; @@ -190,13 +199,15 @@ static void ntb_handle_heartbeat(void *arg); static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state); static void recover_soc_link(void *arg); static int ntb_check_link_status(struct ntb_softc *ntb); -static bool is_bar_for_data_transfer(int bar_num); +static void save_bar_parameters(struct ntb_pci_bar_info *bar); static struct ntb_hw_info pci_ids[] = { - { 0x3C0D8086, NTB_XEON, "Xeon E5/Core i7 Non-Transparent Bridge B2B" }, - { 0x0C4E8086, NTB_SOC, "Atom Processor S1200 NTB Primary B2B" }, - { 0x0E0D8086, NTB_XEON, "Xeon E5 V2 Non-Transparent Bridge B2B" }, - { 0x00000000, NTB_SOC, NULL } + { 0x3C0D8086, "Xeon E5/Core i7 Non-Transparent Bridge B2B", NTB_XEON, + NTB_REGS_THRU_MW }, + { 0x0C4E8086, "Atom Processor S1200 NTB Primary B2B", NTB_SOC, 0 }, + { 0x0E0D8086, "Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON, + NTB_REGS_THRU_MW | NTB_BAR_SIZE_4K }, + { 0x00000000, NULL, NTB_SOC, 0 } }; /* @@ -253,6 +264,7 @@ ntb_attach(device_t device) ntb->device = device; ntb->type = p->type; + ntb->features = p->features; /* Heartbeat timer for NTB_SOC since there is no link interrupt */ callout_init(&ntb->heartbeat_timer, CALLOUT_MPSAFE); @@ -301,7 +313,7 @@ ntb_map_pci_bars(struct ntb_softc *ntb) &ntb->bar_info[NTB_B2B_BAR_2]); if (rc != 0) return rc; - + return (0); } -- cgit v1.1 From a7f877c285a87c2fcb83ce0b0d7560d1530ca3b5 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:02:43 +0000 Subject: Simplifying bus alloc resource call since we only need the default values. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 3605045..9a152d5 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -340,8 +340,8 @@ static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) { - bar->pci_resource = bus_alloc_resource(ntb->device, SYS_RES_MEMORY, - &bar->pci_resource_id, 0, ~0, 1, RF_ACTIVE); + bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, + &bar->pci_resource_id, RF_ACTIVE); if (bar->pci_resource == NULL) return (ENXIO); @@ -356,9 +356,8 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) { int rc; - bar->pci_resource = bus_alloc_resource(ntb->device, - SYS_RES_MEMORY, &bar->pci_resource_id, 0, ~0, 1, - RF_ACTIVE); + bar->pci_resource = bus_alloc_resource_any(ntb->device, + SYS_RES_MEMORY, &bar->pci_resource_id, RF_ACTIVE); if (bar->pci_resource == NULL) return (ENXIO); -- cgit v1.1 From 7afa0361ff928819d5c11e6acb5eb2fcc555edeb Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:04:36 +0000 Subject: Implement workaround for IvyTown 4K BAR size issue. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 35 +++++++++++++++++++++++++++++++++++ sys/dev/ntb/ntb_hw/ntb_regs.h | 2 ++ 2 files changed, 37 insertions(+) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 9a152d5..0f805b2 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -355,6 +355,7 @@ static int map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) { int rc; + uint8_t bar_size_bits = 0; bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, &bar->pci_resource_id, RF_ACTIVE); @@ -363,6 +364,40 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) return (ENXIO); else { save_bar_parameters(bar); + /* + * Ivytown NTB BAR sizes are misreported by the hardware due to + * a hardware issue. To work around this, query the size it + * should be configured to by the device and modify the resource + * to correspond to this new size. The BIOS on systems with this + * problem is required to provide enough address space to allow + * the driver to make this change safely. + * + * Ideally I could have just specified the size when I allocated + * the resource like: + * bus_alloc_resource(ntb->device, + * SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul, + * 1ul << bar_size_bits, RF_ACTIVE); + * but the PCI driver does not honor the size in this call, so + * we have to modify it after the fact. + */ + if (HAS_FEATURE(BAR_SIZE_4K)) { + if (bar->pci_resource_id == PCIR_BAR(2)) + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR23SZ_OFFSET, 1); + else + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR45SZ_OFFSET, 1); + rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY, + bar->pci_resource, bar->pbase, + bar->pbase + (1ul << bar_size_bits) - 1); + if (rc != 0 ) { + device_printf(ntb->device, + "unable to resize bar\n"); + return (rc); + } else + save_bar_parameters(bar); + } + /* Mark bar region as write combining to improve performance. */ rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, VM_MEMATTR_WRITE_COMBINING); diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h index 34ad779..2f1cdeb 100644 --- a/sys/dev/ntb/ntb_hw/ntb_regs.h +++ b/sys/dev/ntb/ntb_hw/ntb_regs.h @@ -120,6 +120,8 @@ #define NTB_CNTL_BAR45_SNOOP (1 << 6) #define SOC_CNTL_LINK_DOWN (1 << 16) +#define XEON_PBAR23SZ_OFFSET 0x00d0 +#define XEON_PBAR45SZ_OFFSET 0x00d1 #define NTB_PPD_OFFSET 0x00D4 #define XEON_PPD_CONN_TYPE 0x0003 #define XEON_PPD_DEV_TYPE 0x0010 -- cgit v1.1 From e954db63c249015048e368a02ecdab722b678810 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:06:25 +0000 Subject: Cleaning up spacing and making hex value case consistent. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_regs.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h index 2f1cdeb..8dd2568 100644 --- a/sys/dev/ntb/ntb_hw/ntb_regs.h +++ b/sys/dev/ntb/ntb_hw/ntb_regs.h @@ -39,14 +39,14 @@ #define XEON_MAX_SPADS 16 #define XEON_MAX_COMPAT_SPADS 8 /* Reserve the uppermost bit for link interrupt */ -#define XEON_MAX_DB_BITS 15 +#define XEON_MAX_DB_BITS 15 #define XEON_DB_BITS_PER_VEC 5 #define XEON_DB_HW_LINK 0x8000 #define XEON_PCICMD_OFFSET 0x0504 #define XEON_DEVCTRL_OFFSET 0x0598 -#define XEON_LINK_STATUS_OFFSET 0x01A2 +#define XEON_LINK_STATUS_OFFSET 0x01a2 #define XEON_PBAR2LMT_OFFSET 0x0000 #define XEON_PBAR4LMT_OFFSET 0x0008 @@ -60,13 +60,13 @@ #define XEON_SBAR2BASE_OFFSET 0x0048 #define XEON_SBAR4BASE_OFFSET 0x0050 #define XEON_NTBCNTL_OFFSET 0x0058 -#define XEON_SBDF_OFFSET 0x005C +#define XEON_SBDF_OFFSET 0x005c #define XEON_PDOORBELL_OFFSET 0x0060 #define XEON_PDBMSK_OFFSET 0x0062 #define XEON_SDOORBELL_OFFSET 0x0064 #define XEON_SDBMSK_OFFSET 0x0066 #define XEON_USMEMMISS 0x0070 -#define XEON_SPAD_OFFSET 0x0080 +#define XEON_SPAD_OFFSET 0x0080 #define XEON_SPADSEMA4_OFFSET 0x00c0 #define XEON_WCCNTRL_OFFSET 0x00e0 #define XEON_B2B_SPAD_OFFSET 0x0100 @@ -105,7 +105,7 @@ #define SOC_MODPHY_PCSREG4 0x1c004 #define SOC_MODPHY_PCSREG6 0x1c006 -#define SOC_IP_BASE 0xC000 +#define SOC_IP_BASE 0xc000 #define SOC_DESKEWSTS_OFFSET (SOC_IP_BASE + 0x3024) #define SOC_LTSSMERRSTS0_OFFSET (SOC_IP_BASE + 0x3180) #define SOC_LTSSMSTATEJMP_OFFSET (SOC_IP_BASE + 0x3040) @@ -114,7 +114,7 @@ #define SOC_DESKEWSTS_DBERR (1 << 15) #define SOC_LTSSMERRSTS0_UNEXPECTEDEI (1 << 20) #define SOC_LTSSMSTATEJMP_FORCEDETECT (1 << 2) -#define SOC_IBIST_ERR_OFLOW 0x7FFF7FFF +#define SOC_IBIST_ERR_OFLOW 0x7fff7fff #define NTB_CNTL_BAR23_SNOOP (1 << 2) #define NTB_CNTL_BAR45_SNOOP (1 << 6) @@ -122,7 +122,7 @@ #define XEON_PBAR23SZ_OFFSET 0x00d0 #define XEON_PBAR45SZ_OFFSET 0x00d1 -#define NTB_PPD_OFFSET 0x00D4 +#define NTB_PPD_OFFSET 0x00d4 #define XEON_PPD_CONN_TYPE 0x0003 #define XEON_PPD_DEV_TYPE 0x0010 #define SOC_PPD_INIT_LINK 0x0008 @@ -138,11 +138,11 @@ #define SOC_PBAR2XLAT_USD_ADDR 0x0000004000000000 #define SOC_PBAR4XLAT_USD_ADDR 0x0000008000000000 -#define SOC_MBAR23_USD_ADDR 0x000000410000000C -#define SOC_MBAR45_USD_ADDR 0x000000810000000C +#define SOC_MBAR23_USD_ADDR 0x000000410000000c +#define SOC_MBAR45_USD_ADDR 0x000000810000000c #define SOC_PBAR2XLAT_DSD_ADDR 0x0000004100000000 #define SOC_PBAR4XLAT_DSD_ADDR 0x0000008100000000 -#define SOC_MBAR23_DSD_ADDR 0x000000400000000C -#define SOC_MBAR45_DSD_ADDR 0x000000800000000C +#define SOC_MBAR23_DSD_ADDR 0x000000400000000c +#define SOC_MBAR45_DSD_ADDR 0x000000800000000c #endif /* _NTB_REGS_H_ */ -- cgit v1.1 From ff47ca437bb163a5622316f588e14d8aa788f9b3 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:08:22 +0000 Subject: Simplify register access macros by removing one level of indirection. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 124 +++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 66 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 0f805b2..9fb36d1 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -161,14 +161,6 @@ struct ntb_softc { bus_space_write_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset), (val)) -#define ntb_read_1(offset) ntb_reg_read(1, (offset)) -#define ntb_read_2(offset) ntb_reg_read(2, (offset)) -#define ntb_read_4(offset) ntb_reg_read(4, (offset)) -#define ntb_read_8(offset) ntb_reg_read(8, (offset)) -#define ntb_write_1(offset, val) ntb_reg_write(1, (offset), (val)) -#define ntb_write_2(offset, val) ntb_reg_write(2, (offset), (val)) -#define ntb_write_4(offset, val) ntb_reg_write(4, (offset), (val)) -#define ntb_write_8(offset, val) ntb_reg_write(8, (offset), (val)) typedef int (*bar_map_strategy)(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); @@ -440,9 +432,9 @@ ntb_setup_interrupts(struct ntb_softc *ntb) * Interrupt. The rest will be unmasked as callbacks are registered. */ if (ntb->type == NTB_SOC) - ntb_write_8(ntb->reg_ofs.pdb_mask, ~0); + ntb_reg_write(8, ntb->reg_ofs.pdb_mask, ~0); else - ntb_write_2(ntb->reg_ofs.pdb_mask, + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, ~(1 << ntb->limits.max_db_bits)); num_vectors = MIN(pci_msix_count(ntb->device), @@ -542,7 +534,7 @@ handle_soc_irq(void *arg) struct ntb_db_cb *db_cb = arg; struct ntb_softc *ntb = db_cb->ntb; - ntb_write_8(ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); + ntb_reg_write(8, ntb->reg_ofs.pdb, (uint64_t) 1 << db_cb->db_num); if (db_cb->callback != NULL) db_cb->callback(db_cb->data, db_cb->db_num); @@ -560,7 +552,7 @@ handle_xeon_irq(void *arg) * vectors, with the 4th having a single bit for link * interrupts. */ - ntb_write_2(ntb->reg_ofs.pdb, + ntb_reg_write(2, ntb->reg_ofs.pdb, ((1 << ntb->bits_per_vector) - 1) << (db_cb->db_num * ntb->bits_per_vector)); @@ -580,7 +572,7 @@ handle_xeon_event_irq(void *arg) device_printf(ntb->device, "Error determining link status\n"); /* bit 15 is always the link bit */ - ntb_write_2(ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); + ntb_reg_write(2, ntb->reg_ofs.pdb, 1 << ntb->limits.max_db_bits); } static void @@ -592,7 +584,7 @@ ntb_handle_legacy_interrupt(void *arg) uint16_t pdb16; if (ntb->type == NTB_SOC) { - pdb64 = ntb_read_8(ntb->reg_ofs.pdb); + pdb64 = ntb_reg_read(8, ntb->reg_ofs.pdb); while (pdb64) { i = ffs(pdb64); @@ -600,7 +592,7 @@ ntb_handle_legacy_interrupt(void *arg) handle_soc_irq(&ntb->db_cb[i]); } } else { - pdb16 = ntb_read_2(ntb->reg_ofs.pdb); + pdb16 = ntb_reg_read(2, ntb->reg_ofs.pdb); if ((pdb16 & XEON_DB_HW_LINK) != 0) { handle_xeon_event_irq(ntb); @@ -714,11 +706,11 @@ ntb_setup_xeon(struct ntb_softc *ntb) ntb->bits_per_vector = XEON_DB_BITS_PER_VEC; /* Enable Bus Master and Memory Space on the secondary side */ - ntb_write_2(ntb->reg_ofs.spci_cmd, + ntb_reg_write(2, ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); /* Enable link training */ - ntb_write_4(ntb->reg_ofs.lnk_cntl, + ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); return (0); @@ -786,37 +778,37 @@ ntb_setup_soc(struct ntb_softc *ntb) * Check and correct the issue. */ if (ntb->dev_type == NTB_DEV_USD) { - if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR2XLAT_OFFSET, + if (ntb_reg_read(8, SOC_PBAR2XLAT_OFFSET) == 0) + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, SOC_PBAR2XLAT_USD_ADDR); - if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR4XLAT_OFFSET, + if (ntb_reg_read(8, SOC_PBAR4XLAT_OFFSET) == 0) + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, SOC_PBAR4XLAT_USD_ADDR); - if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_USD_ADDR); + if (ntb_reg_read(8, SOC_MBAR23_OFFSET) == 0xC) + ntb_reg_write(8, SOC_MBAR23_OFFSET, SOC_MBAR23_USD_ADDR); - if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_USD_ADDR); + if (ntb_reg_read(8, SOC_MBAR45_OFFSET) == 0xC) + ntb_reg_write(8, SOC_MBAR45_OFFSET, SOC_MBAR45_USD_ADDR); } else { - if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR2XLAT_OFFSET, + if (ntb_reg_read(8, SOC_PBAR2XLAT_OFFSET) == 0) + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, SOC_PBAR2XLAT_DSD_ADDR); - if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0) - ntb_write_8(SOC_PBAR4XLAT_OFFSET, + if (ntb_reg_read(8, SOC_PBAR4XLAT_OFFSET) == 0) + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, SOC_PBAR4XLAT_DSD_ADDR); - if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR); + if (ntb_reg_read(8, SOC_MBAR23_OFFSET) == 0xC) + ntb_reg_write(8, SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR); - if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC) - ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR); + if (ntb_reg_read(8, SOC_MBAR45_OFFSET) == 0xC) + ntb_reg_write(8, SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR); } /* Enable Bus Master and Memory Space on the secondary side */ - ntb_write_2(ntb->reg_ofs.spci_cmd, + ntb_reg_write(2, ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb); @@ -836,7 +828,7 @@ ntb_handle_heartbeat(void *arg) "Error determining link status\n"); /* Check to see if a link error is the cause of the link down */ if (ntb->link_status == NTB_LINK_DOWN) { - status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) { callout_reset(&ntb->lr_timer, 0, recover_soc_link, ntb); @@ -854,37 +846,37 @@ soc_perform_link_restart(struct ntb_softc *ntb) uint32_t status; /* Driver resets the NTB ModPhy lanes - magic! */ - ntb_write_1(SOC_MODPHY_PCSREG6, 0xe0); - ntb_write_1(SOC_MODPHY_PCSREG4, 0x40); - ntb_write_1(SOC_MODPHY_PCSREG4, 0x60); - ntb_write_1(SOC_MODPHY_PCSREG6, 0x60); + ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0xe0); + ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x40); + ntb_reg_write(1, SOC_MODPHY_PCSREG4, 0x60); + ntb_reg_write(1, SOC_MODPHY_PCSREG6, 0x60); /* Driver waits 100ms to allow the NTB ModPhy to settle */ pause("ModPhy", hz / 10); /* Clear AER Errors, write to clear */ - status = ntb_read_4(SOC_ERRCORSTS_OFFSET); + status = ntb_reg_read(4, SOC_ERRCORSTS_OFFSET); status &= PCIM_AER_COR_REPLAY_ROLLOVER; - ntb_write_4(SOC_ERRCORSTS_OFFSET, status); + ntb_reg_write(4, SOC_ERRCORSTS_OFFSET, status); /* Clear unexpected electrical idle event in LTSSM, write to clear */ - status = ntb_read_4(SOC_LTSSMERRSTS0_OFFSET); + status = ntb_reg_read(4, SOC_LTSSMERRSTS0_OFFSET); status |= SOC_LTSSMERRSTS0_UNEXPECTEDEI; - ntb_write_4(SOC_LTSSMERRSTS0_OFFSET, status); + ntb_reg_write(4, SOC_LTSSMERRSTS0_OFFSET, status); /* Clear DeSkew Buffer error, write to clear */ - status = ntb_read_4(SOC_DESKEWSTS_OFFSET); + status = ntb_reg_read(4, SOC_DESKEWSTS_OFFSET); status |= SOC_DESKEWSTS_DBERR; - ntb_write_4(SOC_DESKEWSTS_OFFSET, status); + ntb_reg_write(4, SOC_DESKEWSTS_OFFSET, status); - status = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); + status = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); status &= SOC_IBIST_ERR_OFLOW; - ntb_write_4(SOC_IBSTERRRCRVSTS0_OFFSET, status); + ntb_reg_write(4, SOC_IBSTERRRCRVSTS0_OFFSET, status); /* Releases the NTB state machine to allow the link to retrain */ - status = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); status &= ~SOC_LTSSMSTATEJMP_FORCEDETECT; - ntb_write_4(SOC_LTSSMSTATEJMP_OFFSET, status); + ntb_reg_write(4, SOC_LTSSMSTATEJMP_OFFSET, status); } static void @@ -902,7 +894,7 @@ ntb_handle_link_event(struct ntb_softc *ntb, int link_state) event = NTB_EVENT_HW_LINK_UP; if (ntb->type == NTB_SOC) - status = ntb_read_2(ntb->reg_ofs.lnk_stat); + status = ntb_reg_read(2, ntb->reg_ofs.lnk_stat); else status = pci_read_config(ntb->device, XEON_LINK_STATUS_OFFSET, 2); @@ -935,15 +927,15 @@ recover_soc_link(void *arg) soc_perform_link_restart(ntb); pause("Link", SOC_LINK_RECOVERY_TIME * hz / 1000); - status32 = ntb_read_4(SOC_LTSSMSTATEJMP_OFFSET); + status32 = ntb_reg_read(4, SOC_LTSSMSTATEJMP_OFFSET); if ((status32 & SOC_LTSSMSTATEJMP_FORCEDETECT) != 0) goto retry; - status32 = ntb_read_4(SOC_IBSTERRRCRVSTS0_OFFSET); + status32 = ntb_reg_read(4, SOC_IBSTERRRCRVSTS0_OFFSET); if ((status32 & SOC_IBIST_ERR_OFLOW) != 0) goto retry; - status16 = ntb_read_2(ntb->reg_ofs.lnk_stat); + status16 = ntb_reg_read(2, ntb->reg_ofs.lnk_stat); width = (status16 & NTB_LINK_WIDTH_MASK) >> 4; speed = (status16 & NTB_LINK_SPEED_MASK); if (ntb->link_width != width || ntb->link_speed != speed) @@ -966,7 +958,7 @@ ntb_check_link_status(struct ntb_softc *ntb) uint16_t status; if (ntb->type == NTB_SOC) { - ntb_cntl = ntb_read_4(ntb->reg_ofs.lnk_cntl); + ntb_cntl = ntb_reg_read(4, ntb->reg_ofs.lnk_cntl); if ((ntb_cntl & SOC_CNTL_LINK_DOWN) != 0) link_state = NTB_LINK_DOWN; else @@ -1048,9 +1040,9 @@ ntb_register_db_callback(struct ntb_softc *ntb, unsigned int idx, void *data, ntb->db_cb[idx].data = data; /* unmask interrupt */ - mask = ntb_read_2(ntb->reg_ofs.pdb_mask); + mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask); mask &= ~(1 << (idx * ntb->bits_per_vector)); - ntb_write_2(ntb->reg_ofs.pdb_mask, mask); + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask); return (0); } @@ -1071,9 +1063,9 @@ ntb_unregister_db_callback(struct ntb_softc *ntb, unsigned int idx) if (idx >= ntb->allocated_interrupts || !ntb->db_cb[idx].callback) return; - mask = ntb_read_2(ntb->reg_ofs.pdb_mask); + mask = ntb_reg_read(2, ntb->reg_ofs.pdb_mask); mask |= 1 << (idx * ntb->bits_per_vector); - ntb_write_2(ntb->reg_ofs.pdb_mask, mask); + ntb_reg_write(2, ntb->reg_ofs.pdb_mask, mask); ntb->db_cb[idx].callback = NULL; } @@ -1174,7 +1166,7 @@ ntb_write_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) if (idx >= ntb->limits.max_spads) return (EINVAL); - ntb_write_4(ntb->reg_ofs.spad_local + idx * 4, val); + ntb_reg_write(4, ntb->reg_ofs.spad_local + idx * 4, val); return (0); } @@ -1197,7 +1189,7 @@ ntb_read_local_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) if (idx >= ntb->limits.max_spads) return (EINVAL); - *val = ntb_read_4(ntb->reg_ofs.spad_local + idx * 4); + *val = ntb_reg_read(4, ntb->reg_ofs.spad_local + idx * 4); return (0); } @@ -1220,7 +1212,7 @@ ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) if (idx >= ntb->limits.max_spads) return (EINVAL); - ntb_write_4(ntb->reg_ofs.spad_remote + idx * 4, val); + ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val); return (0); } @@ -1243,7 +1235,7 @@ ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) if (idx >= ntb->limits.max_spads) return (EINVAL); - *val = ntb_read_4(ntb->reg_ofs.spad_remote + idx * 4); + *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4); return (0); } @@ -1316,10 +1308,10 @@ ntb_set_mw_addr(struct ntb_softc *ntb, unsigned int mw, uint64_t addr) switch (NTB_MW_TO_BAR(mw)) { case NTB_B2B_BAR_1: - ntb_write_8(ntb->reg_ofs.sbar2_xlat, addr); + ntb_reg_write(8, ntb->reg_ofs.sbar2_xlat, addr); break; case NTB_B2B_BAR_2: - ntb_write_8(ntb->reg_ofs.sbar4_xlat, addr); + ntb_reg_write(8, ntb->reg_ofs.sbar4_xlat, addr); break; } } @@ -1339,9 +1331,9 @@ ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db) { if (ntb->type == NTB_SOC) - ntb_write_8(ntb->reg_ofs.sdb, (uint64_t) 1 << db); + ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db); else - ntb_write_2(ntb->reg_ofs.sdb, + ntb_reg_write(2, ntb->reg_ofs.sdb, ((1 << ntb->bits_per_vector) - 1) << (db * ntb->bits_per_vector)); } -- cgit v1.1 From 5b65301bba2c9d1eb34118038ebddd68ae2d6826 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:11:11 +0000 Subject: Workaround an issue with hardware by accessing remote device through mem window. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/ntb_hw/ntb_hw.c | 142 ++++++++++++++++++++++++++---------------- sys/dev/ntb/ntb_hw/ntb_regs.h | 22 ++++--- 2 files changed, 104 insertions(+), 60 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index 9fb36d1..c81593c 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -154,13 +154,18 @@ struct ntb_softc { uint8_t link_speed; }; -#define ntb_reg_read(SIZE, offset) \ - bus_space_read_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ - ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset)) +#define ntb_bar_read(SIZE, bar, offset) \ + bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset)) +#define ntb_bar_write(SIZE, bar, offset, val) \ + bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset), (val)) +#define ntb_reg_read(SIZE, offset) ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset) #define ntb_reg_write(SIZE, offset, val) \ - bus_space_write_ ## SIZE (ntb->bar_info[NTB_CONFIG_BAR].pci_bus_tag, \ - ntb->bar_info[NTB_CONFIG_BAR].pci_bus_handle, (offset), (val)) - + ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val) +#define ntb_mw_read(SIZE, offset) ntb_bar_read(SIZE, NTB_B2B_BAR_2, offset) +#define ntb_mw_write(SIZE, offset, val) \ + ntb_bar_write(SIZE, NTB_B2B_BAR_2, offset, val) typedef int (*bar_map_strategy)(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); @@ -187,6 +192,8 @@ static struct ntb_hw_info *ntb_get_device_info(uint32_t device_id); static int ntb_initialize_hw(struct ntb_softc *ntb); static int ntb_setup_xeon(struct ntb_softc *ntb); static int ntb_setup_soc(struct ntb_softc *ntb); +static void configure_soc_secondary_side_bars(struct ntb_softc *ntb); +static void configure_xeon_secondary_side_bars(struct ntb_softc *ntb); static void ntb_handle_heartbeat(void *arg); static void ntb_handle_link_event(struct ntb_softc *ntb, int link_state); static void recover_soc_link(void *arg); @@ -301,8 +308,12 @@ ntb_map_pci_bars(struct ntb_softc *ntb) return rc; ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); - rc = map_pci_bar(ntb, map_memory_window_bar, - &ntb->bar_info[NTB_B2B_BAR_2]); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + rc = map_pci_bar(ntb, map_mmr_bar, + &ntb->bar_info[NTB_B2B_BAR_2]); + else + rc = map_pci_bar(ntb, map_memory_window_bar, + &ntb->bar_info[NTB_B2B_BAR_2]); if (rc != 0) return rc; @@ -320,7 +331,7 @@ map_pci_bar(struct ntb_softc *ntb, bar_map_strategy strategy, device_printf(ntb->device, "unable to allocate pci resource\n"); } else { - device_printf(ntb->device, + device_printf(ntb->device, "Bar size = %lx, v %p, p %p\n", bar->size, bar->vbase, (void *)(bar->pbase)); @@ -372,7 +383,7 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) * but the PCI driver does not honor the size in this call, so * we have to modify it after the fact. */ - if (HAS_FEATURE(BAR_SIZE_4K)) { + if (HAS_FEATURE(NTB_BAR_SIZE_4K)) { if (bar->pci_resource_id == PCIR_BAR(2)) bar_size_bits = pci_read_config(ntb->device, XEON_PBAR23SZ_OFFSET, 1); @@ -464,7 +475,8 @@ ntb_setup_interrupts(struct ntb_softc *ntb) int_arg = &ntb->db_cb[i]; } else { if (i == num_vectors - 1) { - interrupt_handler = handle_xeon_event_irq; + interrupt_handler = + handle_xeon_event_irq; int_arg = ntb; } else { interrupt_handler = @@ -484,8 +496,8 @@ ntb_setup_interrupts(struct ntb_softc *ntb) } else { ntb->int_info[0].rid = 0; - ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, - &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); + ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, + SYS_RES_IRQ, &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); interrupt_handler = ntb_handle_legacy_interrupt; if (ntb->int_info[0].res == NULL) { device_printf(ntb->device, @@ -705,10 +717,11 @@ ntb_setup_xeon(struct ntb_softc *ntb) ntb->limits.msix_cnt = XEON_MSIX_CNT; ntb->bits_per_vector = XEON_DB_BITS_PER_VEC; + configure_xeon_secondary_side_bars(ntb); /* Enable Bus Master and Memory Space on the secondary side */ ntb_reg_write(2, ntb->reg_ofs.spci_cmd, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); - + /* Enable link training */ ntb_reg_write(4, ntb->reg_ofs.lnk_cntl, NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP); @@ -773,39 +786,7 @@ ntb_setup_soc(struct ntb_softc *ntb) */ pci_write_config(ntb->device, 0xFC, 0x4, 4); - /* - * Some BIOSes aren't filling out the XLAT offsets. - * Check and correct the issue. - */ - if (ntb->dev_type == NTB_DEV_USD) { - if (ntb_reg_read(8, SOC_PBAR2XLAT_OFFSET) == 0) - ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, - SOC_PBAR2XLAT_USD_ADDR); - - if (ntb_reg_read(8, SOC_PBAR4XLAT_OFFSET) == 0) - ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, - SOC_PBAR4XLAT_USD_ADDR); - - if (ntb_reg_read(8, SOC_MBAR23_OFFSET) == 0xC) - ntb_reg_write(8, SOC_MBAR23_OFFSET, SOC_MBAR23_USD_ADDR); - - if (ntb_reg_read(8, SOC_MBAR45_OFFSET) == 0xC) - ntb_reg_write(8, SOC_MBAR45_OFFSET, SOC_MBAR45_USD_ADDR); - } else { - if (ntb_reg_read(8, SOC_PBAR2XLAT_OFFSET) == 0) - ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, - SOC_PBAR2XLAT_DSD_ADDR); - - if (ntb_reg_read(8, SOC_PBAR4XLAT_OFFSET) == 0) - ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, - SOC_PBAR4XLAT_DSD_ADDR); - - if (ntb_reg_read(8, SOC_MBAR23_OFFSET) == 0xC) - ntb_reg_write(8, SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR); - - if (ntb_reg_read(8, SOC_MBAR45_OFFSET) == 0xC) - ntb_reg_write(8, SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR); - } + configure_soc_secondary_side_bars(ntb); /* Enable Bus Master and Memory Space on the secondary side */ ntb_reg_write(2, ntb->reg_ofs.spci_cmd, @@ -815,6 +796,52 @@ ntb_setup_soc(struct ntb_softc *ntb) return (0); } +static void +configure_soc_secondary_side_bars(struct ntb_softc *ntb) +{ + + if (ntb->dev_type == NTB_DEV_USD) { + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR); + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_USD_ADDR); + ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_USD_ADDR); + ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_USD_ADDR); + } else { + ntb_reg_write(8, SOC_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR); + ntb_reg_write(8, SOC_PBAR4XLAT_OFFSET, PBAR4XLAT_DSD_ADDR); + ntb_reg_write(8, SOC_MBAR23_OFFSET, MBAR23_DSD_ADDR); + ntb_reg_write(8, SOC_MBAR45_OFFSET, MBAR45_DSD_ADDR); + } +} + +static void +configure_xeon_secondary_side_bars(struct ntb_softc *ntb) +{ + + if (ntb->dev_type == NTB_DEV_USD) { + ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_USD_ADDR); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + MBAR01_DSD_ADDR); + else + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + PBAR4XLAT_USD_ADDR); + ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_USD_ADDR); + ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_USD_ADDR); + ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_USD_ADDR); + } else { + ntb_reg_write(8, XEON_PBAR2XLAT_OFFSET, PBAR2XLAT_DSD_ADDR); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + MBAR01_USD_ADDR); + else + ntb_reg_write(8, XEON_PBAR4XLAT_OFFSET, + PBAR4XLAT_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, MBAR01_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR2BASE_OFFSET, MBAR23_DSD_ADDR); + ntb_reg_write(8, XEON_SBAR4BASE_OFFSET, MBAR45_DSD_ADDR); + } +} + /* SOC doesn't have link status interrupt, poll on that platform */ static void ntb_handle_heartbeat(void *arg) @@ -1212,7 +1239,10 @@ ntb_write_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t val) if (idx >= ntb->limits.max_spads) return (EINVAL); - ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_mw_write(4, XEON_SHADOW_SPAD_OFFSET + idx * 4, val); + else + ntb_reg_write(4, ntb->reg_ofs.spad_remote + idx * 4, val); return (0); } @@ -1235,7 +1265,10 @@ ntb_read_remote_spad(struct ntb_softc *ntb, unsigned int idx, uint32_t *val) if (idx >= ntb->limits.max_spads) return (EINVAL); - *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + *val = ntb_mw_read(4, XEON_SHADOW_SPAD_OFFSET + idx * 4); + else + *val = ntb_reg_read(4, ntb->reg_ofs.spad_remote + idx * 4); return (0); } @@ -1333,9 +1366,14 @@ ntb_ring_sdb(struct ntb_softc *ntb, unsigned int db) if (ntb->type == NTB_SOC) ntb_reg_write(8, ntb->reg_ofs.sdb, (uint64_t) 1 << db); else - ntb_reg_write(2, ntb->reg_ofs.sdb, - ((1 << ntb->bits_per_vector) - 1) << - (db * ntb->bits_per_vector)); + if (HAS_FEATURE(NTB_REGS_THRU_MW)) + ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET, + ((1 << ntb->bits_per_vector) - 1) << + (db * ntb->bits_per_vector)); + else + ntb_reg_write(2, ntb->reg_ofs.sdb, + ((1 << ntb->bits_per_vector) - 1) << + (db * ntb->bits_per_vector)); } /** diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h index 8dd2568..bd55a59 100644 --- a/sys/dev/ntb/ntb_hw/ntb_regs.h +++ b/sys/dev/ntb/ntb_hw/ntb_regs.h @@ -136,13 +136,19 @@ #define NTB_DEV_DSD 1 #define NTB_DEV_USD 0 -#define SOC_PBAR2XLAT_USD_ADDR 0x0000004000000000 -#define SOC_PBAR4XLAT_USD_ADDR 0x0000008000000000 -#define SOC_MBAR23_USD_ADDR 0x000000410000000c -#define SOC_MBAR45_USD_ADDR 0x000000810000000c -#define SOC_PBAR2XLAT_DSD_ADDR 0x0000004100000000 -#define SOC_PBAR4XLAT_DSD_ADDR 0x0000008100000000 -#define SOC_MBAR23_DSD_ADDR 0x000000400000000c -#define SOC_MBAR45_DSD_ADDR 0x000000800000000c +#define PBAR2XLAT_USD_ADDR 0x0000004000000000 +#define PBAR4XLAT_USD_ADDR 0x0000008000000000 +#define MBAR01_USD_ADDR 0x000000210000000c +#define MBAR23_USD_ADDR 0x000000410000000c +#define MBAR45_USD_ADDR 0x000000810000000c +#define PBAR2XLAT_DSD_ADDR 0x0000004100000000 +#define PBAR4XLAT_DSD_ADDR 0x0000008100000000 +#define MBAR01_DSD_ADDR 0x000000200000000c +#define MBAR23_DSD_ADDR 0x000000400000000c +#define MBAR45_DSD_ADDR 0x000000800000000c + +/* XEON Shadowed MMIO Space */ +#define XEON_SHADOW_PDOORBELL_OFFSET 0x60 +#define XEON_SHADOW_SPAD_OFFSET 0x80 #endif /* _NTB_REGS_H_ */ -- cgit v1.1 From 679ed329d3d0d827cc6845cf5e1adb03dec09eab Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:12:58 +0000 Subject: Only tear down interface and transport if they've been successfully setup. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/if_ntb/if_ntb.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 510bd75..b74e6c2 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -334,14 +334,19 @@ ntb_setup_interface() static int ntb_teardown_interface() { - struct ifnet *ifp = net_softc.ifp; - ntb_transport_link_down(net_softc.qp); + if (net_softc.qp != NULL) + ntb_transport_link_down(net_softc.qp); - ether_ifdetach(ifp); - if_free(ifp); - ntb_transport_free_queue(net_softc.qp); - ntb_transport_free(&net_softc); + if (net_softc.ifp != NULL) { + ether_ifdetach(net_softc.ifp); + if_free(net_softc.ifp); + } + + if (net_softc.qp != NULL) { + ntb_transport_free_queue(net_softc.qp); + ntb_transport_free(&net_softc); + } return (0); } -- cgit v1.1 From e17bb56f2adb92348c3047dffb7b3aefad021a98 Mon Sep 17 00:00:00 2001 From: carl Date: Thu, 5 Sep 2013 23:14:27 +0000 Subject: Remove contractions. Approved by: jimharris Sponsored by: Intel --- sys/dev/ntb/if_ntb/if_ntb.c | 10 +++++----- sys/dev/ntb/ntb_hw/ntb_hw.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index b74e6c2..e86ed53 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -104,7 +104,7 @@ struct ntb_transport_qp { bool client_ready; bool qp_link; - uint8_t qp_num; /* Only 64 QP's are allowed. 0-63 */ + uint8_t qp_num; /* Only 64 QPs are allowed. 0-63 */ struct ntb_rx_info *rx_info; struct ntb_rx_info *remote_rx_info; @@ -297,7 +297,7 @@ ntb_setup_interface() net_softc.ntb = devclass_get_softc(devclass_find("ntb_hw"), 0); if (net_softc.ntb == NULL) { - printf("ntb: Can't find devclass\n"); + printf("ntb: Cannot find devclass\n"); return (ENXIO); } @@ -410,7 +410,7 @@ ntb_start(struct ifnet *ifp) m_length(m_head, NULL)); if (rc != 0) { CTR1(KTR_NTB, - "TX: couldn't tx mbuf %p. Returning to snd q", + "TX: could not tx mbuf %p. Returning to snd q", m_head); if (rc == EAGAIN) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -505,7 +505,7 @@ ntb_transport_free(void *transport) callout_drain(&nt->link_work); - /* verify that all the qp's are freed */ + /* verify that all the qps are freed */ for (i = 0; i < nt->max_qps; i++) if (!test_bit(i, &nt->qp_bitmap)) ntb_transport_free_queue(&nt->qps[i]); @@ -719,7 +719,7 @@ ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); if (entry == NULL) { - CTR0(KTR_NTB, "TX: couldn't get entry from tx_free_q"); + CTR0(KTR_NTB, "TX: could not get entry from tx_free_q"); return (ENOMEM); } CTR1(KTR_NTB, "TX: got entry %p from tx_free_q", entry); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw.c b/sys/dev/ntb/ntb_hw/ntb_hw.c index c81593c..019f2a7 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw.c @@ -842,7 +842,7 @@ configure_xeon_secondary_side_bars(struct ntb_softc *ntb) } } -/* SOC doesn't have link status interrupt, poll on that platform */ +/* SOC does not have link status interrupt, poll on that platform */ static void ntb_handle_heartbeat(void *arg) { @@ -935,7 +935,7 @@ ntb_handle_link_event(struct ntb_softc *ntb, int link_state) device_printf(ntb->device, "Link Down\n"); ntb->link_status = NTB_LINK_DOWN; event = NTB_EVENT_HW_LINK_DOWN; - /* Don't modify link width/speed, we need it in link recovery */ + /* Do not modify link width/speed, we need it in link recovery */ } /* notify the upper layer if we have an event change */ -- cgit v1.1 From 94d79b37f4502ede6825656f0a6cffb7bea9496d Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Thu, 5 Sep 2013 23:28:50 +0000 Subject: Also align the 32-bit PowerPC stacks. --- sys/powerpc/include/frame.h | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h index 092827d..d2100a1 100644 --- a/sys/powerpc/include/frame.h +++ b/sys/powerpc/include/frame.h @@ -103,6 +103,7 @@ struct callframe { register_t cf_func; register_t cf_arg0; register_t cf_arg1; + register_t _padding; /* Maintain 16-byte alignment */ }; #endif -- cgit v1.1 From 13a117b3c6284b73ccc930ca12683941fda83810 Mon Sep 17 00:00:00 2001 From: rmacklem Date: Fri, 6 Sep 2013 02:34:34 +0000 Subject: It was reported via email that the cu_sent field used by the krpc client side UDP was observed as way out of range and caused the rpc.lockd daemon to hang trying to do an RPC. Inspection of the code found two places where the RPC request is re-queued, but the value of cu_sent was not incremented. Since cu_sent is always decremented when the RPC request is dequeued, I think this could have caused cu_sent to go out of range. This patch adds lines to increment cu_sent for these two cases. Reported by: dwhite@ixsystems.com Discussed with: dwhite@ixsystems.com MFC after: 2 weeks --- sys/rpc/clnt_dg.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index a658de9..4c1fe8c 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -682,6 +682,7 @@ get_reply: next_sendtime += retransmit_time; goto send_again; } + cu->cu_sent += CWNDSCALE; TAILQ_INSERT_TAIL(&cs->cs_pending, cr, cr_link); } @@ -733,6 +734,7 @@ got_reply: */ XDR_DESTROY(&xdrs); mtx_lock(&cs->cs_lock); + cu->cu_sent += CWNDSCALE; TAILQ_INSERT_TAIL(&cs->cs_pending, cr, cr_link); cr->cr_mrep = NULL; -- cgit v1.1 From 37b6e3223fc91b6bf44902ea090b984c9417f3c3 Mon Sep 17 00:00:00 2001 From: grehan Date: Fri, 6 Sep 2013 05:16:10 +0000 Subject: Allow CPUID leaf 0xD to be read as zeroes. Linux reads this even though extended features aren't exposed. Support for 0xD will be expanded once AVX[2] is exposed to the guest in upcoming work. --- sys/amd64/vmm/x86.c | 1 + sys/amd64/vmm/x86.h | 1 + 2 files changed, 2 insertions(+) (limited to 'sys') diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c index 262efbd..4416c53 100644 --- a/sys/amd64/vmm/x86.c +++ b/sys/amd64/vmm/x86.c @@ -200,6 +200,7 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id, case CPUID_0000_0006: case CPUID_0000_0007: case CPUID_0000_000A: + case CPUID_0000_000D: /* * Handle the access, but report 0 for * all options diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h index 368e967..8401c15 100644 --- a/sys/amd64/vmm/x86.h +++ b/sys/amd64/vmm/x86.h @@ -38,6 +38,7 @@ #define CPUID_0000_0007 (0x7) #define CPUID_0000_000A (0xA) #define CPUID_0000_000B (0xB) +#define CPUID_0000_000D (0xD) #define CPUID_8000_0000 (0x80000000) #define CPUID_8000_0001 (0x80000001) #define CPUID_8000_0002 (0x80000002) -- cgit v1.1 From 5110b054b22685516ac8b828fb0e43187ce8a532 Mon Sep 17 00:00:00 2001 From: grehan Date: Fri, 6 Sep 2013 05:20:11 +0000 Subject: Emulate reading of the IA32_MISC_ENABLE MSR, by returning the host MSR and masking off features that aren't supported. Linux reads this MSR to detect if NX has been disabled via BIOS. --- sys/amd64/vmm/vmm_msr.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/amd64/vmm/vmm_msr.c b/sys/amd64/vmm/vmm_msr.c index d97c819..0ccd7af 100644 --- a/sys/amd64/vmm/vmm_msr.c +++ b/sys/amd64/vmm/vmm_msr.c @@ -57,6 +57,7 @@ static struct vmm_msr vmm_msr[] = { { MSR_PAT, VMM_MSR_F_EMULATE | VMM_MSR_F_INVALID }, { MSR_BIOS_SIGN,VMM_MSR_F_EMULATE }, { MSR_MCG_CAP, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, + { MSR_IA32_MISC_ENABLE, VMM_MSR_F_EMULATE | VMM_MSR_F_READONLY }, }; #define vmm_msr_num (sizeof(vmm_msr) / sizeof(vmm_msr[0])) @@ -91,7 +92,7 @@ void guest_msrs_init(struct vm *vm, int cpu) { int i; - uint64_t *guest_msrs; + uint64_t *guest_msrs, misc; guest_msrs = vm_guest_msrs(vm, cpu); @@ -115,6 +116,20 @@ guest_msrs_init(struct vm *vm, int cpu) PAT_VALUE(6, PAT_UNCACHED) | PAT_VALUE(7, PAT_UNCACHEABLE); break; + case MSR_IA32_MISC_ENABLE: + misc = rdmsr(MSR_IA32_MISC_ENABLE); + /* + * Set mandatory bits + * 11: branch trace disabled + * 12: PEBS unavailable + * Clear unsupported features + * 16: SpeedStep enable + * 18: enable MONITOR FSM + */ + misc |= (1 << 12) | (1 << 11); + misc &= ~((1 << 18) | (1 << 16)); + guest_msrs[i] = misc; + break; default: panic("guest_msrs_init: missing initialization for msr " "0x%0x", vmm_msr[i].num); -- cgit v1.1 From 358d3d145a0923158cfe4823195e4c60f4e37249 Mon Sep 17 00:00:00 2001 From: glebius Date: Fri, 6 Sep 2013 05:37:49 +0000 Subject: On those machines, where sf_bufs do not represent any real object, make sf_buf_alloc()/sf_buf_free() inlines, to save two calls to an absolutely empty functions. Reviewed by: alc, kib, scottl Sponsored by: Nginx, Inc. Sponsored by: Netflix --- sys/amd64/amd64/vm_machdep.c | 22 ---------------------- sys/amd64/include/sf_buf.h | 12 ++++++++++++ sys/ia64/ia64/vm_machdep.c | 22 ---------------------- sys/ia64/include/sf_buf.h | 12 ++++++++++++ sys/mips/include/sf_buf.h | 12 ++++++++++++ sys/mips/mips/vm_machdep.c | 10 +++------- 6 files changed, 39 insertions(+), 51 deletions(-) (limited to 'sys') diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 3e961e9..7253fe2 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -695,27 +694,6 @@ cpu_reset_real() } /* - * Allocate an sf_buf for the given vm_page. On this machine, however, there - * is no sf_buf object. Instead, an opaque pointer to the given vm_page is - * returned. - */ -struct sf_buf * -sf_buf_alloc(struct vm_page *m, int pri) -{ - - return ((struct sf_buf *)m); -} - -/* - * Free the sf_buf. In fact, do nothing because there are no resources - * associated with the sf_buf. - */ -void -sf_buf_free(struct sf_buf *sf) -{ -} - -/* * Software interrupt handler for queued VM system processing. */ void diff --git a/sys/amd64/include/sf_buf.h b/sys/amd64/include/sf_buf.h index b5245e6..729e8e5 100644 --- a/sys/amd64/include/sf_buf.h +++ b/sys/amd64/include/sf_buf.h @@ -41,6 +41,18 @@ */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 09987fd..186897b 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include @@ -353,27 +352,6 @@ cpu_exit(struct thread *td) } /* - * Allocate an sf_buf for the given vm_page. On this machine, however, there - * is no sf_buf object. Instead, an opaque pointer to the given vm_page is - * returned. - */ -struct sf_buf * -sf_buf_alloc(struct vm_page *m, int pri) -{ - - return ((struct sf_buf *)m); -} - -/* - * Free the sf_buf. In fact, do nothing because there are no resources - * associated with the sf_buf. - */ -void -sf_buf_free(struct sf_buf *sf) -{ -} - -/* * Software interrupt handler for queued VM system processing. */ void diff --git a/sys/ia64/include/sf_buf.h b/sys/ia64/include/sf_buf.h index 75bcdfa..44d0109 100644 --- a/sys/ia64/include/sf_buf.h +++ b/sys/ia64/include/sf_buf.h @@ -41,6 +41,18 @@ */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_page_t sf_buf_page(struct sf_buf *sf) { diff --git a/sys/mips/include/sf_buf.h b/sys/mips/include/sf_buf.h index b9efaf0..00502a0 100644 --- a/sys/mips/include/sf_buf.h +++ b/sys/mips/include/sf_buf.h @@ -41,6 +41,18 @@ /* In 64 bit the whole memory is directly mapped */ struct sf_buf; +static inline struct sf_buf * +sf_buf_alloc(struct vm_page *m, int pri) +{ + + return ((struct sf_buf *)m); +} + +static inline void +sf_buf_free(struct sf_buf *sf) +{ +} + static __inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 86dfde9..c42f640 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -76,7 +76,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef __mips_n64 #include +#endif #ifndef NSFBUFS #define NSFBUFS (512 + maxusers * 16) @@ -523,7 +525,6 @@ sf_buf_init(void *arg) } sf_buf_alloc_want = 0; } -#endif /* * Get an sf_buf from the freelist. Will block if none are available. @@ -531,7 +532,6 @@ sf_buf_init(void *arg) struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags) { -#ifndef __mips_n64 struct sf_buf *sf; int error; @@ -560,9 +560,6 @@ sf_buf_alloc(struct vm_page *m, int flags) } mtx_unlock(&sf_freelist.sf_lock); return (sf); -#else - return ((struct sf_buf *)m); -#endif } /* @@ -571,7 +568,6 @@ sf_buf_alloc(struct vm_page *m, int flags) void sf_buf_free(struct sf_buf *sf) { -#ifndef __mips_n64 pmap_qremove(sf->kva, 1); mtx_lock(&sf_freelist.sf_lock); SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list); @@ -579,8 +575,8 @@ sf_buf_free(struct sf_buf *sf) if (sf_buf_alloc_want > 0) wakeup(&sf_freelist); mtx_unlock(&sf_freelist.sf_lock); -#endif } +#endif /* !__mips_n64 */ /* * Software interrupt handler for queued VM system processing. -- cgit v1.1 From 1d24f8b2c76c5013cd5b2e661fb0f035fba19a5c Mon Sep 17 00:00:00 2001 From: glebius Date: Fri, 6 Sep 2013 05:38:20 +0000 Subject: Fix build. --- sys/conf/files.mips | 1 + 1 file changed, 1 insertion(+) (limited to 'sys') diff --git a/sys/conf/files.mips b/sys/conf/files.mips index ca8dee2..7f54f08 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -56,6 +56,7 @@ libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/memmove.c standard +libkern/cmpdi2.c optional mips | mipsel libkern/ucmpdi2.c optional mips | mipsel # cfe support -- cgit v1.1 From 3263427a2eb3c2dcf28cdcc849a9b31fa8db4895 Mon Sep 17 00:00:00 2001 From: loos Date: Fri, 6 Sep 2013 12:47:14 +0000 Subject: Fix the leakage of dma tags on if_arge. The leak occur when arge_start() add some packet(s) to tx ring and arge_stop() is called before receive the sent packet interrupt from hardware. Fix arge_stop() to unload the in use dma tags and free the associated mbuf. PR: 178319, 163670 Approved by: adrian (mentor) --- sys/mips/atheros/if_arge.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'sys') diff --git a/sys/mips/atheros/if_arge.c b/sys/mips/atheros/if_arge.c index 21b945f..aabab52 100644 --- a/sys/mips/atheros/if_arge.c +++ b/sys/mips/atheros/if_arge.c @@ -142,6 +142,7 @@ static int arge_resume(device_t); static int arge_rx_ring_init(struct arge_softc *); static void arge_rx_ring_free(struct arge_softc *sc); static int arge_tx_ring_init(struct arge_softc *); +static void arge_tx_ring_free(struct arge_softc *); #ifdef DEVICE_POLLING static int arge_poll(struct ifnet *, enum poll_cmd, int); #endif @@ -1278,6 +1279,7 @@ arge_stop(struct arge_softc *sc) /* Flush FIFO and free any existing mbufs */ arge_flush_ddr(sc); arge_rx_ring_free(sc); + arge_tx_ring_free(sc); } @@ -1708,6 +1710,30 @@ arge_tx_ring_init(struct arge_softc *sc) } /* + * Free the Tx ring, unload any pending dma transaction and free the mbuf. + */ +static void +arge_tx_ring_free(struct arge_softc *sc) +{ + struct arge_txdesc *txd; + int i; + + /* Free the Tx buffers. */ + for (i = 0; i < ARGE_TX_RING_COUNT; i++) { + txd = &sc->arge_cdata.arge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_sync(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->arge_cdata.arge_tx_tag, + txd->tx_dmamap); + } + if (txd->tx_m) + m_freem(txd->tx_m); + txd->tx_m = NULL; + } +} + +/* * Initialize the RX descriptors and allocate mbufs for them. Note that * we arrange the descriptors in a closed ring, so that the last descriptor * points back to the first. -- cgit v1.1 From 9ec6975e732d64de2954810fdc69671b8cf277d8 Mon Sep 17 00:00:00 2001 From: mav Date: Fri, 6 Sep 2013 14:31:52 +0000 Subject: Fix kernel panic if cache->nelms is zero. MFC after: 2 weeks --- sys/cam/scsi/scsi_enc_ses.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c index 2e51030..213fad9 100644 --- a/sys/cam/scsi/scsi_enc_ses.c +++ b/sys/cam/scsi/scsi_enc_ses.c @@ -567,8 +567,8 @@ ses_cache_free_elm_addlstatus(enc_softc_t *enc, enc_cache_t *cache) return; for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ses_element_t *elmpriv; elmpriv = cur_elm->elm_private; @@ -598,8 +598,8 @@ ses_cache_free_elm_descs(enc_softc_t *enc, enc_cache_t *cache) return; for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ses_element_t *elmpriv; elmpriv = cur_elm->elm_private; @@ -644,8 +644,8 @@ ses_cache_free_elm_map(enc_softc_t *enc, enc_cache_t *cache) ses_cache_free_elm_descs(enc, cache); ses_cache_free_elm_addlstatus(enc, cache); for (cur_elm = cache->elm_map, - last_elm = &cache->elm_map[cache->nelms - 1]; - cur_elm <= last_elm; cur_elm++) { + last_elm = &cache->elm_map[cache->nelms]; + cur_elm != last_elm; cur_elm++) { ENC_FREE_AND_NULL(cur_elm->elm_private); } @@ -717,8 +717,8 @@ ses_cache_clone(enc_softc_t *enc, enc_cache_t *src, enc_cache_t *dst) dst->elm_map = ENC_MALLOCZ(dst->nelms * sizeof(enc_element_t)); memcpy(dst->elm_map, src->elm_map, dst->nelms * sizeof(enc_element_t)); for (dst_elm = dst->elm_map, src_elm = src->elm_map, - last_elm = &src->elm_map[src->nelms - 1]; - src_elm <= last_elm; src_elm++, dst_elm++) { + last_elm = &src->elm_map[src->nelms]; + src_elm != last_elm; src_elm++, dst_elm++) { dst_elm->elm_private = ENC_MALLOCZ(sizeof(ses_element_t)); memcpy(dst_elm->elm_private, src_elm->elm_private, -- cgit v1.1 From 5aae754060b8e919a3f95d29a0ee8bf7b21abc19 Mon Sep 17 00:00:00 2001 From: pjd Date: Fri, 6 Sep 2013 14:34:20 +0000 Subject: Bump __FreeBSD_version to 1000053 after cap_rights_t change. Suggested by: danfe --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/sys/param.h b/sys/sys/param.h index 88c8d37..fa3e2eb 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1000052 /* Master, propagated to newvers */ +#define __FreeBSD_version 1000053 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, -- cgit v1.1 From 4dc4ea3c0de319d5731d022a107eb6e8648ef4f4 Mon Sep 17 00:00:00 2001 From: bryanv Date: Fri, 6 Sep 2013 15:19:57 +0000 Subject: Add camcontrol support for the SCSI sanitize command Reviewed by: ken, mjacob (eariler version) Sponsored by: Netapp --- sys/cam/scsi/scsi_da.c | 27 +++++++++++++++++++++++++++ sys/cam/scsi/scsi_da.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'sys') diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 8ee47f9..913951e 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -3851,4 +3851,31 @@ scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, timeout); } +void +scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, u_int8_t byte2, u_int16_t control, + u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, + u_int32_t timeout) +{ + struct scsi_sanitize *scsi_cmd; + + scsi_cmd = (struct scsi_sanitize *)&csio->cdb_io.cdb_bytes; + scsi_cmd->opcode = SANITIZE; + scsi_cmd->byte2 = byte2; + scsi_cmd->control = control; + scsi_ulto2b(dxfer_len, scsi_cmd->length); + + cam_fill_csio(csio, + retries, + cbfcnp, + /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, + tag_action, + data_ptr, + dxfer_len, + sense_len, + sizeof(*scsi_cmd), + timeout); +} + #endif /* _KERNEL */ diff --git a/sys/cam/scsi/scsi_da.h b/sys/cam/scsi/scsi_da.h index 5799238..4fbd725 100644 --- a/sys/cam/scsi/scsi_da.h +++ b/sys/cam/scsi/scsi_da.h @@ -116,6 +116,31 @@ struct scsi_read_defect_data_10 u_int8_t control; }; +struct scsi_sanitize +{ + u_int8_t opcode; + u_int8_t byte2; +#define SSZ_SERVICE_ACTION_OVERWRITE 0x01 +#define SSZ_SERVICE_ACTION_BLOCK_ERASE 0x02 +#define SSZ_SERVICE_ACTION_CRYPTO_ERASE 0x03 +#define SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE 0x1F +#define SSZ_UNRESTRICTED_EXIT 0x20 +#define SSZ_IMMED 0x80 + u_int8_t reserved[5]; + u_int8_t length[2]; + u_int8_t control; +}; + +struct scsi_sanitize_parameter_list +{ + u_int8_t byte1; +#define SSZPL_INVERT 0x80 + u_int8_t reserved; + u_int8_t length[2]; + /* Variable length initialization pattern. */ +#define SSZPL_MAX_PATTERN_LENGTH 65535 +}; + struct scsi_read_defect_data_12 { u_int8_t opcode; @@ -156,6 +181,7 @@ struct scsi_read_defect_data_12 #define WRITE_AND_VERIFY 0x2e #define VERIFY 0x2f #define READ_DEFECT_DATA_10 0x37 +#define SANITIZE 0x48 #define READ_DEFECT_DATA_12 0xb7 struct format_defect_list_header @@ -508,6 +534,12 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout); +void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int8_t tag_action, u_int8_t byte2, u_int16_t control, + u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, + u_int32_t timeout); + #endif /* !_KERNEL */ __END_DECLS -- cgit v1.1 From a368e04207b7ebda519d8731e0b16eac4e9c6bb8 Mon Sep 17 00:00:00 2001 From: mav Date: Fri, 6 Sep 2013 15:41:37 +0000 Subject: Make SES driver adequately react on simple enclosure devices -- read Short Enclosure status to enclosure status field, clear previous state and exit. --- sys/cam/scsi/scsi_enc_ses.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sys') diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c index 213fad9..6917fff 100644 --- a/sys/cam/scsi/scsi_enc_ses.c +++ b/sys/cam/scsi/scsi_enc_ses.c @@ -1555,6 +1555,18 @@ ses_process_status(enc_softc_t *enc, struct enc_fsm_state *state, ENC_VLOG(enc, "Enclosure Status Page Too Long\n"); goto out; } + + /* Check for simple enclosure reporting short enclosure status. */ + if (length >= 4 && page->hdr.page_code == SesShortStatus) { + ENC_DLOG(enc, "Got Short Enclosure Status page\n"); + ses->ses_flags &= ~(SES_FLAG_ADDLSTATUS | SES_FLAG_DESC); + ses_cache_free(enc, enc_cache); + enc_cache->enc_status = page->hdr.page_specific_flags; + enc_update_request(enc, SES_PUBLISH_CACHE); + err = 0; + goto out; + } + /* Make sure the length contains at least one header and status */ if (length < (sizeof(*page) + sizeof(*page->elements))) { ENC_VLOG(enc, "Enclosure Status Page Too Short\n"); -- cgit v1.1 From b10a9f2e78cd159562e826b3206200beaf4a5d5e Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 6 Sep 2013 16:48:34 +0000 Subject: In pmap_ts_referenced(), when restarting the loop due to pv list generation changed, do not drop and immediately relock the pv list. Suggested and reviewed by: alc Sponsored by: The FreeBSD Foundation --- sys/amd64/amd64/pmap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sys') diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index cecd92d..4c6e9e6 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -5086,8 +5086,8 @@ pmap_ts_referenced(vm_page_t m) lock = VM_PAGE_TO_PV_LIST_LOCK(m); pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); rtval = 0; -retry: rw_wlock(lock); +retry: if ((m->flags & PG_FICTITIOUS) != 0) goto small_mappings; TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, pvn) { @@ -5099,7 +5099,6 @@ retry: rw_wlock(lock); if (pvh_gen != pvh->pv_gen) { PMAP_UNLOCK(pmap); - rw_wunlock(lock); goto retry; } } @@ -5154,7 +5153,6 @@ small_mappings: if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { PMAP_UNLOCK(pmap); - rw_wunlock(lock); goto retry; } } -- cgit v1.1 From 8439d9918f1413406e07465a2729a2ce07ee4fdd Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 6 Sep 2013 16:53:48 +0000 Subject: Only lock pvh_global_lock read-only for pmap_page_wired_mappings(), pmap_is_modified() and pmap_is_referenced(), same as it was done for pmap_ts_referenced(). Consolidate identical code for pmap_is_modified() and pmap_is_referenced() into helper pmap_page_test_mappings(). Reviewed by: alc Tested by: pho (previous version) Sponsored by: The FreeBSD Foundation --- sys/amd64/amd64/pmap.c | 206 ++++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 96 deletions(-) (limited to 'sys') diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 4c6e9e6..8940d4a 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -315,7 +315,6 @@ static void pmap_pv_promote_pde(pmap_t pmap, vm_offset_t va, vm_paddr_t pa, static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va); static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va); -static int pmap_pvh_wired_mappings(struct md_page *pvh, int count); static int pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode); static boolean_t pmap_demote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va); @@ -329,8 +328,6 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); -static boolean_t pmap_is_modified_pvh(struct md_page *pvh); -static boolean_t pmap_is_referenced_pvh(struct md_page *pvh); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); static vm_page_t pmap_lookup_pt_page(pmap_t pmap, vm_offset_t va); static void pmap_pde_attr(pd_entry_t *pde, int cache_bits); @@ -4604,42 +4601,61 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m) int pmap_page_wired_mappings(vm_page_t m) { - int count; - - count = 0; - if ((m->oflags & VPO_UNMANAGED) != 0) - return (count); - rw_wlock(&pvh_global_lock); - count = pmap_pvh_wired_mappings(&m->md, count); - if ((m->flags & PG_FICTITIOUS) == 0) { - count = pmap_pvh_wired_mappings(pa_to_pvh(VM_PAGE_TO_PHYS(m)), - count); - } - rw_wunlock(&pvh_global_lock); - return (count); -} - -/* - * pmap_pvh_wired_mappings: - * - * Return the updated number "count" of managed mappings that are wired. - */ -static int -pmap_pvh_wired_mappings(struct md_page *pvh, int count) -{ + struct rwlock *lock; + struct md_page *pvh; pmap_t pmap; pt_entry_t *pte; pv_entry_t pv; + int count, md_gen, pvh_gen; - rw_assert(&pvh_global_lock, RA_WLOCKED); - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + if ((m->oflags & VPO_UNMANAGED) != 0) + return (0); + rw_rlock(&pvh_global_lock); + lock = VM_PAGE_TO_PV_LIST_LOCK(m); + rw_rlock(lock); +restart: + count = 0; + TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } pte = pmap_pte(pmap, pv->pv_va); if ((*pte & PG_W) != 0) count++; PMAP_UNLOCK(pmap); } + if ((m->flags & PG_FICTITIOUS) == 0) { + pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); + TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + pvh_gen = pvh->pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen || + pvh_gen != pvh->pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pde(pmap, pv->pv_va); + if ((*pte & PG_W) != 0) + count++; + PMAP_UNLOCK(pmap); + } + } + rw_runlock(lock); + rw_runlock(&pvh_global_lock); return (count); } @@ -4835,6 +4851,69 @@ pmap_remove_pages(pmap_t pmap) pmap_free_zero_pages(&free); } +static boolean_t +pmap_page_test_mappings(vm_page_t m, pt_entry_t mask) +{ + struct rwlock *lock; + pv_entry_t pv; + struct md_page *pvh; + pt_entry_t *pte; + pmap_t pmap; + int md_gen, pvh_gen; + boolean_t rv; + + rv = FALSE; + rw_rlock(&pvh_global_lock); + lock = VM_PAGE_TO_PV_LIST_LOCK(m); + rw_rlock(lock); +restart: + TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pte(pmap, pv->pv_va); + rv = (*pte & mask) == mask; + PMAP_UNLOCK(pmap); + if (rv) + goto out; + } + if ((m->flags & PG_FICTITIOUS) == 0) { + pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); + TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { + pmap = PV_PMAP(pv); + if (!PMAP_TRYLOCK(pmap)) { + md_gen = m->md.pv_gen; + pvh_gen = pvh->pv_gen; + rw_runlock(lock); + PMAP_LOCK(pmap); + rw_rlock(lock); + if (md_gen != m->md.pv_gen || + pvh_gen != pvh->pv_gen) { + PMAP_UNLOCK(pmap); + goto restart; + } + } + pte = pmap_pde(pmap, pv->pv_va); + rv = (*pte & mask) == mask; + PMAP_UNLOCK(pmap); + if (rv) + goto out; + } + } +out: + rw_runlock(lock); + rw_runlock(&pvh_global_lock); + return (rv); +} + /* * pmap_is_modified: * @@ -4844,7 +4923,6 @@ pmap_remove_pages(pmap_t pmap) boolean_t pmap_is_modified(vm_page_t m) { - boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_is_modified: page %p is not managed", m)); @@ -4857,39 +4935,7 @@ pmap_is_modified(vm_page_t m) VM_OBJECT_ASSERT_WLOCKED(m->object); if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); - rw_wlock(&pvh_global_lock); - rv = pmap_is_modified_pvh(&m->md) || - ((m->flags & PG_FICTITIOUS) == 0 && - pmap_is_modified_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)))); - rw_wunlock(&pvh_global_lock); - return (rv); -} - -/* - * Returns TRUE if any of the given mappings were used to modify - * physical memory. Otherwise, returns FALSE. Both page and 2mpage - * mappings are supported. - */ -static boolean_t -pmap_is_modified_pvh(struct md_page *pvh) -{ - pv_entry_t pv; - pt_entry_t *pte; - pmap_t pmap; - boolean_t rv; - - rw_assert(&pvh_global_lock, RA_WLOCKED); - rv = FALSE; - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { - pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); - pte = pmap_pte(pmap, pv->pv_va); - rv = (*pte & (PG_M | PG_RW)) == (PG_M | PG_RW); - PMAP_UNLOCK(pmap); - if (rv) - break; - } - return (rv); + return (pmap_page_test_mappings(m, PG_M | PG_RW)); } /* @@ -4925,42 +4971,10 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr) boolean_t pmap_is_referenced(vm_page_t m) { - boolean_t rv; KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_is_referenced: page %p is not managed", m)); - rw_wlock(&pvh_global_lock); - rv = pmap_is_referenced_pvh(&m->md) || - ((m->flags & PG_FICTITIOUS) == 0 && - pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m)))); - rw_wunlock(&pvh_global_lock); - return (rv); -} - -/* - * Returns TRUE if any of the given mappings were referenced and FALSE - * otherwise. Both page and 2mpage mappings are supported. - */ -static boolean_t -pmap_is_referenced_pvh(struct md_page *pvh) -{ - pv_entry_t pv; - pt_entry_t *pte; - pmap_t pmap; - boolean_t rv; - - rw_assert(&pvh_global_lock, RA_WLOCKED); - rv = FALSE; - TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) { - pmap = PV_PMAP(pv); - PMAP_LOCK(pmap); - pte = pmap_pte(pmap, pv->pv_va); - rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V); - PMAP_UNLOCK(pmap); - if (rv) - break; - } - return (rv); + return (pmap_page_test_mappings(m, PG_A | PG_V)); } /* -- cgit v1.1 From d13d69ef17e933f4e8a1be14f0558e25dad171c7 Mon Sep 17 00:00:00 2001 From: jamie Date: Fri, 6 Sep 2013 17:32:29 +0000 Subject: Keep PRIV_KMEM_READ permitted inside jails as it is on the outside. --- sys/kern/kern_jail.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sys') diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 6451825..331b0e1 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3885,6 +3885,13 @@ prison_priv_check(struct ucred *cred, int priv) case PRIV_VFS_SETGID: case PRIV_VFS_STAT: case PRIV_VFS_STICKYFILE: + + /* + * As in the non-jail case, non-root users are expected to be + * able to read kernel/phyiscal memory (provided /dev/[k]mem + * exists in the jail and they have permission to access it). + */ + case PRIV_KMEM_READ: return (0); /* -- cgit v1.1