summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--ObsoleteFiles.inc3
-rw-r--r--UPDATING14
-rw-r--r--bin/sh/eval.c14
-rw-r--r--bin/sh/eval.h3
-rw-r--r--bin/sh/jobs.c32
-rw-r--r--bin/sh/jobs.h2
-rw-r--r--bin/sh/main.c2
-rw-r--r--bin/sh/sh.16
-rw-r--r--bin/sh/trap.c16
-rw-r--r--bin/sh/trap.h1
-rw-r--r--contrib/binutils/gas/config/tc-i386.c6
-rw-r--r--contrib/binutils/opcodes/i386-dis.c11
-rw-r--r--contrib/binutils/opcodes/i386-opc.tbl4
-rw-r--r--contrib/binutils/opcodes/i386-tbl.h8
-rw-r--r--contrib/bmake/ChangeLog21
-rw-r--r--contrib/bmake/FILES1
-rw-r--r--contrib/bmake/Makefile4
-rw-r--r--contrib/bmake/bmake.110
-rw-r--r--contrib/bmake/bmake.cat16
-rw-r--r--contrib/bmake/compat.c8
-rw-r--r--contrib/bmake/job.c25
-rw-r--r--contrib/bmake/main.c10
-rw-r--r--contrib/bmake/make.110
-rw-r--r--contrib/bmake/make.h6
-rw-r--r--contrib/bmake/mk/ChangeLog11
-rw-r--r--contrib/bmake/mk/gendirdeps.mk15
-rw-r--r--contrib/bmake/mk/install-mk4
-rw-r--r--contrib/bmake/mk/libs.mk57
-rw-r--r--contrib/bmake/mk/progs.mk18
-rw-r--r--contrib/bmake/parse.c12
-rw-r--r--contrib/bmake/unit-tests/Makefile.in5
-rw-r--r--contrib/bmake/unit-tests/sunshcmd10
-rw-r--r--contrib/bmake/unit-tests/test.exp3
-rw-r--r--contrib/bmake/var.c15
-rw-r--r--contrib/gcc/config/i386/i386.c12
-rw-r--r--contrib/gcc/config/i386/i386.h2
-rw-r--r--contrib/gcc/config/i386/i386.opt4
-rw-r--r--contrib/gcc/doc/invoke.texi12
-rw-r--r--contrib/gcc/opth-gen.awk2
-rw-r--r--contrib/libexecinfo/execinfo.h1
-rw-r--r--contrib/tcpdump/tcpdump.c37
-rw-r--r--etc/defaults/periodic.conf136
-rw-r--r--etc/devd/usb.conf100
-rw-r--r--etc/mtree/BSD.include.dist2
-rw-r--r--etc/mtree/BSD.var.dist2
-rwxr-xr-xetc/rc.d/routing4
-rw-r--r--gnu/usr.bin/Makefile1
-rw-r--r--gnu/usr.bin/cc/include/Makefile3
-rw-r--r--gnu/usr.bin/cc/include/__wmmintrin_aes.h54
-rw-r--r--gnu/usr.bin/cc/include/__wmmintrin_pclmul.h53
-rw-r--r--gnu/usr.bin/patch/EXTERN.h21
-rw-r--r--gnu/usr.bin/patch/INTERN.h19
-rw-r--r--gnu/usr.bin/patch/Makefile12
-rw-r--r--gnu/usr.bin/patch/backupfile.c390
-rw-r--r--gnu/usr.bin/patch/backupfile.h44
-rw-r--r--gnu/usr.bin/patch/common.h195
-rw-r--r--gnu/usr.bin/patch/config.h81
-rw-r--r--gnu/usr.bin/patch/inp.c397
-rw-r--r--gnu/usr.bin/patch/inp.h18
-rw-r--r--gnu/usr.bin/patch/patch.1594
-rw-r--r--gnu/usr.bin/patch/patch.c971
-rw-r--r--gnu/usr.bin/patch/patchlevel.h1
-rw-r--r--gnu/usr.bin/patch/pch.c1449
-rw-r--r--gnu/usr.bin/patch/pch.h36
-rw-r--r--gnu/usr.bin/patch/util.c458
-rw-r--r--gnu/usr.bin/patch/util.h88
-rw-r--r--gnu/usr.bin/patch/version.c25
-rw-r--r--gnu/usr.bin/patch/version.h9
-rw-r--r--include/iconv.h10
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libc++/Makefile1
-rw-r--r--lib/libc/Makefile1
-rw-r--r--lib/libc/capability/Makefile.inc19
-rw-r--r--lib/libc/capability/Symbol.map14
-rw-r--r--lib/libc/gen/signal.31
-rw-r--r--lib/libc/iconv/citrus_iconv_local.h1
-rw-r--r--lib/libc/include/compat.h2
-rw-r--r--lib/libc/stdio/flags.c55
-rw-r--r--lib/libc/stdlib/system.c2
-rw-r--r--lib/libc/sys/Symbol.map3
-rw-r--r--lib/libc/sys/sigaction.252
-rw-r--r--lib/libc/sys/sigpending.24
-rw-r--r--lib/libc/sys/sigreturn.26
-rw-r--r--lib/libc/sys/sigwait.24
-rw-r--r--lib/libexecinfo/Makefile6
-rw-r--r--lib/libiconv_modules/Makefile.inc3
-rw-r--r--lib/libprocstat/libprocstat.c6
-rw-r--r--lib/libprocstat/libprocstat.h1
-rw-r--r--lib/libusb/libusb20_ugen20.c4
-rw-r--r--lib/msun/Makefile1
-rw-r--r--lib/msun/Symbol.map9
-rw-r--r--lib/msun/src/imprecise.c69
-rwxr-xr-xrelease/picobsd/build/picobsd33
-rw-r--r--sbin/camcontrol/camcontrol.8125
-rw-r--r--sbin/camcontrol/camcontrol.c422
-rw-r--r--sbin/camcontrol/fwdownload.c2
-rw-r--r--sbin/dhclient/bpf.c12
-rw-r--r--sbin/dhclient/dhclient.c31
-rw-r--r--sbin/hastd/subr.c9
-rw-r--r--sbin/swapon/swapon.c117
-rw-r--r--share/man/man4/capsicum.42
-rw-r--r--share/man/man4/netgraph.46
-rw-r--r--share/man/man4/ntb.42
-rw-r--r--share/man/man4/procdesc.42
-rw-r--r--share/man/man5/periodic.conf.5444
-rw-r--r--share/man/man9/Makefile7
-rw-r--r--share/misc/committers-ports.dot3
-rw-r--r--share/misc/committers-src.dot4
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--sys/amd64/amd64/apic_vector.S110
-rw-r--r--sys/amd64/amd64/db_disasm.c2
-rw-r--r--sys/amd64/amd64/genassym.c1
-rw-r--r--sys/amd64/amd64/mp_machdep.c21
-rw-r--r--sys/amd64/amd64/pmap.c241
-rw-r--r--sys/amd64/amd64/vm_machdep.c26
-rw-r--r--sys/amd64/include/pcpu.h1
-rw-r--r--sys/amd64/include/pmap.h1
-rw-r--r--sys/amd64/include/sf_buf.h12
-rw-r--r--sys/amd64/include/smp.h2
-rw-r--r--sys/amd64/linux32/linux32_machdep.c5
-rw-r--r--sys/amd64/vmm/vmm_msr.c17
-rw-r--r--sys/amd64/vmm/x86.c1
-rw-r--r--sys/amd64/vmm/x86.h1
-rw-r--r--sys/arm/conf/DIGI-CCWMX53175
-rw-r--r--sys/arm/freescale/imx/files.imx5351
-rw-r--r--sys/arm/freescale/imx/imx51_ccm.c3
-rw-r--r--sys/arm/freescale/imx/imx51_gpio.c3
-rw-r--r--sys/arm/freescale/imx/imx51_iomux.c3
-rw-r--r--sys/arm/freescale/imx/imx53_machdep.c141
-rw-r--r--sys/arm/freescale/imx/imx_gpt.c3
-rw-r--r--sys/arm/freescale/imx/imx_wdog.c3
-rw-r--r--sys/arm/freescale/imx/std.imx5315
-rw-r--r--sys/boot/fdt/dts/digi-ccwmx53.dts123
-rw-r--r--sys/boot/fdt/dts/imx53x.dtsi680
-rw-r--r--sys/bsm/audit_kevents.h1
-rw-r--r--sys/bsm/audit_record.h4
-rw-r--r--sys/cam/cam_debug.h11
-rw-r--r--sys/cam/cam_periph.c3
-rw-r--r--sys/cam/cam_xpt.c57
-rw-r--r--sys/cam/cam_xpt.h4
-rw-r--r--sys/cam/scsi/scsi_da.c27
-rw-r--r--sys/cam/scsi/scsi_da.h32
-rw-r--r--sys/cam/scsi/scsi_enc_ses.c28
-rw-r--r--sys/cddl/compat/opensolaris/sys/file.h6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c37
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c15
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c3
-rw-r--r--sys/cddl/dev/dtrace/powerpc/dtrace_subr.c96
-rw-r--r--sys/compat/freebsd32/freebsd32_capability.c20
-rw-r--r--sys/compat/freebsd32/freebsd32_ioctl.c4
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c5
-rw-r--r--sys/compat/freebsd32/freebsd32_proto.h17
-rw-r--r--sys/compat/freebsd32/freebsd32_syscall.h9
-rw-r--r--sys/compat/freebsd32/freebsd32_syscalls.c9
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c9
-rw-r--r--sys/compat/freebsd32/freebsd32_systrace_args.c102
-rw-r--r--sys/compat/freebsd32/syscalls.master16
-rw-r--r--sys/compat/linux/linux_file.c17
-rw-r--r--sys/compat/linux/linux_ioctl.c82
-rw-r--r--sys/compat/linux/linux_socket.c4
-rw-r--r--sys/compat/svr4/svr4_fcntl.c16
-rw-r--r--sys/compat/svr4/svr4_filio.c3
-rw-r--r--sys/compat/svr4/svr4_ioctl.c4
-rw-r--r--sys/compat/svr4/svr4_misc.c10
-rw-r--r--sys/compat/svr4/svr4_stream.c12
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/files.amd647
-rw-r--r--sys/conf/files.i3867
-rw-r--r--sys/conf/files.mips1
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/crypto/aesni/aesencdec.h136
-rw-r--r--sys/crypto/aesni/aesencdec_amd64.S135
-rw-r--r--sys/crypto/aesni/aesencdec_i386.S166
-rw-r--r--sys/crypto/aesni/aeskeys_amd64.S96
-rw-r--r--sys/crypto/aesni/aesni.c8
-rw-r--r--sys/crypto/aesni/aesni.h15
-rw-r--r--sys/crypto/aesni/aesni_wrap.c225
-rw-r--r--sys/dev/aac/aac_linux.c4
-rw-r--r--sys/dev/aacraid/aacraid_linux.c13
-rw-r--r--sys/dev/amr/amr_linux.c4
-rw-r--r--sys/dev/atkbdc/psm.c131
-rw-r--r--sys/dev/cfi/cfi_bus_nexus.c5
-rw-r--r--sys/dev/cfi/cfi_core.c329
-rw-r--r--sys/dev/cfi/cfi_dev.c12
-rw-r--r--sys/dev/cfi/cfi_disk.c6
-rw-r--r--sys/dev/cfi/cfi_reg.h14
-rw-r--r--sys/dev/cfi/cfi_var.h21
-rw-r--r--sys/dev/cxgbe/tom/t4_listen.c2
-rw-r--r--sys/dev/filemon/filemon.c16
-rw-r--r--sys/dev/gpio/gpiobus.c2
-rw-r--r--sys/dev/gxemul/cons/gxemul_cons.c10
-rw-r--r--sys/dev/gxemul/disk/gxemul_disk.c15
-rw-r--r--sys/dev/gxemul/disk/gxemul_diskreg.h14
-rw-r--r--sys/dev/gxemul/ether/gxreg.h7
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c4
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c6
-rw-r--r--sys/dev/hwpmc/hwpmc_mpc7xxx.c748
-rw-r--r--sys/dev/hwpmc/hwpmc_powerpc.c763
-rw-r--r--sys/dev/hwpmc/hwpmc_powerpc.h59
-rw-r--r--sys/dev/ipmi/ipmi_linux.c4
-rw-r--r--sys/dev/iscsi_initiator/iscsi.c7
-rw-r--r--sys/dev/mfi/mfi_linux.c4
-rw-r--r--sys/dev/ntb/if_ntb/if_ntb.c50
-rw-r--r--sys/dev/ntb/ntb_hw/ntb_hw.c432
-rw-r--r--sys/dev/ntb/ntb_hw/ntb_hw.h1
-rw-r--r--sys/dev/ntb/ntb_hw/ntb_regs.h38
-rw-r--r--sys/dev/tdfx/tdfx_linux.c4
-rw-r--r--sys/dev/usb/serial/uftdi.c1
-rw-r--r--sys/dev/usb/usbdevs2
-rw-r--r--sys/dev/usb/wlan/if_run.c1
-rw-r--r--sys/dev/virtio/network/if_vtnet.c11
-rw-r--r--sys/dev/virtio/network/if_vtnetvar.h1
-rw-r--r--sys/dev/virtio/virtqueue.c4
-rw-r--r--sys/dev/xen/blkback/blkback.c18
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c6
-rw-r--r--sys/fs/fuse/fuse_vfsops.c3
-rw-r--r--sys/fs/nfsclient/nfs_clkrpc.c20
-rw-r--r--sys/fs/nfsclient/nfs_clport.c9
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c15
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c5
-rw-r--r--sys/geom/eli/g_eli.c22
-rw-r--r--sys/geom/part/g_part_ldm.c11
-rw-r--r--sys/i386/ibcs2/ibcs2_fcntl.c4
-rw-r--r--sys/i386/ibcs2/ibcs2_ioctl.c4
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c11
-rw-r--r--sys/i386/linux/linux_machdep.c5
-rw-r--r--sys/i386/xen/mp_machdep.c91
-rw-r--r--sys/ia64/ia64/vm_machdep.c22
-rw-r--r--sys/ia64/include/sf_buf.h12
-rw-r--r--sys/kern/capabilities.conf3
-rw-r--r--sys/kern/init_sysent.c6
-rw-r--r--sys/kern/kern_descrip.c158
-rw-r--r--sys/kern/kern_event.c12
-rw-r--r--sys/kern/kern_exec.c4
-rw-r--r--sys/kern/kern_jail.c7
-rw-r--r--sys/kern/kern_ktrace.c8
-rw-r--r--sys/kern/kern_mbuf.c2
-rw-r--r--sys/kern/kern_sig.c4
-rw-r--r--sys/kern/subr_capability.c285
-rw-r--r--sys/kern/subr_witness.c10
-rw-r--r--sys/kern/sys_capability.c170
-rw-r--r--sys/kern/sys_generic.c36
-rw-r--r--sys/kern/sys_procdesc.c12
-rw-r--r--sys/kern/syscalls.c6
-rw-r--r--sys/kern/syscalls.master8
-rw-r--r--sys/kern/systrace_args.c48
-rw-r--r--sys/kern/tty.c4
-rw-r--r--sys/kern/uipc_debug.c2
-rw-r--r--sys/kern/uipc_mqueue.c27
-rw-r--r--sys/kern/uipc_sem.c18
-rw-r--r--sys/kern/uipc_sockbuf.c4
-rw-r--r--sys/kern/uipc_socket.c7
-rw-r--r--sys/kern/uipc_syscalls.c384
-rw-r--r--sys/kern/uipc_usrreq.c8
-rw-r--r--sys/kern/vfs_acl.c18
-rw-r--r--sys/kern/vfs_aio.c13
-rw-r--r--sys/kern/vfs_bio.c4
-rw-r--r--sys/kern/vfs_extattr.c17
-rw-r--r--sys/kern/vfs_lookup.c33
-rw-r--r--sys/kern/vfs_mount.c10
-rw-r--r--sys/kern/vfs_syscalls.c384
-rw-r--r--sys/mips/atheros/if_arge.c26
-rw-r--r--sys/mips/conf/DIR-8253
-rw-r--r--sys/mips/conf/GXEMUL3261
-rw-r--r--sys/mips/gxemul/mpreg.h7
-rw-r--r--sys/mips/include/_stdint.h2
-rw-r--r--sys/mips/include/sf_buf.h12
-rw-r--r--sys/mips/mips/pmap.c2
-rw-r--r--sys/mips/mips/vm_machdep.c10
-rw-r--r--sys/modules/aesni/Makefile13
-rw-r--r--sys/modules/cam/Makefile1
-rw-r--r--sys/modules/hwpmc/Makefile2
-rw-r--r--sys/modules/send/Makefile2
-rw-r--r--sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c1
-rw-r--r--sys/netgraph/netflow/ng_netflow.h2
-rw-r--r--sys/netinet/ip_mroute.c28
-rw-r--r--sys/netinet/sctp_auth.c94
-rw-r--r--sys/netinet/sctp_auth.h14
-rw-r--r--sys/netinet/sctp_indata.c2
-rw-r--r--sys/netinet/sctp_os_bsd.h26
-rw-r--r--sys/netinet/sctp_output.c11
-rw-r--r--sys/netinet/sctp_structs.h2
-rw-r--r--sys/netinet/sctp_timer.c2
-rw-r--r--sys/netinet/sctp_uio.h4
-rw-r--r--sys/netinet/sctputil.c1
-rw-r--r--sys/netinet6/ip6_mroute.c4
-rw-r--r--sys/netpfil/pf/pf_lb.c55
-rw-r--r--sys/netsmb/smb_dev.c3
-rw-r--r--sys/nfsserver/nfs_srvkrpc.c4
-rw-r--r--sys/ofed/include/linux/file.h12
-rw-r--r--sys/powerpc/aim/trap.c10
-rw-r--r--sys/powerpc/aim/vm_machdep.c1
-rw-r--r--sys/powerpc/include/_stdint.h2
-rw-r--r--sys/powerpc/include/frame.h2
-rw-r--r--sys/powerpc/include/pmc_mdep.h3
-rw-r--r--sys/rpc/clnt_dg.c2
-rw-r--r--sys/security/audit/audit.h2
-rw-r--r--sys/security/audit/audit_arg.c4
-rw-r--r--sys/security/audit/audit_bsm.c3
-rw-r--r--sys/security/audit/audit_bsm_klib.c2
-rw-r--r--sys/security/audit/audit_private.h1
-rw-r--r--sys/security/audit/bsm_token.c16
-rw-r--r--sys/security/mac/mac_syscalls.c6
-rw-r--r--sys/sys/_types.h1
-rw-r--r--sys/sys/capability.h247
-rw-r--r--sys/sys/caprights.h61
-rw-r--r--sys/sys/file.h21
-rw-r--r--sys/sys/filedesc.h9
-rw-r--r--sys/sys/ktrace.h7
-rw-r--r--sys/sys/mount.h10
-rw-r--r--sys/sys/mouse.h3
-rw-r--r--sys/sys/namei.h29
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/procdesc.h4
-rw-r--r--sys/sys/sf_buf.h1
-rw-r--r--sys/sys/sockbuf.h2
-rw-r--r--sys/sys/syscall.h6
-rw-r--r--sys/sys/syscall.mk5
-rw-r--r--sys/sys/sysproto.h19
-rw-r--r--sys/sys/time.h159
-rw-r--r--sys/sys/types.h9
-rw-r--r--sys/sys/user.h4
-rw-r--r--sys/ufs/ffs/ffs_alloc.c7
-rw-r--r--sys/vm/vm_mmap.c12
-rw-r--r--sys/vm/vm_page.c10
-rw-r--r--sys/x86/xen/hvm.c22
-rw-r--r--tools/regression/bin/sh/builtins/return8.013
-rw-r--r--tools/regression/lib/libc/stdio/test-fmemopen.t7
-rw-r--r--tools/regression/lib/libc/stdio/test-fopen.c113
-rw-r--r--tools/regression/lib/libc/stdio/test-fopen.t10
-rw-r--r--tools/regression/lib/libc/stdio/test-mkostemp.t10
-rw-r--r--tools/regression/lib/libc/stdio/test-open_memstream.t7
-rw-r--r--tools/regression/lib/libc/stdio/test-open_wmemstream.t7
-rw-r--r--tools/tools/bus_autoconf/bus_load_file.c2
-rw-r--r--usr.bin/bmake/Makefile4
-rw-r--r--usr.bin/bmake/unit-tests/Makefile5
-rw-r--r--usr.bin/kdump/kdump.c71
-rw-r--r--usr.bin/kdump/mksubr24
-rw-r--r--usr.bin/patch/pch.c59
-rw-r--r--usr.bin/patch/util.c2
-rw-r--r--usr.bin/procstat/procstat_files.c18
-rw-r--r--usr.bin/rwho/rwho.c7
-rw-r--r--usr.bin/uniq/uniq.c13
-rw-r--r--usr.sbin/bhyve/ioapic.c4
-rw-r--r--usr.sbin/periodic/periodic.sh10
-rw-r--r--usr.sbin/rtadvd/if.c4
-rw-r--r--usr.sbin/rwhod/rwhod.c26
-rw-r--r--usr.sbin/watch/watch.c3
349 files changed, 7817 insertions, 8640 deletions
diff --git a/Makefile b/Makefile
index d002ca7..d324c7d 100644
--- a/Makefile
+++ b/Makefile
@@ -498,3 +498,11 @@ universe_epilogue:
buildLINT:
${MAKE} -C ${.CURDIR}/sys/${_TARGET}/conf LINT
+
+.if defined(.PARSEDIR)
+.if make(universe)
+# we do not want a failure of one branch abort all.
+MAKE_JOB_ERROR_TOKEN= no
+.export MAKE_JOB_ERROR_TOKEN
+.endif
+.endif
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 7399a6e..30ec49b 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,9 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20130903: gnupatch is no more
+OLD_FILES+=usr/bin/gnupatch
+OLD_FILES+=usr/share/man/man1/gnupatch.1.gz
# 20130829: bsdpatch is patch unconditionally
OLD_FILES+=usr/bin/bsdpatch
OLD_FILES+=usr/share/man/man1/bsdpatch.1.gz
diff --git a/UPDATING b/UPDATING
index aafbcf8..8238204 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,20 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20130905:
+ The PROCDESC kernel option is now part of the GENERIC kernel
+ configuration and is required for the rwhod(8) to work.
+ If you are using custom kernel configuration, you should include
+ 'options PROCDESC'.
+
+20130905:
+ The API and ABI related to the Capsicum framework was modified
+ in backward incompatible way. The userland libraries and programs
+ have to be recompiled to work with the new kernel. This includes the
+ following libraries and programs, but the whole buildworld is
+ advised: libc, libprocstat, dhclient, tcpdump, hastd, hastctl,
+ kdump, procstat, rwho, rwhod, uniq.
+
20130827:
Thomas Dickey (vendor author thereof) reports that dialog(1) since
2011/10/18 has a bug in handling --hline. Testers and I noticed the
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 655bf81..b8f76d5 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -324,7 +324,7 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
}
if (evalskip == SKIPBREAK && --skipcount <= 0)
evalskip = 0;
- if (evalskip == SKIPFUNC || evalskip == SKIPFILE)
+ if (evalskip == SKIPRETURN)
status = exitstatus;
break;
}
@@ -1068,7 +1068,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
funcnest--;
popredir();
INTON;
- if (evalskip == SKIPFUNC) {
+ if (evalskip == SKIPRETURN) {
evalskip = 0;
skipcount = 0;
}
@@ -1305,14 +1305,8 @@ returncmd(int argc, char **argv)
{
int ret = argc > 1 ? number(argv[1]) : oexitstatus;
- if (funcnest) {
- evalskip = SKIPFUNC;
- skipcount = 1;
- } else {
- /* skip the rest of the file */
- evalskip = SKIPFILE;
- skipcount = 1;
- }
+ evalskip = SKIPRETURN;
+ skipcount = 1;
return ret;
}
diff --git a/bin/sh/eval.h b/bin/sh/eval.h
index a6e87b2..4129757 100644
--- a/bin/sh/eval.h
+++ b/bin/sh/eval.h
@@ -67,5 +67,4 @@ extern int skipcount;
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
-#define SKIPFUNC 3
-#define SKIPFILE 4
+#define SKIPRETURN 3
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index b6ea4da..bbb954a 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -83,13 +83,12 @@ static struct job *bgjob = NULL; /* last background process */
static struct job *jobmru; /* most recently used job list */
static pid_t initialpgrp; /* pgrp of shell on invocation */
#endif
-int in_waitcmd = 0; /* are we in waitcmd()? */
-volatile sig_atomic_t breakwaitcmd = 0; /* should wait be terminated? */
static int ttyfd = -1;
/* mode flags for dowait */
#define DOWAIT_BLOCK 0x1 /* wait until a child exits */
-#define DOWAIT_SIG 0x2 /* if DOWAIT_BLOCK, abort on signals */
+#define DOWAIT_SIG 0x2 /* if DOWAIT_BLOCK, abort on SIGINT/SIGQUIT */
+#define DOWAIT_SIG_ANY 0x4 /* if DOWAIT_SIG, abort on any signal */
#if JOBS
static void restartjob(struct job *);
@@ -484,7 +483,7 @@ waitcmd(int argc __unused, char **argv __unused)
static int
waitcmdloop(struct job *job)
{
- int status, retval;
+ int status, retval, sig;
struct job *jp;
/*
@@ -492,7 +491,6 @@ waitcmdloop(struct job *job)
* received.
*/
- in_waitcmd++;
do {
if (job != NULL) {
if (job->state == JOBDONE) {
@@ -508,7 +506,6 @@ waitcmdloop(struct job *job)
if (job == bgjob)
bgjob = NULL;
}
- in_waitcmd--;
return retval;
}
} else {
@@ -524,7 +521,6 @@ waitcmdloop(struct job *job)
}
for (jp = jobtab ; ; jp++) {
if (jp >= jobtab + njobs) { /* no running procs */
- in_waitcmd--;
return 0;
}
if (jp->used && jp->state == 0)
@@ -532,9 +528,10 @@ waitcmdloop(struct job *job)
}
}
} while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1);
- in_waitcmd--;
- return pendingsig + 128;
+ sig = pendingsig_waitcmd;
+ pendingsig_waitcmd = 0;
+ return sig + 128;
}
@@ -990,7 +987,8 @@ waitforjob(struct job *jp, int *origstatus)
INTOFF;
TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1));
while (jp->state == 0)
- if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG : 0), jp) == -1)
+ if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG |
+ DOWAIT_SIG_ANY : 0), jp) == -1)
dotrap();
#if JOBS
if (jp->jobctl) {
@@ -1081,12 +1079,17 @@ dowait(int mode, struct job *job)
pid = wait3(&status, wflags, (struct rusage *)NULL);
TRACE(("wait returns %d, status=%d\n", (int)pid, status));
if (pid == 0 && (mode & DOWAIT_SIG) != 0) {
- sigsuspend(&omask);
pid = -1;
+ if (((mode & DOWAIT_SIG_ANY) != 0 ?
+ pendingsig : pendingsig_waitcmd) != 0) {
+ errno = EINTR;
+ break;
+ }
+ sigsuspend(&omask);
if (int_pending())
break;
}
- } while (pid == -1 && errno == EINTR && breakwaitcmd == 0);
+ } while (pid == -1 && errno == EINTR);
if (pid == -1 && errno == ECHILD && job != NULL)
job->state = JOBDONE;
if ((mode & DOWAIT_SIG) != 0) {
@@ -1095,11 +1098,6 @@ dowait(int mode, struct job *job)
sigprocmask(SIG_SETMASK, &omask, NULL);
INTON;
}
- if (breakwaitcmd != 0) {
- breakwaitcmd = 0;
- if (pid <= 0)
- return -1;
- }
if (pid <= 0)
return pid;
INTOFF;
diff --git a/bin/sh/jobs.h b/bin/sh/jobs.h
index 1570b46..892f129 100644
--- a/bin/sh/jobs.h
+++ b/bin/sh/jobs.h
@@ -83,8 +83,6 @@ enum {
};
extern int job_warning; /* user was warned about stopped jobs */
-extern int in_waitcmd; /* are we in waitcmd()? */
-extern volatile sig_atomic_t breakwaitcmd; /* break wait to process traps? */
void setjobctl(int);
void showjobs(int, int);
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 295f277..e4974ea 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -231,7 +231,7 @@ cmdloop(int top)
popstackmark(&smark);
setstackmark(&smark);
if (evalskip != 0) {
- if (evalskip == SKIPFILE)
+ if (evalskip == SKIPRETURN)
evalskip = 0;
break;
}
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 174788d..ea1d899 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -1145,8 +1145,10 @@ command is
.Pp
.D1 Ic return Op Ar exitstatus
.Pp
-It terminates the current executional scope, returning from the previous
-nested function, sourced script, or shell instance, in that order.
+It terminates the current executional scope, returning from the closest
+nested function or sourced script;
+if no function or sourced script is being executed,
+it exits the shell instance.
The
.Ic return
command is implemented as a special built-in command.
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index 1411289..3fc8566 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
static char sigmode[NSIG]; /* current value of signal */
volatile sig_atomic_t pendingsig; /* indicates some signal received */
+volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */
int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
@@ -389,23 +390,13 @@ onsig(int signo)
}
/* If we are currently in a wait builtin, prepare to break it */
- if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0) {
- breakwaitcmd = 1;
- pendingsig = signo;
- }
+ if (signo == SIGINT || signo == SIGQUIT)
+ pendingsig_waitcmd = signo;
if (trap[signo] != NULL && trap[signo][0] != '\0' &&
(signo != SIGCHLD || !ignore_sigchld)) {
gotsig[signo] = 1;
pendingsig = signo;
-
- /*
- * If a trap is set, not ignored and not the null command, we
- * need to make sure traps are executed even when a child
- * blocks signals.
- */
- if (Tflag && !(trap[signo][0] == ':' && trap[signo][1] == '\0'))
- breakwaitcmd = 1;
}
#ifndef NO_HISTORY
@@ -428,6 +419,7 @@ dotrap(void)
in_dotrap++;
for (;;) {
pendingsig = 0;
+ pendingsig_waitcmd = 0;
for (i = 1; i < NSIG; i++) {
if (gotsig[i]) {
gotsig[i] = 0;
diff --git a/bin/sh/trap.h b/bin/sh/trap.h
index 0a05d8d..a962251 100644
--- a/bin/sh/trap.h
+++ b/bin/sh/trap.h
@@ -34,6 +34,7 @@
*/
extern volatile sig_atomic_t pendingsig;
+extern volatile sig_atomic_t pendingsig_waitcmd;
extern int in_dotrap;
extern volatile sig_atomic_t gotwinch;
diff --git a/contrib/binutils/gas/config/tc-i386.c b/contrib/binutils/gas/config/tc-i386.c
index 5ba2ce2..6eb51aa 100644
--- a/contrib/binutils/gas/config/tc-i386.c
+++ b/contrib/binutils/gas/config/tc-i386.c
@@ -3990,7 +3990,8 @@ output_insn (void)
goto check_prefix;
}
}
- else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881)
+ else if (i.tm.base_opcode == 0x660f3880 || i.tm.base_opcode == 0x660f3881
+ || i.tm.base_opcode == 0x660f3882)
{
/* invept and invvpid are 3 byte instructions with a
mandatory prefix. */
@@ -4040,7 +4041,8 @@ output_insn (void)
*p++ = (i.tm.base_opcode >> 16) & 0xff;
}
else if (i.tm.base_opcode == 0x660f3880 ||
- i.tm.base_opcode == 0x660f3881)
+ i.tm.base_opcode == 0x660f3881 ||
+ i.tm.base_opcode == 0x660f3882)
{
p = frag_more (3);
*p++ = (i.tm.base_opcode >> 16) & 0xff;
diff --git a/contrib/binutils/opcodes/i386-dis.c b/contrib/binutils/opcodes/i386-dis.c
index 6ef0434..eb33089 100644
--- a/contrib/binutils/opcodes/i386-dis.c
+++ b/contrib/binutils/opcodes/i386-dis.c
@@ -550,6 +550,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
#define PREGRP104 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 104 } }
#define PREGRP105 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 105 } }
#define PREGRP106 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 106 } }
+#define PREGRP107 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 107 } }
#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
@@ -2668,6 +2669,14 @@ static const struct dis386 prefix_user_table[][4] = {
{ "pclmulqdq", { XM, EXx, Ib } },
{ "(bad)", { XX } },
},
+
+ /* PREGRP107 */
+ {
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "invpcid",{ Gm, Mo } },
+ { "(bad)", { XX } },
+ },
};
static const struct dis386 x86_64_table[][2] = {
@@ -2839,7 +2848,7 @@ static const struct dis386 three_byte_table[][256] = {
/* 80 */
{ PREGRP98 },
{ PREGRP99 },
- { "(bad)", { XX } },
+ { PREGRP107 },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
diff --git a/contrib/binutils/opcodes/i386-opc.tbl b/contrib/binutils/opcodes/i386-opc.tbl
index f1f5ae5..6cb7219 100644
--- a/contrib/binutils/opcodes/i386-opc.tbl
+++ b/contrib/binutils/opcodes/i386-opc.tbl
@@ -1498,3 +1498,7 @@ xsetbv, 0, 0xf01, 0xd1, CpuXSAVE, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSu
xsave, 1, 0xfae, 0x4, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
xsaveopt, 1, 0xfae, 0x6, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
xrstor, 1, 0xfae, 0x5, CpuXSAVE, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf, { BaseIndex|Disp8|Disp16|Disp32|Disp32S }
+
+// INVPCID
+invpcid, 2, 0x660f3882, None, CpuNo64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg32 }
+invpcid, 2, 0x660f3882, None, Cpu64, Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64, { BaseIndex|Disp8|Disp16|Disp32|Disp32S, Reg64 }
diff --git a/contrib/binutils/opcodes/i386-tbl.h b/contrib/binutils/opcodes/i386-tbl.h
index 4ee72a4..c42f565 100644
--- a/contrib/binutils/opcodes/i386-tbl.h
+++ b/contrib/binutils/opcodes/i386-tbl.h
@@ -3641,6 +3641,14 @@ const template i386_optab[] =
Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
{ BaseIndex|Disp8|Disp16|Disp32|Disp32S,
Reg64 } },
+ { "invpcid", 2, 0x660f3882, None, CpuNo64,
+ Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
+ { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+ Reg32 } },
+ { "invpcid", 2, 0x660f3882, None, Cpu64,
+ Modrm|IgnoreSize|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_xSuf|NoRex64,
+ { BaseIndex|Disp8|Disp16|Disp32|Disp32S,
+ Reg64 } },
{ "vmcall", 0, 0xf01, 0xc1, CpuVMX,
No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf|ImmExt,
{ 0 } },
diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index 21ab78e..251998f 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,24 @@
+2013-09-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130904
+ Merge with NetBSD make, pick up
+ o Add VAR_INTERNAL context, so that internal setting of
+ MAKEFILE does not override value set by makefiles.
+
+2013-09-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130902
+ Merge with NetBSD make, pick up
+ o CompatRunCommand: only apply shellErrFlag when errCheck is true
+
+2013-08-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130828
+ Merge with NetBSD make, pick up
+ o Fix VAR :sh = syntax from Will Andrews at freebsd.org
+ o Call Job_SetPrefix() from Job_Init() so makefiles have
+ opportunity to set .MAKE.JOB.PREFIX
+
2013-07-30 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20130730
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index b0d8b2e..d4b5dca 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -114,6 +114,7 @@ unit-tests/order
unit-tests/phony-end
unit-tests/posix
unit-tests/qequals
+unit-tests/sunshcmd
unit-tests/sysv
unit-tests/ternary
unit-tests/test.exp
diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile
index 1b1cd59..98df1e2 100644
--- a/contrib/bmake/Makefile
+++ b/contrib/bmake/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.17 2013/07/30 19:13:53 sjg Exp $
+# $Id: Makefile,v 1.20 2013/09/04 15:42:03 sjg Exp $
# Base version on src date
-MAKE_VERSION= 20130730
+MAKE_VERSION= 20130904
PROG= bmake
diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1
index 021a94a..df604e7 100644
--- a/contrib/bmake/bmake.1
+++ b/contrib/bmake/bmake.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.220 2013/07/30 19:09:57 sjg Exp $
+.\" $NetBSD: make.1,v 1.222 2013/08/11 09:53:49 apb Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd July 30, 2013
+.Dd August 11, 2013
.Dt MAKE 1
.Os
.Sh NAME
@@ -1971,6 +1971,12 @@ If the source is the special
.Ic .DOTLAST
target, then the current working
directory is searched last.
+.It Ic .PATH. Ns Va suffix
+Like
+.Ic .PATH
+but applies only to files with a particular suffix.
+The suffix must have been previously declared with
+.Ic .SUFFIXES .
.It Ic .PHONY
Apply the
.Ic .PHONY
diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1
index e18c267..ca49bb6 100644
--- a/contrib/bmake/bmake.cat1
+++ b/contrib/bmake/bmake.cat1
@@ -1257,6 +1257,10 @@ SSPPEECCIIAALL TTAARRGGEETTSS
source is the special ..DDOOTTLLAASSTT target, then the current working
directory is searched last.
+ ..PPAATTHH.._s_u_f_f_i_x
+ Like ..PPAATTHH but applies only to files with a particular suffix.
+ The suffix must have been previously declared with ..SSUUFFFFIIXXEESS.
+
..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources.
..PPRREECCIIOOUUSS
@@ -1374,4 +1378,4 @@ BBUUGGSS
There is no way of escaping a space character in a filename.
-NetBSD 5.1 July 30, 2013 NetBSD 5.1
+NetBSD 5.1 August 11, 2013 NetBSD 5.1
diff --git a/contrib/bmake/compat.c b/contrib/bmake/compat.c
index 3586048..b0bbc93 100644
--- a/contrib/bmake/compat.c
+++ b/contrib/bmake/compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $ */
+/* $NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.92 2013/07/05 22:14:56 sjg Exp $");
+__RCSID("$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -340,7 +340,7 @@ again:
/*
* The following work for any of the builtin shell specs.
*/
- if (shellErrFlag) {
+ if (errCheck && shellErrFlag) {
shargv[shargc++] = shellErrFlag;
}
if (DEBUG(SHELL))
diff --git a/contrib/bmake/job.c b/contrib/bmake/job.c
index 4d901b0..4e22959 100644
--- a/contrib/bmake/job.c
+++ b/contrib/bmake/job.c
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $ */
+/* $NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $");
+__RCSID("$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -178,6 +178,14 @@ __RCSID("$NetBSD: job.c,v 1.175 2013/07/30 19:09:57 sjg Exp $");
*/
#define MAKE_ALWAYS_PASS_JOB_QUEUE ".MAKE.ALWAYS_PASS_JOB_QUEUE"
static int Always_pass_job_queue = TRUE;
+/*
+ * FreeBSD: aborting entire parallel make isn't always
+ * desired. When doing tinderbox for example, failure of
+ * one architecture should not stop all.
+ * We still want to bail on interrupt though.
+ */
+#define MAKE_JOB_ERROR_TOKEN "MAKE_JOB_ERROR_TOKEN"
+static int Job_error_token = TRUE;
/*
* error handling variables
@@ -2237,6 +2245,9 @@ Job_Init(void)
Always_pass_job_queue = getBoolean(MAKE_ALWAYS_PASS_JOB_QUEUE,
Always_pass_job_queue);
+ Job_error_token = getBoolean(MAKE_JOB_ERROR_TOKEN, Job_error_token);
+
+
/*
* There is a non-zero chance that we already have children.
* eg after 'make -f- <<EOF'
@@ -2832,13 +2843,19 @@ JobTokenAdd(void)
{
char tok = JOB_TOKENS[aborting], tok1;
+ if (!Job_error_token && aborting == ABORT_ERROR) {
+ if (jobTokensRunning == 0)
+ return;
+ tok = '+'; /* no error token */
+ }
+
/* If we are depositing an error token flush everything else */
while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1)
continue;
if (DEBUG(JOB))
fprintf(debug_file, "(%d) aborting %d, deposit token %c\n",
- getpid(), aborting, JOB_TOKENS[aborting]);
+ getpid(), aborting, tok);
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
continue;
}
diff --git a/contrib/bmake/main.c b/contrib/bmake/main.c
index f4445c9..45a45e0 100644
--- a/contrib/bmake/main.c
+++ b/contrib/bmake/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.222 2013/07/18 15:31:49 sjg Exp $ */
+/* $NetBSD: main.c,v 1.224 2013/09/04 15:38:26 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.222 2013/07/18 15:31:49 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.224 2013/09/04 15:38:26 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.222 2013/07/18 15:31:49 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.224 2013/09/04 15:38:26 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1414,7 +1414,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
if (!strcmp(fname, "-")) {
Parse_File(NULL /*stdin*/, -1);
- Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
+ Var_Set("MAKEFILE", "", VAR_INTERNAL, 0);
} else {
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
@@ -1463,7 +1463,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
*/
found:
if (!doing_depend)
- Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
+ Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0);
Parse_File(fname, fd);
}
free(path);
diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1
index 0dec8ef..c4b647d 100644
--- a/contrib/bmake/make.1
+++ b/contrib/bmake/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.220 2013/07/30 19:09:57 sjg Exp $
+.\" $NetBSD: make.1,v 1.222 2013/08/11 09:53:49 apb Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd July 30, 2013
+.Dd August 11, 2013
.Dt MAKE 1
.Os
.Sh NAME
@@ -1982,6 +1982,12 @@ If the source is the special
.Ic .DOTLAST
target, then the current working
directory is searched last.
+.It Ic .PATH. Ns Va suffix
+Like
+.Ic .PATH
+but applies only to files with a particular suffix.
+The suffix must have been previously declared with
+.Ic .SUFFIXES .
.It Ic .PHONY
Apply the
.Ic .PHONY
diff --git a/contrib/bmake/make.h b/contrib/bmake/make.h
index c51fbe5..b13716fd 100644
--- a/contrib/bmake/make.h
+++ b/contrib/bmake/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.91 2013/06/18 20:06:09 sjg Exp $ */
+/* $NetBSD: make.h,v 1.92 2013/09/04 15:38:26 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -404,6 +404,10 @@ extern Boolean varNoExportEnv; /* TRUE if we should not export variables
extern GNode *DEFAULT; /* .DEFAULT rule */
+extern GNode *VAR_INTERNAL; /* Variables defined internally by make
+ * which should not override those set by
+ * makefiles.
+ */
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
* in the Makefile itself */
extern GNode *VAR_CMD; /* Variables defined on the command line */
diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog
index db1e289..b547197 100644
--- a/contrib/bmake/mk/ChangeLog
+++ b/contrib/bmake/mk/ChangeLog
@@ -1,3 +1,14 @@
+2013-09-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * gendirdeps.mk (_objtops): fix typo also
+ while processing M2D_OBJROOTS to gather qualdir_list
+ qualify $ql with loop iterator to ensure correct results.
+
+2013-08-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20130801
+ * libs.mk: update to match progs.mk
+
2013-07-26 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): 20130726
diff --git a/contrib/bmake/mk/gendirdeps.mk b/contrib/bmake/mk/gendirdeps.mk
index 9be3673..20e2b15 100644
--- a/contrib/bmake/mk/gendirdeps.mk
+++ b/contrib/bmake/mk/gendirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: gendirdeps.mk,v 1.22 2013/05/11 05:16:26 sjg Exp $
+# $Id: gendirdeps.mk,v 1.23 2013/09/04 17:49:20 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
@@ -162,7 +162,7 @@ dir_list != cd ${_OBJDIR} && \
.warning Skipping ${_DEPENDFILE:S,${SRCTOP}/,,}
# we are not going to update anything
.else
-
+dpadd_dir_list=
.if !empty(DPADD)
_nonlibs := ${DPADD:T:Nlib*:N*include}
.if !empty(_nonlibs)
@@ -174,6 +174,7 @@ ddep_list += $f.dirdep
ddep_list += ${f:H}.dirdep
.else
dir_list += ${f:H:tA}
+dpadd_dir_list += ${f:H:tA}
.endif
.endfor
.if !empty(ddep_list)
@@ -197,7 +198,7 @@ dir_list += ${ddeps}
# so we add
# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
# to GENDIRDEPS_DIR_LIST_XTRAS
-_objtops = ${OBJTOP} ${_OBJTOP} ${_obtop}
+_objtops = ${OBJTOP} ${_OBJTOP} ${_objtop}
_objtops := ${_objtops:O:u}
dirdep_list = \
${_objtops:@o@${dir_list:M$o*/*:C,$o[^/]*/,,}@} \
@@ -212,8 +213,11 @@ M2D_OBJROOTS := ${M2D_OBJROOTS:O:u:[-1..1]}
skip_ql= ${SRCTOP}* ${_objtops:@o@$o*@}
.for o in ${M2D_OBJROOTS:${skip_ql:${M_ListToSkip}}}
# we need := so only skip_ql to this point applies
-ql := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
-qualdir_list += ${ql}
+ql.$o := ${dir_list:${skip_ql:${M_ListToSkip}}:M$o*/*/*:C,$o([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
+qualdir_list += ${ql.$o}
+.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
+.info ${RELDIR}: o=$o ${ql.$o qualdir_list:L:@v@$v=${$v}@}
+.endif
skip_ql+= $o*
.endfor
@@ -241,6 +245,7 @@ DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u}
.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
.info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS}
.info ${RELDIR}: dir_list='${dir_list}'
+.info ${RELDIR}: dpadd_dir_list='${dpadd_dir_list}'
.info ${RELDIR}: dirdep_list='${dirdep_list}'
.info ${RELDIR}: qualdir_list='${qualdir_list}'
.info ${RELDIR}: SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS}'
diff --git a/contrib/bmake/mk/install-mk b/contrib/bmake/mk/install-mk
index 59b1b01..0640906 100644
--- a/contrib/bmake/mk/install-mk
+++ b/contrib/bmake/mk/install-mk
@@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: install-mk,v 1.92 2013/07/27 05:37:37 sjg Exp $
+# $Id: install-mk,v 1.93 2013/08/02 18:28:47 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -70,7 +70,7 @@
# sjg@crufty.net
#
-MK_VERSION=20130726
+MK_VERSION=20130801
OWNER=
GROUP=
MODE=444
diff --git a/contrib/bmake/mk/libs.mk b/contrib/bmake/mk/libs.mk
index 05b4506..7f974bf 100644
--- a/contrib/bmake/mk/libs.mk
+++ b/contrib/bmake/mk/libs.mk
@@ -1,4 +1,4 @@
-# $Id: libs.mk,v 1.2 2007/04/30 17:39:27 sjg Exp $
+# $Id: libs.mk,v 1.3 2013/08/02 18:28:48 sjg Exp $
#
# @(#) Copyright (c) 2006, Simon J. Gerraty
#
@@ -17,7 +17,15 @@
.if defined(LIBS)
+# In meta mode, we can capture dependenices for _one_ of the progs.
+# if makefile doesn't nominate one, we use the first.
+.ifndef UPDATE_DEPENDFILE_LIB
+UPDATE_DEPENDFILE_LIB = ${LIBS:[1]}
+.export UPDATE_DEPENDFILE_LIB
+.endif
+
.ifndef LIB
+# They may have asked us to build just one
.for t in ${LIBS:R:T:S,^lib,,}
.if make(lib$t)
LIB?= $t
@@ -28,14 +36,41 @@ lib$t: all
.if defined(LIB)
# just one of many
-.for v in DPADD SRCS CFLAGS ${LIB_VARS}
-$v += ${${v}_lib${LIB}}
+LIB_VARS += \
+ LIBDIR \
+ CFLAGS \
+ COPTS \
+ CPPFLAGS \
+ CXXFLAGS \
+ DPADD \
+ DPLIBS \
+ LDADD \
+ LDFLAGS \
+ MAN \
+ SRCS
+
+.for v in ${LIB_VARS:O:u}
+.if defined(${v}.${LIB}) || defined(${v}_${LIB})
+$v += ${${v}_${LIB}:U${${v}.${LIB}}}
+.endif
.endfor
+
+# for meta mode, there can be only one!
+.if ${LIB} == ${UPDATE_DEPENDFILE_LIB:Uno}
+UPDATE_DEPENDFILE ?= yes
+.endif
+UPDATE_DEPENDFILE ?= NO
+
# ensure that we don't clobber each other's dependencies
DEPENDFILE?= .depend.${LIB}
# lib.mk will do the rest
.else
all: ${LIBS:S,^lib,,:@t@lib$t.a@} .MAKE
+
+# We cannot capture dependencies for meta mode here
+UPDATE_DEPENDFILE = NO
+# nor can we safely run in parallel.
+.NOTPARALLEL:
.endif
.endif
@@ -43,12 +78,16 @@ all: ${LIBS:S,^lib,,:@t@lib$t.a@} .MAKE
.include <${.PARSEFILE:S,libs,lib,}>
.ifndef LIB
-.for t in ${LIBS:R:T:S,^lib,,}
-lib$t.a: ${SRCS} ${DPADD} ${SRCS_lib$t} ${DPADD_lib$t}
- (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$t)
+# tell libs.mk we might want to install things
+LIBS_TARGETS+= cleandepend cleandir cleanobj depend install
-clean: $t.clean
-$t.clean:
- (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$t ${@:E})
+.for b in ${LIBS:R:T:S,^lib,,}
+lib$b.a: ${SRCS} ${DPADD} ${SRCS_lib$b} ${DPADD_lib$b}
+ (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b)
+
+.for t in ${LIBS_TARGETS:O:u}
+$b.$t: .PHONY .MAKE
+ (cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} LIB=$b ${@:E})
+.endfor
.endfor
.endif
diff --git a/contrib/bmake/mk/progs.mk b/contrib/bmake/mk/progs.mk
index f74f640..7ccebbf 100644
--- a/contrib/bmake/mk/progs.mk
+++ b/contrib/bmake/mk/progs.mk
@@ -1,4 +1,4 @@
-# $Id: progs.mk,v 1.12 2013/04/22 18:10:04 sjg Exp $
+# $Id: progs.mk,v 1.13 2013/08/02 18:28:48 sjg Exp $
#
# @(#) Copyright (c) 2006, Simon J. Gerraty
#
@@ -35,9 +35,21 @@ PROG ?= $t
.if defined(PROG)
# just one of many
-PROG_VARS += BINDIR CFLAGS CPPFLAGS CXXFLAGS DPADD DPLIBS LDADD MAN SRCS
+PROG_VARS += \
+ BINDIR \
+ CFLAGS \
+ COPTS \
+ CPPFLAGS \
+ CXXFLAGS \
+ DPADD \
+ DPLIBS \
+ LDADD \
+ LDFLAGS \
+ MAN \
+ SRCS
+
.for v in ${PROG_VARS:O:u}
-.if defined(${v}.${PROG})
+.if defined(${v}.${PROG}) || defined(${v}_${PROG})
$v += ${${v}_${PROG}:U${${v}.${PROG}}}
.endif
.endfor
diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c
index 5096767..41323b5 100644
--- a/contrib/bmake/parse.c
+++ b/contrib/bmake/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $ */
+/* $NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.189 2013/06/18 19:31:27 sjg Exp $");
+__RCSID("$NetBSD: parse.c,v 1.191 2013/08/28 21:56:49 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1751,6 +1751,12 @@ Parse_IsVar(char *line)
ch = *line++;
wasSpace = TRUE;
}
+#ifdef SUNSHCMD
+ if (ch == ':' && strncmp(line, "sh", 2) == 0) {
+ line += 2;
+ continue;
+ }
+#endif
if (ch == '=')
return TRUE;
if (*line == '=' && ISEQOPERATOR(ch))
diff --git a/contrib/bmake/unit-tests/Makefile.in b/contrib/bmake/unit-tests/Makefile.in
index 78ca92f..3f70f8a 100644
--- a/contrib/bmake/unit-tests/Makefile.in
+++ b/contrib/bmake/unit-tests/Makefile.in
@@ -1,6 +1,6 @@
-# $Id: Makefile.in,v 1.43 2013/07/16 21:14:30 sjg Exp $
+# $Id: Makefile.in,v 1.44 2013/08/28 22:09:29 sjg Exp $
#
-# $NetBSD: Makefile,v 1.37 2013/07/16 19:59:28 sjg Exp $
+# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $
#
# Unit tests for make(1)
# The main targets are:
@@ -45,6 +45,7 @@ SUBFILES= \
phony-end \
posix \
qequals \
+ sunshcmd \
sysv \
ternary \
unexport \
diff --git a/contrib/bmake/unit-tests/sunshcmd b/contrib/bmake/unit-tests/sunshcmd
new file mode 100644
index 0000000..e3baf90
--- /dev/null
+++ b/contrib/bmake/unit-tests/sunshcmd
@@ -0,0 +1,10 @@
+BYECMD = echo bye
+LATERCMD = echo later
+TEST1 :sh = echo hello
+TEST2 :sh = ${BYECMD}
+TEST3 = ${LATERCMD:sh}
+
+all:
+ @echo "TEST1=${TEST1}"
+ @echo "TEST2=${TEST2}"
+ @echo "TEST3=${TEST3}"
diff --git a/contrib/bmake/unit-tests/test.exp b/contrib/bmake/unit-tests/test.exp
index b6fad78..aaecb96 100644
--- a/contrib/bmake/unit-tests/test.exp
+++ b/contrib/bmake/unit-tests/test.exp
@@ -349,6 +349,9 @@ Now we expect an error...
*** Error code 1 (continuing)
`all' not remade because of errors.
V.i386 ?= OK
+TEST1=hello
+TEST2=bye
+TEST3=later
FOOBAR =
FOOBAR = foobar fubar
fun
diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c
index c4a6735..dd911f9 100644
--- a/contrib/bmake/var.c
+++ b/contrib/bmake/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $ */
+/* $NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.183 2013/07/16 20:00:56 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -187,6 +187,7 @@ static char varNoError[] = "";
* The four contexts are searched in the reverse order from which they are
* listed.
*/
+GNode *VAR_INTERNAL; /* variables from make itself */
GNode *VAR_GLOBAL; /* variables from the makefile */
GNode *VAR_CMD; /* variables defined on the command-line */
@@ -419,6 +420,10 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+ /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
+ var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+ }
}
if ((var == NULL) && (flags & FIND_ENV)) {
char *env;
@@ -440,6 +445,9 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+ var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+ }
if (var == NULL) {
return NULL;
} else {
@@ -4182,6 +4190,7 @@ Var_GetHead(char *file)
void
Var_Init(void)
{
+ VAR_INTERNAL = Targ_NewGN("Internal");
VAR_GLOBAL = Targ_NewGN("Global");
VAR_CMD = Targ_NewGN("Command");
diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c
index 0187cb2..1598ae9 100644
--- a/contrib/gcc/config/i386/i386.c
+++ b/contrib/gcc/config/i386/i386.c
@@ -1684,6 +1684,14 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
}
return true;
+ case OPT_maes:
+ if (!value)
+ {
+ target_flags &= ~MASK_AES;
+ target_flags_explicit |= MASK_AES;
+ }
+ return true;
+
default:
return true;
}
@@ -2187,6 +2195,10 @@ override_options (void)
if (TARGET_SSE3)
target_flags |= MASK_SSE2;
+ /* Turn on SSE2 builtins for -maes. */
+ if (TARGET_AES)
+ target_flags |= MASK_SSE2;
+
/* Turn on SSE builtins for -msse2. */
if (TARGET_SSE2)
target_flags |= MASK_SSE;
diff --git a/contrib/gcc/config/i386/i386.h b/contrib/gcc/config/i386/i386.h
index e918fc3..1394fba 100644
--- a/contrib/gcc/config/i386/i386.h
+++ b/contrib/gcc/config/i386/i386.h
@@ -428,6 +428,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
builtin_define ("__SSSE3__"); \
if (TARGET_SSE4A) \
builtin_define ("__SSE4A__"); \
+ if (TARGET_AES) \
+ builtin_define ("__AES__"); \
if (TARGET_SSE_MATH && TARGET_SSE) \
builtin_define ("__SSE_MATH__"); \
if (TARGET_SSE_MATH && TARGET_SSE2) \
diff --git a/contrib/gcc/config/i386/i386.opt b/contrib/gcc/config/i386/i386.opt
index fa73e17..4de7569 100644
--- a/contrib/gcc/config/i386/i386.opt
+++ b/contrib/gcc/config/i386/i386.opt
@@ -205,6 +205,10 @@ msse4a
Target Report Mask(SSE4A)
Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation
+maes
+Target Report Mask(AES)
+Support AES built-in functions and code generation.
+
mpopcnt
Target Report Mask(POPCNT)
Support code generation of popcount instruction for popcount built-ins
diff --git a/contrib/gcc/doc/invoke.texi b/contrib/gcc/doc/invoke.texi
index 0f66c3d..13b9ae9 100644
--- a/contrib/gcc/doc/invoke.texi
+++ b/contrib/gcc/doc/invoke.texi
@@ -513,7 +513,7 @@ in the following sections.
-mno-fp-ret-in-387 -msoft-float -msvr3-shlib @gol
-mno-wide-multiply -mrtd -malign-double @gol
-mpreferred-stack-boundary=@var{num} @gol
--mmmx -msse -msse2 -msse3 -mssse3 -msse4a -m3dnow -mpopcnt -mabm @gol
+-mmmx -msse -msse2 -msse3 -mssse3 -msse4a -m3dnow -mpopcnt -mabm -maes @gol
-mthreads -mno-align-stringops -minline-all-stringops @gol
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
-m96bit-long-double -mregparm=@var{num} -msseregparm @gol
@@ -9367,6 +9367,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mno-popcnt
@item -mabm
@itemx -mno-abm
+@item -maes
+@itemx -mno-aes
@opindex mmmx
@opindex mno-mmx
@opindex msse
@@ -9374,10 +9376,10 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@opindex m3dnow
@opindex mno-3dnow
These switches enable or disable the use of instructions in the MMX,
-SSE, SSE2, SSE3, SSSE3, SSE4A, ABM or 3DNow! extended instruction sets.
-These extensions are also available as built-in functions: see
-@ref{X86 Built-in Functions}, for details of the functions enabled and
-disabled by these switches.
+SSE, SSE2, SSE3, SSSE3, SSE4A, ABM, AES or 3DNow! extended
+instruction sets. These extensions are also available as built-in
+functions: see @ref{X86 Built-in Functions}, for details of the functions
+enabled and disabled by these switches.
To have SSE/SSE2 instructions generated automatically from floating-point
code (as opposed to 387 instructions), see @option{-mfpmath=sse}.
diff --git a/contrib/gcc/opth-gen.awk b/contrib/gcc/opth-gen.awk
index e7ffc1a..84b3170 100644
--- a/contrib/gcc/opth-gen.awk
+++ b/contrib/gcc/opth-gen.awk
@@ -87,7 +87,7 @@ for (i = 0; i < n_extra_masks; i++) {
}
for (var in masknum) {
- if (masknum[var] > 31) {
+ if (masknum[var] > 32) {
if (var == "")
print "#error too many target masks"
else
diff --git a/contrib/libexecinfo/execinfo.h b/contrib/libexecinfo/execinfo.h
index 0ea529e..2246096 100644
--- a/contrib/libexecinfo/execinfo.h
+++ b/contrib/libexecinfo/execinfo.h
@@ -1,4 +1,5 @@
/* $NetBSD: execinfo.h,v 1.2 2012/06/09 21:22:17 christos Exp $ */
+/* $FreeBSD$ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c
index 48b774d..afcc152 100644
--- a/contrib/tcpdump/tcpdump.c
+++ b/contrib/tcpdump/tcpdump.c
@@ -715,8 +715,9 @@ main(int argc, char **argv)
int status;
FILE *VFile;
#ifdef __FreeBSD__
+ cap_rights_t rights;
int cansandbox;
-#endif
+#endif /* __FreeBSD__ */
#ifdef WIN32
if(wsockinit() != 0) return 1;
@@ -1206,7 +1207,8 @@ main(int argc, char **argv)
if (pd == NULL)
error("%s", ebuf);
#ifdef __FreeBSD__
- if (cap_rights_limit(fileno(pcap_file(pd)), CAP_READ) < 0 &&
+ cap_rights_init(&rights, CAP_READ);
+ if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
@@ -1484,8 +1486,9 @@ main(int argc, char **argv)
if (RFileName == NULL && VFileName == NULL) {
static const unsigned long cmds[] = { BIOCGSTATS };
- if (cap_rights_limit(pcap_fileno(pd),
- CAP_IOCTL | CAP_READ) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
+ if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
+ errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
if (cap_ioctls_limit(pcap_fileno(pd), cmds,
@@ -1516,8 +1519,9 @@ main(int argc, char **argv)
if (p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
- if (cap_rights_limit(fileno(pcap_dump_file(p)),
- CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(fileno(pcap_dump_file(p)), &rights) < 0 &&
+ errno != ENOSYS) {
error("unable to limit dump descriptor");
}
#endif
@@ -1530,9 +1534,10 @@ main(int argc, char **argv)
error("unable to open directory %s",
dirname(WFileName));
}
- if (cap_rights_limit(dumpinfo.dirfd, CAP_CREATE |
- CAP_FCNTL | CAP_FTRUNCATE | CAP_LOOKUP | CAP_SEEK |
- CAP_WRITE) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL,
+ CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 &&
+ errno != ENOSYS) {
error("unable to limit directory rights");
}
#else /* !__FreeBSD__ */
@@ -1615,7 +1620,7 @@ main(int argc, char **argv)
error("unable to enter the capability mode");
if (cap_sandboxed())
fprintf(stderr, "capability mode sandbox enabled\n");
-#endif
+#endif /* __FreeBSD__ */
do {
status = pcap_loop(pd, cnt, callback, pcap_userdata);
@@ -1657,8 +1662,9 @@ main(int argc, char **argv)
if (pd == NULL)
error("%s", ebuf);
#ifdef __FreeBSD__
+ cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)),
- CAP_READ) < 0 && errno != ENOSYS) {
+ &rights) < 0 && errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
#endif
@@ -1830,6 +1836,9 @@ static void
dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
struct dump_info *dump_info;
+#ifdef __FreeBSD__
+ cap_rights_t rights;
+#endif
++packets_captured;
@@ -1933,8 +1942,9 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
if (dump_info->p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
+ cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
- CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+ &rights) < 0 && errno != ENOSYS) {
error("unable to limit dump descriptor");
}
#endif
@@ -1993,8 +2003,9 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
if (dump_info->p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
+ cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
- CAP_SEEK | CAP_WRITE) < 0 && errno != ENOSYS) {
+ &rights) < 0 && errno != ENOSYS) {
error("unable to limit dump descriptor");
}
#endif
diff --git a/etc/defaults/periodic.conf b/etc/defaults/periodic.conf
index 5dd7fa9..9fb6859 100644
--- a/etc/defaults/periodic.conf
+++ b/etc/defaults/periodic.conf
@@ -162,6 +162,71 @@ daily_scrub_zfs_default_threshold="35" # days between scrubs
daily_local="/etc/daily.local" # Local scripts
+# Weekly options
+
+# These options are used by periodic(8) itself to determine what to do
+# with the output of the sub-programs that are run, and where to send
+# that output. $weekly_output might be set to /var/log/weekly.log if you
+# wish to log the weekly output and have the files rotated by newsyslog(8)
+#
+weekly_output="root" # user or /file
+weekly_show_success="YES" # scripts returning 0
+weekly_show_info="YES" # scripts returning 1
+weekly_show_badconfig="NO" # scripts returning 2
+
+# 310.locate
+weekly_locate_enable="YES" # Update locate weekly
+
+# 320.whatis
+weekly_whatis_enable="YES" # Update whatis weekly
+
+# 330.catman
+weekly_catman_enable="NO" # Preformat man pages
+
+# 340.noid
+weekly_noid_enable="NO" # Find unowned files
+weekly_noid_dirs="/" # Look here
+
+# 400.status-pkg
+weekly_status_pkg_enable="NO" # Find out-of-date pkgs
+pkg_version=pkg_version # Use this program
+pkg_version_index=/usr/ports/INDEX-10 # Use this index file
+
+# 450.status-security
+weekly_status_security_enable="YES" # Security check
+# See also "Security options" above for more options
+weekly_status_security_inline="NO" # Run inline ?
+weekly_status_security_output="root" # user or /file
+
+# 999.local
+weekly_local="/etc/weekly.local" # Local scripts
+
+
+# Monthly options
+
+# These options are used by periodic(8) itself to determine what to do
+# with the output of the sub-programs that are run, and where to send
+# that output. $monthly_output might be set to /var/log/monthly.log if you
+# wish to log the monthly output and have the files rotated by newsyslog(8)
+#
+monthly_output="root" # user or /file
+monthly_show_success="YES" # scripts returning 0
+monthly_show_info="YES" # scripts returning 1
+monthly_show_badconfig="NO" # scripts returning 2
+
+# 200.accounting
+monthly_accounting_enable="YES" # Login accounting
+
+# 450.status-security
+monthly_status_security_enable="YES" # Security check
+# See also "Security options" above for more options
+monthly_status_security_inline="NO" # Run inline ?
+monthly_status_security_output="root" # user or /file
+
+# 999.local
+monthly_local="/etc/monthly.local" # Local scripts
+
+
# Security options
# These options are used by the security periodic(8) scripts spawned in
@@ -169,11 +234,14 @@ daily_local="/etc/daily.local" # Local scripts
security_status_logdir="/var/log" # Directory for logs
security_status_diff_flags="-b -u" # flags for diff output
-# Each of the security_status_*_enable options below can have one of the
+# Each of the security_status_*_period options below can have one of the
# following values:
-# - NO
+# - NO: do not run at all
# - daily: only run during the daily security status
# - weekly: only run during the weekly security status
+# - monthly: only run during the monthly security status
+# Note that if periodic security scripts are run from crontab(5) directly,
+# they will be run unless _enable or _period is set to "NO".
# 100.chksetuid
security_status_chksetuid_enable="YES"
@@ -239,70 +307,6 @@ security_status_tcpwrap_enable="YES"
security_status_tcpwrap_period="daily"
-# Weekly options
-
-# These options are used by periodic(8) itself to determine what to do
-# with the output of the sub-programs that are run, and where to send
-# that output. $weekly_output might be set to /var/log/weekly.log if you
-# wish to log the weekly output and have the files rotated by newsyslog(8)
-#
-weekly_output="root" # user or /file
-weekly_show_success="YES" # scripts returning 0
-weekly_show_info="YES" # scripts returning 1
-weekly_show_badconfig="NO" # scripts returning 2
-
-# 310.locate
-weekly_locate_enable="YES" # Update locate weekly
-
-# 320.whatis
-weekly_whatis_enable="YES" # Update whatis weekly
-
-# 330.catman
-weekly_catman_enable="NO" # Preformat man pages
-
-# 340.noid
-weekly_noid_enable="NO" # Find unowned files
-weekly_noid_dirs="/" # Look here
-
-# 400.status-pkg
-weekly_status_pkg_enable="NO" # Find out-of-date pkgs
-pkg_version=pkg_version # Use this program
-pkg_version_index=/usr/ports/INDEX-10 # Use this index file
-
-# 450.status-security
-weekly_status_security_enable="YES" # Security check
-# See also "Security options" above for more options
-weekly_status_security_inline="NO" # Run inline ?
-weekly_status_security_output="root" # user or /file
-
-# 999.local
-weekly_local="/etc/weekly.local" # Local scripts
-
-
-# Monthly options
-
-# These options are used by periodic(8) itself to determine what to do
-# with the output of the sub-programs that are run, and where to send
-# that output. $monthly_output might be set to /var/log/monthly.log if you
-# wish to log the monthly output and have the files rotated by newsyslog(8)
-#
-monthly_output="root" # user or /file
-monthly_show_success="YES" # scripts returning 0
-monthly_show_info="YES" # scripts returning 1
-monthly_show_badconfig="NO" # scripts returning 2
-
-# 200.accounting
-monthly_accounting_enable="YES" # Login accounting
-
-# 450.status-security
-monthly_status_security_enable="YES" # Security check
-# See also "Security options" above for more options
-monthly_status_security_inline="NO" # Run inline ?
-monthly_status_security_output="root" # user or /file
-
-# 999.local
-monthly_local="/etc/monthly.local" # Local scripts
-
# Define source_periodic_confs, the mechanism used by /etc/periodic/*/*
# scripts to source defaults/periodic.conf overrides safely.
diff --git a/etc/devd/usb.conf b/etc/devd/usb.conf
index 8be81ed..449b20b 100644
--- a/etc/devd/usb.conf
+++ b/etc/devd/usb.conf
@@ -129,7 +129,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x0403";
- match "product" "(0x6001|0x6004|0x6006|0x6006|0x6010|0x6011|0x6014|0x8372|0x9378|0x9379|0x937a|0x937c|0x9868|0x9e90|0x9f80|0xa6d0|0xabb8|0xb810|0xb811|0xb812|0xbaf8|0xbbe2|0xbca0|0xbca1|0xbca2|0xbca4|0xbcd8|0xbcd9|0xbcda|0xbdc8|0xbfd8|0xbfd9|0xbfda|0xbfdb|0xbfdc|0xc7d0|0xc850|0xc991|0xcaa0|0xcc48|0xcc49|0xcc4a|0xd010|0xd011|0xd012|0xd013|0xd014|0xd015|0xd016|0xd017|0xd070|0xd071|0xd388|0xd389|0xd38a|0xd38b|0xd38c|0xd38d|0xd38e|0xd38f|0xd578|0xd678|0xd738|0xd780|0xdaf8|0xdaf9|0xdafa|0xdafb|0xdafc|0xdafd|0xdafe|0xdaff|0xdc00|0xdc01|0xdd20|0xdf28|0xdf30|0xdf31|0xdf32|0xdf33|0xdf35|0xe000|0xe001|0xe002|0xe004|0xe006|0xe008|0xe009|0xe00a|0xe050|0xe0e8|0xe0e9|0xe0ea|0xe0eb|0xe0ec|0xe0ed|0xe0ee|0xe0ef|0xe0f0|0xe0f1|0xe0f2|0xe0f3|0xe0f4|0xe0f5|0xe0f6|0xe0f7|0xe40b|0xe520|0xe548|0xe6c8|0xe700|0xe729|0xe808|0xe809|0xe80a|0xe80b|0xe80c|0xe80d|0xe80e|0xe80f|0xe888|0xe889|0xe88a|0xe88b|0xe88c|0xe88d|0xe88e|0xe88f|0xea90|0xebe0|0xec88|0xec89|0xed22|0xed71|0xed72|0xed73|0xed74|0xee18|0xeee8|0xeee9|0xeeea|0xeeeb|0xeeec|0xeeed|0xeeee|0xeeef|0xef50|0xef51|0xf068|0xf069|0xf06a|0xf06b|0xf06c|0xf06d|0xf06e|0xf06f|0xf070|0xf0c0|0xf0c8|0xf208|0xf2d0|0xf3c0|0xf3c1|0xf3c2|0xf448|0xf449|0xf44a|0xf44b|0xf44c|0xf460|0xf608|0xf60b|0xf680|0xf850|0xf857|0xf9d0|0xf9d1|0xf9d2|0xf9d3|0xf9d4|0xf9d5|0xfa00|0xfa01|0xfa02|0xfa03|0xfa04|0xfa05|0xfa06|0xfa10|0xfa33|0xfa88|0xfad0|0xfaf0|0xfb58|0xfb59|0xfb5a|0xfb5b|0xfb5c|0xfb5d|0xfb5e|0xfb5f|0xfb80|0xfb99|0xfbfa|0xfc08|0xfc09|0xfc0a|0xfc0b|0xfc0c|0xfc0d|0xfc0e|0xfc0f|0xfc60|0xfc70|0xfc71|0xfc72|0xfc73|0xfc82|0xfd60|0xfe38|0xff00|0xff18|0xff1c|0xff1d|0xff20|0xff38|0xff39|0xff3a|0xff3b|0xff3c|0xff3d|0xff3e|0xff3f|0xffa8)";
+ match "product" "(0x6001|0x6004|0x6006|0x6006|0x6010|0x6011|0x6014|0x6015|0x8372|0x9378|0x9379|0x937a|0x937c|0x9868|0x9e90|0x9f80|0xa6d0|0xabb8|0xb810|0xb811|0xb812|0xbaf8|0xbbe2|0xbca0|0xbca1|0xbca2|0xbca4|0xbcd8|0xbcd9|0xbcda|0xbdc8|0xbfd8|0xbfd9|0xbfda|0xbfdb|0xbfdc|0xc7d0|0xc850|0xc991|0xcaa0|0xcc48|0xcc49|0xcc4a|0xd010|0xd011|0xd012|0xd013|0xd014|0xd015|0xd016|0xd017|0xd070|0xd071|0xd388|0xd389|0xd38a|0xd38b|0xd38c|0xd38d|0xd38e|0xd38f|0xd578|0xd678|0xd738|0xd780|0xdaf8|0xdaf9|0xdafa|0xdafb|0xdafc|0xdafd|0xdafe|0xdaff|0xdc00|0xdc01|0xdd20|0xdf28|0xdf30|0xdf31|0xdf32|0xdf33|0xdf35|0xe000|0xe001|0xe002|0xe004|0xe006|0xe008|0xe009|0xe00a|0xe050|0xe0e8|0xe0e9|0xe0ea|0xe0eb|0xe0ec|0xe0ed|0xe0ee|0xe0ef|0xe0f0|0xe0f1|0xe0f2|0xe0f3|0xe0f4|0xe0f5|0xe0f6|0xe0f7|0xe40b|0xe520|0xe548|0xe6c8|0xe700|0xe729|0xe808|0xe809|0xe80a|0xe80b|0xe80c|0xe80d|0xe80e|0xe80f|0xe888|0xe889|0xe88a|0xe88b|0xe88c|0xe88d|0xe88e|0xe88f|0xea90|0xebe0|0xec88|0xec89|0xed22|0xed71|0xed72|0xed73|0xed74|0xee18|0xeee8|0xeee9|0xeeea|0xeeeb|0xeeec|0xeeed|0xeeee|0xeeef|0xef50|0xef51|0xf068|0xf069|0xf06a|0xf06b|0xf06c|0xf06d|0xf06e|0xf06f|0xf070|0xf0c0|0xf0c8|0xf208|0xf2d0|0xf3c0|0xf3c1|0xf3c2|0xf448|0xf449|0xf44a|0xf44b|0xf44c|0xf460|0xf608|0xf60b|0xf680|0xf850|0xf857|0xf9d0|0xf9d1|0xf9d2|0xf9d3|0xf9d4|0xf9d5|0xfa00|0xfa01|0xfa02|0xfa03|0xfa04|0xfa05|0xfa06|0xfa10|0xfa33|0xfa88|0xfad0|0xfaf0|0xfb58|0xfb59|0xfb5a|0xfb5b|0xfb5c|0xfb5d|0xfb5e|0xfb5f|0xfb80|0xfb99|0xfbfa|0xfc08|0xfc09|0xfc0a|0xfc0b|0xfc0c|0xfc0d|0xfc0e|0xfc0f|0xfc60|0xfc70|0xfc71|0xfc72|0xfc73|0xfc82|0xfd60|0xfe38|0xff00|0xff18|0xff1c|0xff1d|0xff20|0xff38|0xff39|0xff3a|0xff3b|0xff3c|0xff3d|0xff3e|0xff3f|0xffa8)";
action "kldload -n uftdi";
};
@@ -296,6 +296,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x044e";
+ match "product" "(0x3001|0x3002)";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x0456";
match "product" "(0xf000|0xf001)";
action "kldload -n uftdi";
@@ -385,7 +393,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x0489";
- match "product" "(0xe027|0xe02c|0xe036|0xe03c|0xe03d|0xe04e|0xe056|0xe057)";
+ match "product" "(0xe027|0xe02c|0xe036|0xe03c|0xe03d|0xe042|0xe04e|0xe056|0xe057)";
action "kldload -n ng_ubt";
};
@@ -520,6 +528,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x04bf";
+ match "product" "0x030a";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x04c5";
match "product" "(0x1058|0x1079)";
action "kldload -n uipaq";
@@ -529,7 +545,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x04ca";
- match "product" "(0x3005|0x3006|0x3008)";
+ match "product" "(0x2003|0x3005|0x3006|0x3008)";
action "kldload -n ng_ubt";
};
@@ -1080,6 +1096,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x05ac";
+ match "product" "(0x8213|0x8215|0x8218|0x821a|0x821b|0x821f|0x8281|0x828f)";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x05ad";
match "product" "0x0fba";
action "kldload -n uplcom";
@@ -2048,6 +2072,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x0a5c";
+ match "product" "0x21e1";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x0acd";
match "product" "0x0300";
action "kldload -n uftdi";
@@ -2257,6 +2289,14 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x0b05";
+ match "product" "0x17b5";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
+ match "vendor" "0x0b05";
match "product" "(0x4200|0x4201|0x4202|0x420f|0x9200|0x9202)";
action "kldload -n uipaq";
};
@@ -2448,6 +2488,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x0bdb";
+ match "product" "0x1002";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x0bed";
match "product" "(0x1100|0x1101)";
action "kldload -n uslcom";
@@ -2472,6 +2520,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x0c10";
+ match "product" "0x0000";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x0c26";
match "product" "(0x0004|0x0009|0x000a|0x000b|0x000c|0x000d|0x0010|0x0011|0x0012|0x0013|0x0018)";
action "kldload -n uftdi";
@@ -2888,6 +2944,14 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x0e8d";
+ match "product" "0x763f";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x0ea0";
match "product" "0x6858";
action "kldload -n uplcom";
@@ -4777,6 +4841,14 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x413c";
+ match "product" "0x8197";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
+ match "vendor" "0x413c";
match "product" "0x9500";
action "kldload -n uslcom";
};
@@ -5008,6 +5080,26 @@ nomatch 32 {
nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
+ match "vendor" "0x0489";
+ match "intclass" "0xff";
+ match "intsubclass" "0x01";
+ match "intprotocol" "0x01";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
+ match "vendor" "0x05ac";
+ match "intclass" "0xff";
+ match "intsubclass" "0x01";
+ match "intprotocol" "0x01";
+ action "kldload -n ng_ubt";
+};
+
+nomatch 32 {
+ match "bus" "uhub[0-9]+";
+ match "mode" "host";
match "vendor" "0x05ac";
match "intclass" "0xff";
match "intsubclass" "0xfd";
@@ -5168,5 +5260,5 @@ nomatch 32 {
action "kldload -n umass";
};
-# 2515 USB entries processed
+# 2537 USB entries processed
diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index e295348..dbfbfc9 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -83,6 +83,8 @@
v1
ext
..
+ tr1
+ ..
..
..
cam
diff --git a/etc/mtree/BSD.var.dist b/etc/mtree/BSD.var.dist
index 6a9a7f4..196ee42 100644
--- a/etc/mtree/BSD.var.dist
+++ b/etc/mtree/BSD.var.dist
@@ -23,6 +23,8 @@
remote uname=auditdistd gname=wheel mode=0700
..
..
+ authpf uname=root gname=authpf mode=0770
+ ..
/set gname=wheel
backups
..
diff --git a/etc/rc.d/routing b/etc/rc.d/routing
index 74e5472..284aa7d 100755
--- a/etc/rc.d/routing
+++ b/etc/rc.d/routing
@@ -143,7 +143,7 @@ static_inet()
[Nn][Oo] | '')
;;
*)
- static_routes="_default ${static_routes}"
+ static_routes="${static_routes} _default"
route__default="default ${defaultrouter}"
;;
esac
@@ -205,7 +205,7 @@ static_inet6()
[Nn][Oo] | '')
;;
*)
- ipv6_static_routes="_default ${ipv6_static_routes}"
+ ipv6_static_routes="${ipv6_static_routes} _default"
ipv6_route__default="default ${ipv6_defaultrouter}"
;;
esac
diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile
index cfb9a21..663107c 100644
--- a/gnu/usr.bin/Makefile
+++ b/gnu/usr.bin/Makefile
@@ -12,7 +12,6 @@ SUBDIR= ${_binutils} \
${_gperf} \
grep \
${_groff} \
- patch \
${_rcs} \
sdiff \
send-pr \
diff --git a/gnu/usr.bin/cc/include/Makefile b/gnu/usr.bin/cc/include/Makefile
index 2b04b4c..c48975e 100644
--- a/gnu/usr.bin/cc/include/Makefile
+++ b/gnu/usr.bin/cc/include/Makefile
@@ -6,11 +6,12 @@
INCSDIR=${INCLUDEDIR}/gcc/${GCCVER}
-.PATH: ${GCCDIR}/config/${GCC_CPU}
+.PATH: ${GCCDIR}/config/${GCC_CPU} ${.CURDIR}/../../../../contrib/llvm/tools/clang/lib/Headers
.if ${TARGET_ARCH} == "i386" || ${TARGET_ARCH} == "amd64"
INCS= ammintrin.h emmintrin.h mmintrin.h mm3dnow.h pmmintrin.h \
tmmintrin.h xmmintrin.h mm_malloc.h
+INCS+= wmmintrin.h __wmmintrin_aes.h __wmmintrin_pclmul.h
.elif ${TARGET_ARCH} == "ia64"
INCS= ia64intrin.h
.elif ${TARGET_ARCH} == "arm"
diff --git a/gnu/usr.bin/cc/include/__wmmintrin_aes.h b/gnu/usr.bin/cc/include/__wmmintrin_aes.h
new file mode 100644
index 0000000..ff8a345
--- /dev/null
+++ b/gnu/usr.bin/cc/include/__wmmintrin_aes.h
@@ -0,0 +1,54 @@
+/*-
+ * 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$
+ *
+ */
+
+#ifndef _WMMINTRIN_AES_H_
+#define _WMMINTRIN_AES_H_
+
+#include <emmintrin.h>
+
+#define MAKE_AES(name) \
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) \
+_mm_## name ##_si128(__m128i __V, __m128i __R) \
+{ \
+ __m128i v = __V; \
+ \
+ __asm__ (#name " %2, %0": "=x" (v): "0" (v), "xm" (__R)); \
+ \
+ return v; \
+}
+
+MAKE_AES(aesimc)
+MAKE_AES(aesenc)
+MAKE_AES(aesenclast)
+MAKE_AES(aesdec)
+MAKE_AES(aesdeclast)
+
+#undef MAKE_AES
+
+#endif /* _WMMINTRIN_AES_H_ */
diff --git a/gnu/usr.bin/cc/include/__wmmintrin_pclmul.h b/gnu/usr.bin/cc/include/__wmmintrin_pclmul.h
new file mode 100644
index 0000000..5bebd81
--- /dev/null
+++ b/gnu/usr.bin/cc/include/__wmmintrin_pclmul.h
@@ -0,0 +1,53 @@
+/*-
+ * 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$
+ *
+ */
+
+#ifndef _WMMINTRIN_PCLMUL_H_
+#define _WMMINTRIN_PCLMUL_H_
+
+#include <emmintrin.h>
+
+/*
+ * c selects which parts of a and b to multiple:
+ * 0x00: a[ 63: 0] * b[ 63: 0]
+ * 0x01: a[127:64] * b[ 63: 0]
+ * 0x10: a[ 63: 0] * b[127:64]
+ * 0x11: a[127:64] * b[127:64]
+ */
+#define _mm_clmulepi64_si128(a, b, c) \
+({ \
+ __m128i _a = (a); \
+ __m128i _b = (b); \
+ \
+ __asm__("pclmulqdq %3, %2, %0": "=x" (_a): "0" (_a), "xm" (_b), \
+ "i" (c)); \
+ \
+ _a; \
+})
+
+#endif /* _WMMINTRIN_PCLMUL_H_ */
diff --git a/gnu/usr.bin/patch/EXTERN.h b/gnu/usr.bin/patch/EXTERN.h
deleted file mode 100644
index 374c94f..0000000
--- a/gnu/usr.bin/patch/EXTERN.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: EXTERN.h,v $
- * Revision 2.0 86/09/17 15:35:37 lwall
- * Baseline for netwide release.
- *
- */
-
-#ifdef EXT
-#undef EXT
-#endif
-#define EXT extern
-
-#ifdef INIT
-#undef INIT
-#endif
-#define INIT(x)
-
-#ifdef DOINIT
-#undef DOINIT
-#endif
diff --git a/gnu/usr.bin/patch/INTERN.h b/gnu/usr.bin/patch/INTERN.h
deleted file mode 100644
index c04e722..0000000
--- a/gnu/usr.bin/patch/INTERN.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: INTERN.h,v $
- * Revision 2.0 86/09/17 15:35:58 lwall
- * Baseline for netwide release.
- *
- */
-
-#ifdef EXT
-#undef EXT
-#endif
-#define EXT
-
-#ifdef INIT
-#undef INIT
-#endif
-#define INIT(x) = x
-
-#define DOINIT
diff --git a/gnu/usr.bin/patch/Makefile b/gnu/usr.bin/patch/Makefile
deleted file mode 100644
index 8d8cc7b..0000000
--- a/gnu/usr.bin/patch/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# $FreeBSD$
-
-PROG= gnupatch
-CLEANFILES+= gnupatch.1
-
-gnupatch.1: patch.1
- cp ${.ALLSRC} ${.TARGET}
-
-SRCS= backupfile.c inp.c patch.c pch.c util.c version.c
-CFLAGS+=-DHAVE_CONFIG_H
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/patch/backupfile.c b/gnu/usr.bin/patch/backupfile.c
deleted file mode 100644
index 94a615d..0000000
--- a/gnu/usr.bin/patch/backupfile.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* backupfile.c -- make Emacs style backup file names
- Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.
- Some algorithms adapted from GNU Emacs.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "config.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include "backupfile.h"
-#ifdef STDC_HEADERS
-#include <string.h>
-#include <stdlib.h>
-#else
-char *malloc ();
-#endif
-
-#if defined (HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#if defined(DIRENT) || defined(_POSIX_VERSION)
-#include <dirent.h>
-#define NLENGTH(direct) (strlen((direct)->d_name))
-#else /* not (DIRENT or _POSIX_VERSION) */
-#define dirent direct
-#define NLENGTH(direct) ((direct)->d_namlen)
-#ifdef SYSNDIR
-#include <sys/ndir.h>
-#endif /* SYSNDIR */
-#ifdef SYSDIR
-#include <sys/dir.h>
-#endif /* SYSDIR */
-#ifdef NDIR
-#include <ndir.h>
-#endif /* NDIR */
-#endif /* DIRENT or _POSIX_VERSION */
-
-#ifndef isascii
-#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
-#else
-#define ISDIGIT(c) (isascii (c) && isdigit (c))
-#endif
-
-#if defined (_POSIX_VERSION)
-/* POSIX does not require that the d_ino field be present, and some
- systems do not provide it. */
-#define REAL_DIR_ENTRY(dp) 1
-#else
-#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
-#endif
-
-/* Which type of backup file names are generated. */
-enum backup_type backup_type = none;
-
-/* The extension added to file names to produce a simple (as opposed
- to numbered) backup file name. */
-char *simple_backup_suffix = "~";
-
-int argmatch(char *_arg, const char **_optlist);
-const char *basename(const char *_name);
-char *dirname(const char *_path);
-static char *concat(const char *_str1, const char *_str2);
-char *find_backup_file_name(char *_file);
-static char *make_version_name (char *_file, int _version);
-static int max_backup_version(char *_file, char *_dir);
-static int version_number(char *base, char *backup, int base_length);
-void invalid_arg(const char *_kind, char *_value, int _problem);
-
-/* Return NAME with any leading path stripped off. */
-
-const char *
-basename(const char *name)
-{
- const char *r = name, *p = name;
-
- while (*p)
- if (*p++ == '/')
- r = p;
- return r;
-}
-
-#ifndef NODIR
-/* Return the name of the new backup file for file FILE,
- allocated with malloc. Return 0 if out of memory.
- FILE must not end with a '/' unless it is the root directory.
- Do not call this function if backup_type == none. */
-
-char *
-find_backup_file_name(char *file)
-{
- char *dir;
- char *base_versions;
- int highest_backup;
-
- if (backup_type == simple)
- {
- char *s = malloc (strlen (file) + strlen (simple_backup_suffix) + 1);
- strcpy (s, file);
- addext (s, simple_backup_suffix, '~');
- return s;
- }
- base_versions = concat (basename (file), ".~");
- if (base_versions == 0)
- return 0;
- dir = dirname (file);
- if (dir == 0)
- {
- free (base_versions);
- return 0;
- }
- highest_backup = max_backup_version (base_versions, dir);
- free (base_versions);
- free (dir);
- if (backup_type == numbered_existing && highest_backup == 0)
- return concat (file, simple_backup_suffix);
- return make_version_name (file, highest_backup + 1);
-}
-
-/* Return the number of the highest-numbered backup file for file
- FILE in directory DIR. If there are no numbered backups
- of FILE in DIR, or an error occurs reading DIR, return 0.
- FILE should already have ".~" appended to it. */
-
-static int
-max_backup_version(char *file, char *dir)
-{
- DIR *dirp;
- struct dirent *dp;
- int highest_version;
- int this_version;
- int file_name_length;
-
- dirp = opendir (dir);
- if (!dirp)
- return 0;
-
- highest_version = 0;
- file_name_length = strlen (file);
-
- while ((dp = readdir (dirp)) != 0)
- {
- if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
- continue;
-
- this_version = version_number (file, dp->d_name, file_name_length);
- if (this_version > highest_version)
- highest_version = this_version;
- }
- closedir (dirp);
- return highest_version;
-}
-
-/* Return a string, allocated with malloc, containing
- "FILE.~VERSION~". Return 0 if out of memory. */
-
-static char *
-make_version_name(char *file, int version)
-{
- char *backup_name;
-
- backup_name = malloc (strlen (file) + 16);
- if (backup_name == 0)
- return 0;
- sprintf (backup_name, "%s.~%d~", file, version);
- return backup_name;
-}
-
-/* If BACKUP is a numbered backup of BASE, return its version number;
- otherwise return 0. BASE_LENGTH is the length of BASE.
- BASE should already have ".~" appended to it. */
-
-static int
-version_number(char *base, char *backup, int base_length)
-{
- int version;
- char *p;
-
- version = 0;
- if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
- {
- for (p = &backup[base_length]; ISDIGIT (*p); ++p)
- version = version * 10 + *p - '0';
- if (p[0] != '~' || p[1])
- version = 0;
- }
- return version;
-}
-
-/* Return the newly-allocated concatenation of STR1 and STR2.
- If out of memory, return 0. */
-
-static char *
-concat(const char *str1, const char *str2)
-{
- char *newstr;
- int str1_length = strlen (str1);
-
- newstr = malloc (str1_length + strlen (str2) + 1);
- if (newstr == 0)
- return 0;
- strcpy (newstr, str1);
- strcpy (newstr + str1_length, str2);
- return newstr;
-}
-
-/* Return the leading directories part of PATH,
- allocated with malloc. If out of memory, return 0.
- Assumes that trailing slashes have already been
- removed. */
-
-char *
-dirname(const char *path)
-{
- char *newpath;
- const char *slash;
- int length; /* Length of result, not including NUL. */
-
- slash = basename (path);
- if (slash == path)
- {
- /* File is in the current directory. */
- path = ".";
- length = 1;
- }
- else
- {
- /* Remove any trailing slashes from result. */
- while (*--slash == '/' && slash > path)
- ;
-
- length = slash - path + 1;
- }
- newpath = malloc (length + 1);
- if (newpath == 0)
- return 0;
- strncpy (newpath, path, length);
- newpath[length] = 0;
- return newpath;
-}
-
-/* If ARG is an unambiguous match for an element of the
- null-terminated array OPTLIST, return the index in OPTLIST
- of the matched element, else -1 if it does not match any element
- or -2 if it is ambiguous (is a prefix of more than one element). */
-
-int
-argmatch(char *arg, const char **optlist)
-{
- int i; /* Temporary index in OPTLIST. */
- int arglen; /* Length of ARG. */
- int matchind = -1; /* Index of first nonexact match. */
- int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
-
- arglen = strlen (arg);
-
- /* Test all elements for either exact match or abbreviated matches. */
- for (i = 0; optlist[i]; i++)
- {
- if (!strncmp (optlist[i], arg, arglen))
- {
- if (strlen (optlist[i]) == arglen)
- /* Exact match found. */
- return i;
- else if (matchind == -1)
- /* First nonexact match found. */
- matchind = i;
- else
- /* Second nonexact match found. */
- ambiguous = 1;
- }
- }
- if (ambiguous)
- return -2;
- else
- return matchind;
-}
-
-/* Error reporting for argmatch.
- KIND is a description of the type of entity that was being matched.
- VALUE is the invalid value that was given.
- PROBLEM is the return value from argmatch. */
-
-void
-invalid_arg(const char *kind, char *value, int problem)
-{
- fprintf (stderr, "patch: ");
- if (problem == -1)
- fprintf (stderr, "invalid");
- else /* Assume -2. */
- fprintf (stderr, "ambiguous");
- fprintf (stderr, " %s `%s'\n", kind, value);
-}
-
-static const char *backup_args[] =
-{
- "never", "simple", "nil", "existing", "t", "numbered", 0
-};
-
-static enum backup_type backup_types[] =
-{
- simple, simple, numbered_existing, numbered_existing, numbered, numbered
-};
-
-/* Return the type of backup indicated by VERSION.
- Unique abbreviations are accepted. */
-
-enum backup_type
-get_version(char *version)
-{
- int i;
-
- if (version == 0 || *version == 0)
- return numbered_existing;
- i = argmatch (version, backup_args);
- if (i >= 0)
- return backup_types[i];
- invalid_arg ("version control type", version, i);
- exit (1);
-}
-#endif /* NODIR */
-
-/* Append to FILENAME the extension EXT, unless the result would be too long,
- in which case just append the character E. */
-
-void
-addext(char *filename, char *ext, int e)
-{
- char *s = (char *)(uintptr_t)(const void *)basename (filename);
- int slen = strlen (s), extlen = strlen (ext);
- long slen_max = -1;
-
-#if HAVE_PATHCONF && defined (_PC_NAME_MAX)
-#ifndef _POSIX_NAME_MAX
-#define _POSIX_NAME_MAX 14
-#endif
- if (slen + extlen <= _POSIX_NAME_MAX)
- /* The file name is so short there's no need to call pathconf. */
- slen_max = _POSIX_NAME_MAX;
- else if (s == filename)
- slen_max = pathconf (".", _PC_NAME_MAX);
- else
- {
- char c = *s;
- *s = 0;
- slen_max = pathconf (filename, _PC_NAME_MAX);
- *s = c;
- }
-#endif
- if (slen_max == -1) {
-#ifdef HAVE_LONG_FILE_NAMES
- slen_max = 255;
-#else
- slen_max = 14;
-#endif
- }
- if (slen + extlen <= slen_max)
- strcpy (s + slen, ext);
- else
- {
- if (slen_max <= slen) {
- /* Try to preserve difference between .h .c etc. */
- if (slen == slen_max && s[slen - 2] == '.')
- s[slen - 2] = s[slen - 1];
-
- slen = slen_max - 1;
- }
- s[slen] = e;
- s[slen + 1] = 0;
- }
-}
diff --git a/gnu/usr.bin/patch/backupfile.h b/gnu/usr.bin/patch/backupfile.h
deleted file mode 100644
index 7600714..0000000
--- a/gnu/usr.bin/patch/backupfile.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* backupfile.h -- declarations for making Emacs style backup file names
- Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/*
- * $FreeBSD$
- */
-
-/* When to make backup files. */
-enum backup_type
-{
- /* Never make backups. */
- none,
-
- /* Make simple backups of every file. */
- simple,
-
- /* Make numbered backups of files that already have numbered backups,
- and simple backups of the others. */
- numbered_existing,
-
- /* Make numbered backups of every file. */
- numbered
-};
-
-extern enum backup_type backup_type;
-extern char *simple_backup_suffix;
-
-char *find_backup_file_name (char *_file);
-enum backup_type get_version(char *_version);
-void addext(char *_filename, char *_ext, int _e);
diff --git a/gnu/usr.bin/patch/common.h b/gnu/usr.bin/patch/common.h
deleted file mode 100644
index aa19105..0000000
--- a/gnu/usr.bin/patch/common.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: common.h,v $
- * Revision 2.0.1.2 88/06/22 20:44:53 lwall
- * patch12: sprintf was declared wrong
- *
- * Revision 2.0.1.1 88/06/03 15:01:56 lwall
- * patch10: support for shorter extensions.
- *
- * Revision 2.0 86/09/17 15:36:39 lwall
- * Baseline for netwide release.
- *
- */
-
-#define DEBUGGING
-
-#define VOIDUSED 7
-#include "config.h"
-
-/* shut lint up about the following when return value ignored */
-
-#define Signal (void)signal
-#define Unlink (void)unlink
-#define Lseek (void)lseek
-#define Fseek (void)fseek
-#define Fstat (void)fstat
-#define Pclose (void)pclose
-#define Close (void)close
-#define Fclose (void)fclose
-#define Fflush (void)fflush
-#define Sprintf (void)sprintf
-#define Snprintf (void)snprintf
-#define Mktemp (void)mktemp
-#define Strcpy (void)strcpy
-#define Strcat (void)strcat
-#define Strlcpy (void)strlcpy
-#define Strncpy (void)strncpy
-#define Strlcat (void)strlcat
-
-/* NeXT declares malloc and realloc incompatibly from us in some of
- these files. Temporarily redefine them to prevent errors. */
-#define malloc system_malloc
-#define realloc system_realloc
-#include <stdio.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <signal.h>
-#undef malloc
-#undef realloc
-
-/* constants */
-
-/* AIX predefines these. */
-#ifdef TRUE
-#undef TRUE
-#endif
-#ifdef FALSE
-#undef FALSE
-#endif
-#define TRUE (1)
-#define FALSE (0)
-
-#define MAXHUNKSIZE 200000 /* is this enough lines? */
-#define INITHUNKMAX 125 /* initial dynamic allocation size */
-#define INITLINELEN 4096
-#define BUFFERSIZE 4096
-
-#define SCCSPREFIX "s."
-#define GET "get %s"
-#define GET_LOCKED "get -e %s"
-#define SCCSDIFF "get -p %s | diff - %s >/dev/null"
-
-#define RCSSUFFIX ",v"
-#define CHECKOUT "co %s"
-#define CHECKOUT_LOCKED "co -l %s"
-#define RCSDIFF "rcsdiff %s > /dev/null"
-
-/* handy definitions */
-
-#define Null(t) ((t)0)
-#define Nullch Null(char *)
-#define Nullfp Null(FILE *)
-#define Nulline Null(LINENUM)
-
-#define Ctl(ch) ((ch) & 037)
-
-#define strNE(s1,s2) (strcmp(s1, s2))
-#define strEQ(s1,s2) (!strcmp(s1, s2))
-#define strnNE(s1,s2,l) (strncmp(s1, s2, l))
-#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l))
-
-/* typedefs */
-
-typedef char bool;
-typedef long LINENUM; /* must be signed */
-typedef unsigned MEM; /* what to feed malloc */
-
-/* globals */
-
-EXT int Argc; /* guess */
-EXT char **Argv;
-EXT int optind_last; /* for restarting plan_b */
-
-EXT struct stat filestat; /* file statistics area */
-EXT int filemode INIT(0644);
-
-EXT char *buf; /* general purpose buffer */
-EXT size_t buf_size; /* size of the general purpose buffer */
-EXT FILE *ofp INIT(Nullfp); /* output file pointer */
-EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */
-
-EXT int myuid; /* cache getuid return value */
-
-EXT bool using_plan_a INIT(TRUE); /* try to keep everything in memory */
-EXT bool out_of_mem INIT(FALSE); /* ran out of memory in plan a */
-
-#define MAXFILEC 2
-EXT int filec INIT(0); /* how many file arguments? */
-EXT char *filearg[MAXFILEC];
-EXT bool ok_to_create_file INIT(FALSE);
-EXT char *bestguess INIT(Nullch); /* guess at correct filename */
-
-EXT char *outname INIT(Nullch);
-EXT char rejname[128];
-
-EXT char *origprae INIT(Nullch);
-
-EXT char *TMPOUTNAME;
-EXT char *TMPINNAME;
-EXT char *TMPREJNAME;
-EXT char *TMPPATNAME;
-EXT bool toutkeep INIT(FALSE);
-EXT bool trejkeep INIT(FALSE);
-
-EXT LINENUM last_offset INIT(0);
-#ifdef DEBUGGING
-EXT int debug INIT(0);
-#endif
-EXT LINENUM maxfuzz INIT(2);
-EXT bool force INIT(FALSE);
-EXT bool batch INIT(FALSE);
-EXT bool verbose INIT(TRUE);
-EXT bool reverse INIT(FALSE);
-EXT bool noreverse INIT(FALSE);
-EXT bool skip_rest_of_patch INIT(FALSE);
-EXT int strippath INIT(957);
-EXT bool canonicalize INIT(FALSE);
-
-#define CONTEXT_DIFF 1
-#define NORMAL_DIFF 2
-#define ED_DIFF 3
-#define NEW_CONTEXT_DIFF 4
-#define UNI_DIFF 5
-EXT int diff_type INIT(0);
-
-EXT bool do_defines INIT(FALSE); /* patch using ifdef, ifndef, etc. */
-EXT char if_defined[128]; /* #ifdef xyzzy */
-EXT char not_defined[128]; /* #ifndef xyzzy */
-EXT char else_defined[] INIT("#else\n");/* #else */
-EXT char end_defined[128]; /* #endif xyzzy */
-
-EXT char *revision INIT(Nullch); /* prerequisite revision, if any */
-
-#include <errno.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#include <string.h>
-#else
-extern int errno;
-FILE *popen();
-char *malloc();
-char *realloc();
-long atol();
-char *getenv();
-char *strcpy();
-char *strcat();
-#endif
-char *mktemp(char *);
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#else
-long lseek();
-#endif
-#if defined(_POSIX_VERSION) || defined(HAVE_FCNTL_H)
-#include <fcntl.h>
-#endif
-
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG) && defined(S_IFREG)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
diff --git a/gnu/usr.bin/patch/config.h b/gnu/usr.bin/patch/config.h
deleted file mode 100644
index 177a8c5..0000000
--- a/gnu/usr.bin/patch/config.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* config.h. Generated automatically by configure. */
-/* Portability variables. -*- C -*- */
-
-/* Define if the system does not support the `const' keyword. */
-/* #undef const */
-
-/* Define if the system supports file names longer than 14 characters. */
-#define HAVE_LONG_FILE_NAMES
-
-/* Define if the system has pathconf(). */
-/* #undef HAVE_PATHCONF */
-
-/* Define if the system has strerror(). */
-#define HAVE_STRERROR 1
-
-/* Define if the system has ANSI C header files and library functions. */
-#define STDC_HEADERS
-
-/* Define if the system uses strchr instead of index
- and strrchr instead of rindex. */
-#define HAVE_STRING_H 1
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#define index strchr
-#define rindex strrchr
-#endif
-
-/* Define if the system has unistd.h. */
-#define HAVE_UNISTD_H 1
-
-/* Define if the system has fcntl.h. */
-#define HAVE_FCNTL_H 1
-
-/* Define as either int or void -- the type that signal handlers return. */
-#define RETSIGTYPE void
-
-#ifndef RETSIGTYPE
-#define RETSIGTYPE void
-#endif
-
-/* Which directory library header to use. */
-#define DIRENT 1 /* dirent.h */
-/* #undef SYSNDIR */ /* sys/ndir.h */
-/* #undef SYSDIR */ /* sys/dir.h */
-/* #undef NDIR */ /* ndir.h */
-/* #undef NODIR */ /* none -- don't make numbered backup files */
-
-/* Define if the system lets you pass fewer arguments to a function
- than the function actually accepts (in the absence of a prototype).
- Defining it makes I/O calls slightly more efficient.
- You need not bother defining it unless your C preprocessor chokes on
- multi-line arguments to macros. */
-/* #undef CANVARARG */
-
-/* Define Reg* as either `register' or nothing, depending on whether
- the C compiler pays attention to this many register declarations.
- The intent is that you don't have to order your register declarations
- in the order of importance, so you can freely declare register variables
- in sub-blocks of code and as function parameters.
- Do not use Reg<n> more than once per routine.
-
- These don't really matter a lot, since most modern C compilers ignore
- register declarations and often do a better job of allocating
- registers than people do. */
-
-#define Reg1 register
-#define Reg2 register
-#define Reg3 register
-#define Reg4 register
-#define Reg5 register
-#define Reg6 register
-#define Reg7
-#define Reg8
-#define Reg9
-#define Reg10
-#define Reg11
-#define Reg12
-#define Reg13
-#define Reg14
-#define Reg15
-#define Reg16
diff --git a/gnu/usr.bin/patch/inp.c b/gnu/usr.bin/patch/inp.c
deleted file mode 100644
index 17f8adb..0000000
--- a/gnu/usr.bin/patch/inp.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: inp.c,v $
- * Revision 2.0.1.1 88/06/03 15:06:13 lwall
- * patch10: made a little smarter about sccs files
- *
- * Revision 2.0 86/09/17 15:37:02 lwall
- * Baseline for netwide release.
- *
- */
-
-#include "EXTERN.h"
-#include "common.h"
-#include "util.h"
-#include "pch.h"
-#include "INTERN.h"
-#include "inp.h"
-
-/* Input-file-with-indexable-lines abstract type. */
-
-static long i_size; /* Size of the input file */
-static char *i_womp; /* Plan a buffer for entire file */
-static char **i_ptr; /* Pointers to lines in i_womp */
-
-static int tifd = -1; /* Plan b virtual string array */
-static char *tibuf[2]; /* Plan b buffers */
-static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */
-static LINENUM lines_per_buf; /* How many lines per buffer */
-static int tireclen; /* Length of records in tmp file */
-
-/*
- * New patch--prepare to edit another file.
- */
-void
-re_input(void)
-{
- if (using_plan_a) {
- i_size = 0;
-#ifndef lint
- if (i_ptr != Null(char**))
- free((char *)i_ptr);
-#endif
- if (i_womp != Nullch)
- free(i_womp);
- i_womp = Nullch;
- i_ptr = Null(char **);
- } else {
- using_plan_a = TRUE; /* maybe the next one is smaller */
- Close(tifd);
- tifd = -1;
- free(tibuf[0]);
- free(tibuf[1]);
- tibuf[0] = tibuf[1] = Nullch;
- tiline[0] = tiline[1] = -1;
- tireclen = 0;
- }
-}
-
-/*
- * Constuct the line index, somehow or other.
- */
-void
-scan_input(char *filename)
-{
- if (!plan_a(filename))
- plan_b(filename);
- if (verbose) {
- say3("Patching file %s using Plan %s...\n", filename,
- (using_plan_a ? "A" : "B") );
- }
-}
-
-/*
- * Try keeping everything in memory.
- */
-bool
-plan_a(char *filename)
-{
- int ifd, statfailed;
- Reg1 char *s;
- Reg2 LINENUM iline;
- char lbuf[INITLINELEN];
- int output_elsewhere = strcmp(filename, outname);
- extern int check_patch;
-
- statfailed = stat(filename, &filestat);
- if (statfailed && ok_to_create_file) {
- if (verbose)
- say2("(Creating file %s...)\n",filename);
- if (check_patch)
- return TRUE;
- makedirs(filename, TRUE);
- close(creat(filename, 0666));
- statfailed = stat(filename, &filestat);
- }
- if (statfailed && check_patch) {
- fatal2("%s not found and in check_patch mode.", filename);
- }
- /*
- * For nonexistent or read-only files, look for RCS or SCCS
- * versions.
- */
- if (statfailed ||
- (! output_elsewhere &&
- (/* No one can write to it. */
- (filestat.st_mode & 0222) == 0 ||
- /* I can't write to it. */
- ((filestat.st_mode & 0022) == 0 && filestat.st_uid != myuid)))) {
- struct stat cstat;
- char *cs = Nullch;
- char *filebase;
- int pathlen;
-
- filebase = basename(filename);
- pathlen = filebase - filename;
-
- /*
- * Put any leading path into `s'.
- * Leave room in lbuf for the diff command.
- */
- s = lbuf + 20;
- strncpy(s, filename, pathlen);
-
-#define try(f,a1,a2) (Sprintf(s + pathlen, f, a1, a2), stat(s, &cstat) == 0)
- if ((try("RCS/%s%s", filebase, RCSSUFFIX) ||
- try("RCS/%s%s", filebase, "") ||
- try("%s%s", filebase, RCSSUFFIX)) &&
- /*
- * Check that RCS file is not working file.
- * Some hosts don't report file name length errors.
- */
- (statfailed ||
- ((filestat.st_dev ^ cstat.st_dev) |
- (filestat.st_ino ^ cstat.st_ino)))) {
- Sprintf(buf, output_elsewhere?CHECKOUT:CHECKOUT_LOCKED, filename);
- Sprintf(lbuf, RCSDIFF, filename);
- cs = "RCS";
- } else if (try("SCCS/%s%s", SCCSPREFIX, filebase) ||
- try("%s%s", SCCSPREFIX, filebase)) {
- Sprintf(buf, output_elsewhere?GET:GET_LOCKED, s);
- Sprintf(lbuf, SCCSDIFF, s, filename);
- cs = "SCCS";
- } else if (statfailed)
- fatal2("can't find %s\n", filename);
- /*
- * else we can't write to it but it's not under a version
- * control system, so just proceed.
- */
- if (cs) {
- if (!statfailed) {
- if ((filestat.st_mode & 0222) != 0)
- /* The owner can write to it. */
- fatal3(
-"file %s seems to be locked by somebody else under %s\n",
- filename, cs);
- /*
- * It might be checked out unlocked. See if
- * it's safe to check out the default version
- * locked.
- */
- if (verbose)
- say3(
-"Comparing file %s to default %s version...\n",
- filename, cs);
- if (system(lbuf))
- fatal3(
-"can't check out file %s: differs from default %s version\n",
- filename, cs);
- }
- if (verbose)
- say3("Checking out file %s from %s...\n", filename, cs);
- if (system(buf) || stat(filename, &filestat))
- fatal3("can't check out file %s from %s\n",
- filename, cs);
- }
- }
- filemode = filestat.st_mode;
- if (!S_ISREG(filemode))
- fatal2("%s is not a normal file--can't patch\n", filename);
- i_size = filestat.st_size;
- if (out_of_mem) {
- set_hunkmax(); /* make sure dynamic arrays are allocated */
- out_of_mem = FALSE;
- return FALSE; /* force plan b because plan a bombed */
- }
-#ifdef lint
- i_womp = Nullch;
-#else
- /*
- * Lint says this may alloc less than i_size,
- * but that's okay, I think.
- */
- i_womp = malloc((MEM)(i_size + 2));
-#endif
- if (i_womp == Nullch)
- return FALSE;
- if ((ifd = open(filename, 0)) < 0)
- pfatal2("can't open file %s", filename);
-#ifndef lint
- if (read(ifd, i_womp, (int)i_size) != i_size) {
- /*
- * This probably means i_size > 15 or 16 bits worth. At
- * this point it doesn't matter if i_womp was undersized.
- */
- Close(ifd);
- free(i_womp);
- return FALSE;
- }
-#endif
- Close(ifd);
- if (i_size && i_womp[i_size - 1] != '\n')
- i_womp[i_size++] = '\n';
- i_womp[i_size] = '\0';
-
- /*
- * Count the lines in the buffer so we know how many pointers we
- * need.
- */
- iline = 0;
- for (s = i_womp; *s; s++) {
- if (*s == '\n')
- iline++;
- }
-#ifdef lint
- i_ptr = Null(char**);
-#else
- i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
-#endif
- if (i_ptr == Null(char **)) { /* shucks, it was a near thing */
- free((char *)i_womp);
- return FALSE;
- }
-
- /* Now scan the buffer and build pointer array. */
- iline = 1;
- i_ptr[iline] = i_womp;
- for (s = i_womp; *s; s++) {
- if (*s == '\n') {
- /* These are NOT null terminated. */
- i_ptr[++iline] = s + 1;
- }
- }
- input_lines = iline - 1;
-
- /* Now check for revision, if any. */
- if (revision != Nullch) {
- if (!rev_in_string(i_womp)) {
- if (force) {
- if (verbose)
- say2(
-"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
- revision);
- } else if (batch) {
- fatal2(
-"this file doesn't appear to be the %s version--aborting.\n", revision);
- } else {
- (void) ask2(
-"This file doesn't appear to be the %s version--patch anyway? [n] ",
- revision);
- if (*buf != 'y')
- fatal1("aborted\n");
- }
- } else if (verbose)
- say2("Good. This file appears to be the %s version.\n",
- revision);
- }
-
- return TRUE; /* Plan a will work. */
-}
-
-/*
- * Keep (virtually) nothing in memory.
- */
-void
-plan_b(char *filename)
-{
- Reg3 FILE *ifp;
- Reg1 int i = 0;
- Reg2 int maxlen = 1;
- Reg4 bool found_revision = (revision == Nullch);
-
- using_plan_a = FALSE;
- if ((ifp = fopen(filename, "r")) == Nullfp)
- pfatal2("can't open file %s", filename);
- if ((tifd = creat(TMPINNAME, 0666)) < 0)
- pfatal2("can't open file %s", TMPINNAME);
- while (fgets(buf, buf_size, ifp) != Nullch) {
- if (revision != Nullch && !found_revision && rev_in_string(buf))
- found_revision = TRUE;
- if ((i = strlen(buf)) > maxlen)
- maxlen = i; /* Find longest line. */
- }
- if (revision != Nullch) {
- if (!found_revision) {
- if (force) {
- if (verbose)
- say2(
-"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
- revision);
- } else if (batch) {
- fatal2(
-"this file doesn't appear to be the %s version--aborting.\n", revision);
- } else {
- (void) ask2(
-"This file doesn't appear to be the %s version--patch anyway? [n] ",
- revision);
- if (*buf != 'y')
- fatal1("aborted\n");
- }
- } else if (verbose)
- say2("Good. This file appears to be the %s version.\n",
- revision);
- }
- Fseek(ifp, 0L, 0); /* Rewind file. */
- lines_per_buf = BUFFERSIZE / maxlen;
- tireclen = maxlen;
- tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
- tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
- if (tibuf[1] == Nullch)
- fatal1("out of memory\n");
- for (i = 1; ; i++) {
- if (! (i % lines_per_buf)) /* New block. */
- if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
- pfatal1("can't write temp file");
- if (fgets(tibuf[0] + maxlen * (i%lines_per_buf),
- maxlen + 1, ifp) == Nullch) {
- input_lines = i - 1;
- if (i % lines_per_buf)
- if (write(tifd, tibuf[0], BUFFERSIZE) <
- BUFFERSIZE)
- pfatal1("can't write temp file");
- break;
- }
- }
- Fclose(ifp);
- Close(tifd);
- if ((tifd = open(TMPINNAME, 0)) < 0) {
- pfatal2("can't reopen file %s", TMPINNAME);
- }
-}
-
-/*
- * Fetch a line from the input file, \n terminated, not necessarily \0.
- */
-char *
-ifetch(line,whichbuf)
-Reg1 LINENUM line;
-int whichbuf; /* ignored when file in memory */
-{
- if (line < 1 || line > input_lines)
- return "";
- if (using_plan_a)
- return i_ptr[line];
- else {
- LINENUM offline = line % lines_per_buf;
- LINENUM baseline = line - offline;
-
- if (tiline[0] == baseline)
- whichbuf = 0;
- else if (tiline[1] == baseline)
- whichbuf = 1;
- else {
- tiline[whichbuf] = baseline;
-#ifndef lint /* complains of long accuracy */
- Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
-#endif
- if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
- pfatal2("error reading tmp file %s", TMPINNAME);
- }
- return tibuf[whichbuf] + (tireclen * offline);
- }
-}
-
-/*
- * True if the string argument contains the revision number we want.
- */
-bool
-rev_in_string(char *string)
-{
- Reg1 char *s;
- Reg2 int patlen;
-
- if (revision == Nullch)
- return TRUE;
- patlen = strlen(revision);
- if (strnEQ(string,revision,patlen) &&
- isspace((unsigned char)string[patlen]))
- return TRUE;
- for (s = string; *s; s++) {
- if (isspace((unsigned char)*s) &&
- strnEQ(s + 1, revision, patlen) &&
- isspace((unsigned char)s[patlen + 1] )) {
- return TRUE;
- }
- }
- return FALSE;
-}
diff --git a/gnu/usr.bin/patch/inp.h b/gnu/usr.bin/patch/inp.h
deleted file mode 100644
index f1f0386..0000000
--- a/gnu/usr.bin/patch/inp.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: inp.h,v $
- * Revision 2.0 86/09/17 15:37:25 lwall
- * Baseline for netwide release.
- *
- */
-
-EXT LINENUM input_lines INIT(0); /* how long is input file in lines */
-EXT LINENUM last_frozen_line INIT(0); /* how many input lines have been */
- /* irretractibly output */
-void re_input(void);
-void scan_input(char *_filename);
-bool plan_a(char *_filename);
-void plan_b(char *_filename);
-bool rev_in_string(char *_string);
-char *ifetch(LINENUM _line, int _whichbuf);
-
diff --git a/gnu/usr.bin/patch/patch.1 b/gnu/usr.bin/patch/patch.1
deleted file mode 100644
index 3cc7957..0000000
--- a/gnu/usr.bin/patch/patch.1
+++ /dev/null
@@ -1,594 +0,0 @@
-.\" -*- nroff -*-
-.rn '' }`
-'\" $Header: patch.man,v 2.0.1.2 88/06/22 20:47:18 lwall Locked $
-'\" $FreeBSD$
-'\"
-'\" $Log: patch.man,v $
-'\" Revision 2.0.1.2 88/06/22 20:47:18 lwall
-'\" patch12: now avoids Bell System Logo
-'\"
-'\" Revision 2.0.1.1 88/06/03 15:12:51 lwall
-'\" patch10: -B switch was contributed.
-'\"
-'\" Revision 2.0 86/09/17 15:39:09 lwall
-'\" Baseline for netwide release.
-'\"
-'\" Revision 1.4 86/08/01 19:23:22 lwall
-'\" Documented -v, -p, -F.
-'\" Added notes to patch senders.
-'\"
-'\" Revision 1.3 85/03/26 15:11:06 lwall
-'\" Frozen.
-'\"
-'\" Revision 1.2.1.4 85/03/12 16:14:27 lwall
-'\" Documented -p.
-'\"
-'\" Revision 1.2.1.3 85/03/12 16:09:41 lwall
-'\" Documented -D.
-'\"
-'\" Revision 1.2.1.2 84/12/05 11:06:55 lwall
-'\" Added -l switch, and noted bistability bug.
-'\"
-'\" Revision 1.2.1.1 84/12/04 17:23:39 lwall
-'\" Branch for sdcrdcf changes.
-'\"
-'\" Revision 1.2 84/12/04 17:22:02 lwall
-'\" Baseline version.
-'\"
-.de Sh
-.br
-.ne 5
-.PP
-\fB\\$1\fR
-.PP
-..
-.de Sp
-.if t .sp .5v
-.if n .sp
-..
-'\"
-'\" Set up \*(-- to give an unbreakable dash;
-'\" string Tr holds user defined translation string.
-'\" Bell System Logo is used as a dummy character.
-'\"
-.if !d Tr .ds Tr
-.ie n \{\
-.tr \(*W-\*(Tr
-.ds -- \(*W-
-.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-.ds L" ""
-.ds R" ""
-.ds L' '
-.ds R' '
-'br \}
-.el \{\
-.ds -- \(em\|
-.tr \*(Tr
-.ds L" ``
-.ds R" ''
-.ds L' `
-.ds R' '
-'br\}
-.TH PATCH 1 LOCAL
-.SH NAME
-patch - apply a diff file to an original
-.SH SYNOPSIS
-.B patch
-[options] [origfile [patchfile]] [+ [options] [origfile]]...
-.sp
-but usually just
-.sp
-.B patch
-<patchfile
-.SH DESCRIPTION
-.I Patch
-will take a patch file containing any of the four forms of difference
-listing produced by the
-.I diff
-program and apply those differences to an original file, producing a patched
-version.
-By default, the patched version is put in place of the original, with
-the original file backed up to the same name with the
-extension \*(L".orig\*(R" (\*(L"~\*(R" on systems that do not
-support long file names), or as specified by the
-\fB\-b\fP (\fB\-\-suffix\fP),
-\fB\-B\fP (\fB\-\-prefix\fP),
-or
-\fB\-V\fP (\fB\-\-version\-control\fP)
-options.
-The extension used for making backup files may also be specified in the
-.B SIMPLE_BACKUP_SUFFIX
-environment variable, which is overridden by the above options.
-.PP
-If the backup file already exists,
-.B patch
-creates a new backup file name by changing the first lowercase letter
-in the last component of the file's name into uppercase. If there are
-no more lowercase letters in the name, it removes the first character
-from the name. It repeats this process until it comes up with a
-backup file that does not already exist.
-.PP
-You may also specify where you want the output to go with a
-\fB\-o\fP (\fB\-\-output\fP)
-option; if that file already exists, it is backed up first.
-.PP
-If
-.I patchfile
-is omitted, or is a hyphen, the patch will be read from standard input.
-If a
-\fB\-i\fP
-argument is specified, the filename following it will be used, instead of
-standard input. You may specify only one
-\fB\-i\fP
-directive.
-.PP
-Upon startup, patch will attempt to determine the type of the diff listing,
-unless over-ruled by a
-\fB\-c\fP (\fB\-\-context\fP),
-\fB\-e\fP (\fB\-\-ed\fP),
-\fB\-n\fP (\fB\-\-normal\fP),
-or
-\fB\-u\fP (\fB\-\-unified\fP)
-option.
-Context diffs (old-style, new-style, and unified) and
-normal diffs are applied by the
-.I patch
-program itself, while
-.I ed
-diffs are simply fed to the
-.I ed
-editor via a pipe.
-.PP
-.I Patch
-will try to skip any leading garbage, apply the diff,
-and then skip any trailing garbage.
-Thus you could feed an article or message containing a
-diff listing to
-.IR patch ,
-and it should work.
-If the entire diff is indented by a consistent amount,
-this will be taken into account.
-.PP
-With context diffs, and to a lesser extent with normal diffs,
-.I patch
-can detect when the line numbers mentioned in the patch are incorrect,
-and will attempt to find the correct place to apply each hunk of the patch.
-As a first guess, it takes the line number mentioned for the hunk, plus or
-minus any offset used in applying the previous hunk.
-If that is not the correct place,
-.I patch
-will scan both forwards and backwards for a set of lines matching the context
-given in the hunk.
-First
-.I patch
-looks for a place where all lines of the context match.
-If no such place is found, and it's a context diff, and the maximum fuzz factor
-is set to 1 or more, then another scan takes place ignoring the first and last
-line of context.
-If that fails, and the maximum fuzz factor is set to 2 or more,
-the first two and last two lines of context are ignored,
-and another scan is made.
-(The default maximum fuzz factor is 2.)
-If
-.I patch
-cannot find a place to install that hunk of the patch, it will put the
-hunk out to a reject file, which normally is the name of the output file
-plus \*(L".rej\*(R" (\*(L"#\*(R" on systems that do not support
-long file names).
-(Note that the rejected hunk will come out in context diff form whether the
-input patch was a context diff or a normal diff.
-If the input was a normal diff, many of the contexts will simply be null.)
-The line numbers on the hunks in the reject file may be different than
-in the patch file: they reflect the approximate location patch thinks the
-failed hunks belong in the new file rather than the old one.
-.PP
-As each hunk is completed, you will be told whether the hunk succeeded or
-failed, and which line (in the new file)
-.I patch
-thought the hunk should go on.
-If this is different from the line number specified in the diff you will
-be told the offset.
-A single large offset MAY be an indication that a hunk was installed in the
-wrong place.
-You will also be told if a fuzz factor was used to make the match, in which
-case you should also be slightly suspicious.
-.PP
-If no original file is specified on the command line,
-.I patch
-will try to figure out from the leading garbage what the name of the file
-to edit is.
-In the header of a context diff, the file name is found from lines beginning
-with \*(L"***\*(R" or \*(L"---\*(R", with the shortest name of an existing
-file winning.
-Only context diffs have lines like that, but if there is an \*(L"Index:\*(R"
-line in the leading garbage,
-.I patch
-will try to use the file name from that line.
-The context diff header takes precedence over an Index line.
-If no file name can be intuited from the leading garbage, you will be asked
-for the name of the file to patch.
-.PP
-If the original file cannot be found or is read-only, but a suitable
-SCCS or RCS file is handy,
-.I patch
-will attempt to get or check out the file.
-.PP
-Additionally, if the leading garbage contains a \*(L"Prereq: \*(R" line,
-.I patch
-will take the first word from the prerequisites line (normally a version
-number) and check the input file to see if that word can be found.
-If not,
-.I patch
-will ask for confirmation before proceeding.
-.PP
-The upshot of all this is that you should be able to say, while in a news
-interface, the following:
-.Sp
- | patch -d /usr/src/local/blurfl
-.Sp
-and patch a file in the blurfl directory directly from the article containing
-the patch.
-.PP
-If the patch file contains more than one patch,
-.I patch
-will try to apply each of them as if they came from separate patch files.
-This means, among other things, that it is assumed that the name of the file
-to patch must be determined for each diff listing,
-and that the garbage before each diff listing will
-be examined for interesting things such as file names and revision level, as
-mentioned previously.
-You can give options (and another original file name) for the second and
-subsequent patches by separating the corresponding argument lists
-by a \*(L'+\*(R'.
-(The argument list for a second or subsequent patch may not specify a new
-patch file, however.)
-.PP
-.I Patch
-recognizes the following options:
-.TP 5
-.B "\-b suff, \-\-suffix=suff"
-causes
-.B suff
-to be interpreted as the backup extension, to be
-used in place of \*(L".orig\*(R" or \*(L"~\*(R".
-.TP 5
-.B "\-B pref, \-\-prefix=pref"
-causes
-.B pref
-to be interpreted as a prefix to the backup file
-name. If this argument is specified, any argument from
-.B \-b
-will be ignored.
-.TP 5
-.B "\-c, \-\-context"
-forces
-.I patch
-to interpret the patch file as a context diff.
-.TP 5
-.B "\-C, \-\-check"
-see what would happen, but don't do it.
-.TP 5
-.B "\-d dir, \-\-directory=dir"
-causes
-.I patch
-to interpret
-.B dir
-as a directory, and cd to it before doing
-anything else.
-.TP 5
-.B "\-D sym, \-\-ifdef=sym"
-causes
-.I patch
-to use the "#ifdef...#endif" construct to mark changes.
-.B sym
-will be used as the differentiating symbol.
-.TP 5
-.B "\-e, \-\-ed"
-forces
-.I patch
-to interpret the patch file as an
-.I ed
-script.
-.TP 5
-.B "\-E, \-\-remove\-empty\-files"
-causes
-.I patch
-to remove output files that are empty after the patches have been applied.
-.TP 5
-.B "\-f, \-\-force"
-forces
-.I patch
-to assume that the user knows exactly what he or she is doing, and to not
-ask any questions. It assumes the following: skip patches for which a
-file to patch can't be found; patch files even though they have the
-wrong version for the ``Prereq:'' line in the patch; and assume that
-patches are not reversed even if they look like they are.
-This option does not suppress commentary; use
-.B \-s
-for that.
-.TP 5
-.B "\-t, \-\-batch"
-similar to
-.BR \-f ,
-in that it suppresses questions, but makes some different assumptions:
-skip patches for which a file to patch can't be found (the same as \fB\-f\fP);
-skip patches for which the file has the wrong version for the ``Prereq:'' line
-in the patch; and assume that patches are reversed if they look like
-they are.
-.TP 5
-.B "\-F number, \-\-fuzz=number"
-sets the maximum fuzz factor.
-This option only applies to context diffs, and causes
-.I patch
-to ignore up to that many lines in looking for places to install a hunk.
-Note that a larger fuzz factor increases the odds of a faulty patch.
-The default fuzz factor is 2, and it may not be set to more than
-the number of lines of context in the context diff, ordinarily 3.
-.TP 5
-.B "\-i patchfile"
-tells
-.I patch
-to apply \fBpatchfile\fP instead of stdin.
-.TP 5
-.B "\-I, \-\-index-first"
-forces
-.I patch
-to take ``Index:'' line precedence over context diff header.
-The same effect have
-.B PATCH_INDEX_FIRST
-environment variable if present.
-.TP 5
-.B "\-l, \-\-ignore\-whitespace"
-causes the pattern matching to be done loosely, in case the tabs and
-spaces have been munged in your input file.
-Any sequence of whitespace in the pattern line will match any sequence
-in the input file.
-Normal characters must still match exactly.
-Each line of the context must still match a line in the input file.
-.TP 5
-.B "\-n, \-\-normal"
-forces
-.I patch
-to interpret the patch file as a normal diff.
-.TP 5
-.B "\-N, \-\-forward"
-causes
-.I patch
-to ignore patches that it thinks are reversed or already applied.
-See also
-.B \-R .
-.TP 5
-.B "\-o file, \-\-output=file"
-causes
-.B file
-to be interpreted as the output file name.
-.TP 5
-.B "\-p[number], \-\-strip[=number]"
-sets the pathname strip count,
-which controls how pathnames found in the patch file are treated, in case
-you keep your files in a different directory than the person who sent
-out the patch.
-The strip count specifies how many slashes are to be stripped from
-the front of the pathname.
-(Any intervening directory names also go away.)
-For example, supposing the file name in the patch file was
-.sp
- /u/howard/src/blurfl/blurfl.c
-.sp
-setting
-.B \-p
-or
-.B \-p0
-gives the entire pathname unmodified,
-.B \-p1
-gives
-.sp
- u/howard/src/blurfl/blurfl.c
-.sp
-without the leading slash,
-.B \-p4
-gives
-.sp
- blurfl/blurfl.c
-.sp
-and not specifying
-.B \-p
-at all just gives you "blurfl.c", unless all of the directories in the
-leading path (u/howard/src/blurfl) exist and that path is relative,
-in which case you get the entire pathname unmodified.
-Whatever you end up with is looked for either in the current directory,
-or the directory specified by the
-.B \-d
-option.
-.TP 5
-.B "\-r file, \-\-reject\-file=file"
-causes
-.B file
-to be interpreted as the reject file name.
-.TP 5
-.B "\-R, \-\-reverse"
-tells
-.I patch
-that this patch was created with the old and new files swapped.
-(Yes, I'm afraid that does happen occasionally, human nature being what it
-is.)
-.I Patch
-will attempt to swap each hunk around before applying it.
-Rejects will come out in the swapped format.
-The
-.B \-R
-option will not work with
-.I ed
-diff scripts because there is too little
-information to reconstruct the reverse operation.
-.Sp
-If the first hunk of a patch fails,
-.I patch
-will reverse the hunk to see if it can be applied that way.
-If it can, you will be asked if you want to have the
-.B \-R
-option set.
-If it can't, the patch will continue to be applied normally.
-(Note: this method cannot detect a reversed patch if it is a normal diff
-and if the first command is an append (i.e. it should have been a delete)
-since appends always succeed, due to the fact that a null context will match
-anywhere.
-Luckily, most patches add or change lines rather than delete them, so most
-reversed normal diffs will begin with a delete, which will fail, triggering
-the heuristic.)
-.TP 5
-.B "\-s, \-\-silent, \-\-quiet"
-makes
-.I patch
-do its work silently, unless an error occurs.
-.TP 5
-.B "\-S, \-\-skip"
-causes
-.I patch
-to ignore this patch from the patch file, but continue on looking
-for the next patch in the file.
-Thus
-.sp
- patch -S + -S + <patchfile
-.sp
-will ignore the first and second of three patches.
-.TP 5
-.B "\-u, \-\-unified"
-forces
-.I patch
-to interpret the patch file as a unified context diff (a unidiff).
-.TP 5
-.B "\-v, \-\-version"
-causes
-.I patch
-to print out its revision header and patch level.
-.TP 5
-.B "\-V method, \-\-version\-control=method"
-causes
-.B method
-to be interpreted as a method for creating
-backup file names. The type of backups made can also be given in the
-.B VERSION_CONTROL
-environment variable, which is overridden by this option.
-The
-.B -B
-option overrides this option, causing the prefix to always be used for
-making backup file names.
-The value of the
-.B VERSION_CONTROL
-environment variable and the argument to the
-.B -V
-option are like the GNU
-Emacs `version-control' variable; they also recognize synonyms that
-are more descriptive. The valid values are (unique abbreviations are
-accepted):
-.RS
-.TP
-`t' or `numbered'
-Always make numbered backups.
-.TP
-`nil' or `existing'
-Make numbered backups of files that already
-have them, simple backups of the others.
-This is the default.
-.TP
-`never' or `simple'
-Always make simple backups.
-.RE
-.TP 5
-.B "\-x number, \-\-debug=number"
-sets internal debugging flags, and is of interest only to
-.I patch
-patchers.
-.SH AUTHOR
-Larry Wall <lwall@netlabs.com>
-.br
-with many other contributors.
-.SH ENVIRONMENT
-.TP
-.B TMPDIR
-Directory to put temporary files in; default is /tmp.
-.TP
-.B SIMPLE_BACKUP_SUFFIX
-Extension to use for backup file names instead of \*(L".orig\*(R" or
-\*(L"~\*(R".
-.TP
-.B VERSION_CONTROL
-Selects when numbered backup files are made.
-.SH FILES
-$TMPDIR/patch*
-.SH SEE ALSO
-diff(1)
-.SH NOTES FOR PATCH SENDERS
-There are several things you should bear in mind if you are going to
-be sending out patches.
-First, you can save people a lot of grief by keeping a patchlevel.h file
-which is patched to increment the patch level as the first diff in the
-patch file you send out.
-If you put a Prereq: line in with the patch, it won't let them apply
-patches out of order without some warning.
-Second, make sure you've specified the file names right, either in a
-context diff header, or with an Index: line.
-If you are patching something in a subdirectory, be sure to tell the patch
-user to specify a
-.B \-p
-option as needed.
-Third, you can create a file by sending out a diff that compares a
-null file to the file you want to create.
-This will only work if the file you want to create doesn't exist already in
-the target directory.
-Fourth, take care not to send out reversed patches, since it makes people wonder
-whether they already applied the patch.
-Fifth, while you may be able to get away with putting 582 diff listings into
-one file, it is probably wiser to group related patches into separate files in
-case something goes haywire.
-.SH DIAGNOSTICS
-Too many to list here, but generally indicative that
-.I patch
-couldn't parse your patch file.
-.PP
-The message \*(L"Hmm...\*(R" indicates that there is unprocessed text in
-the patch file and that
-.I patch
-is attempting to intuit whether there is a patch in that text and, if so,
-what kind of patch it is.
-.PP
-.I Patch
-will exit with a non-zero status if any reject files were created.
-When applying a set of patches in a loop it behooves you to check this
-exit status so you don't apply a later patch to a partially patched file.
-.SH CAVEATS
-.I Patch
-cannot tell if the line numbers are off in an
-.I ed
-script, and can only detect
-bad line numbers in a normal diff when it finds a \*(L"change\*(R" or
-a \*(L"delete\*(R" command.
-A context diff using fuzz factor 3 may have the same problem.
-Until a suitable interactive interface is added, you should probably do
-a context diff in these cases to see if the changes made sense.
-Of course, compiling without errors is a pretty good indication that the patch
-worked, but not always.
-.PP
-.I Patch
-usually produces the correct results, even when it has to do a lot of
-guessing.
-However, the results are guaranteed to be correct only when the patch is
-applied to exactly the same version of the file that the patch was
-generated from.
-.SH BUGS
-Could be smarter about partial matches, excessively \&deviant offsets and
-swapped code, but that would take an extra pass.
-.PP
-If code has been duplicated (for instance with #ifdef OLDCODE ... #else ...
-#endif),
-.I patch
-is incapable of patching both versions, and, if it works at all, will likely
-patch the wrong one, and tell you that it succeeded to boot.
-.PP
-If you apply a patch you've already applied,
-.I patch
-will think it is a reversed patch, and offer to un-apply the patch.
-This could be construed as a feature.
-.rn }` ''
diff --git a/gnu/usr.bin/patch/patch.c b/gnu/usr.bin/patch/patch.c
deleted file mode 100644
index fbf7e70..0000000
--- a/gnu/usr.bin/patch/patch.c
+++ /dev/null
@@ -1,971 +0,0 @@
-char rcsid[] =
- "$FreeBSD$";
-
-/* patch - a program to apply diffs to original files
- *
- * Copyright 1986, Larry Wall
- *
- * This program may be copied as long as you don't try to make any
- * money off of it, or pretend that you wrote it.
- *
- * $Log: patch.c,v $
- * Revision 2.0.2.0 90/05/01 22:17:50 davison
- * patch12u: unidiff support added
- *
- * Revision 2.0.1.6 88/06/22 20:46:39 lwall
- * patch12: rindex() wasn't declared
- *
- * Revision 2.0.1.5 88/06/03 15:09:37 lwall
- * patch10: exit code improved.
- * patch10: better support for non-flexfilenames.
- *
- * Revision 2.0.1.4 87/02/16 14:00:04 lwall
- * Short replacement caused spurious "Out of sync" message.
- *
- * Revision 2.0.1.3 87/01/30 22:45:50 lwall
- * Improved diagnostic on sync error.
- * Moved do_ed_script() to pch.c.
- *
- * Revision 2.0.1.2 86/11/21 09:39:15 lwall
- * Fuzz factor caused offset of installed lines.
- *
- * Revision 2.0.1.1 86/10/29 13:10:22 lwall
- * Backwards search could terminate prematurely.
- *
- * Revision 2.0 86/09/17 15:37:32 lwall
- * Baseline for netwide release.
- *
- * Revision 1.5 86/08/01 20:53:24 lwall
- * Changed some %d's to %ld's.
- * Linted.
- *
- * Revision 1.4 86/08/01 19:17:29 lwall
- * Fixes for machines that can't vararg.
- * Added fuzz factor.
- * Generalized -p.
- * General cleanup.
- *
- * 85/08/15 van%ucbmonet@berkeley
- * Changes for 4.3bsd diff -c.
- *
- * Revision 1.3 85/03/26 15:07:43 lwall
- * Frozen.
- *
- * Revision 1.2.1.9 85/03/12 17:03:35 lwall
- * Changed pfp->_file to fileno(pfp).
- *
- * Revision 1.2.1.8 85/03/12 16:30:43 lwall
- * Check i_ptr and i_womp to make sure they aren't null before freeing.
- * Also allow ed output to be suppressed.
- *
- * Revision 1.2.1.7 85/03/12 15:56:13 lwall
- * Added -p option from jromine@uci-750a.
- *
- * Revision 1.2.1.6 85/03/12 12:12:51 lwall
- * Now checks for normalness of file to patch.
- *
- * Revision 1.2.1.5 85/03/12 11:52:12 lwall
- * Added -D (#ifdef) option from joe@fluke.
- *
- * Revision 1.2.1.4 84/12/06 11:14:15 lwall
- * Made smarter about SCCS subdirectories.
- *
- * Revision 1.2.1.3 84/12/05 11:18:43 lwall
- * Added -l switch to do loose string comparison.
- *
- * Revision 1.2.1.2 84/12/04 09:47:13 lwall
- * Failed hunk count not reset on multiple patch file.
- *
- * Revision 1.2.1.1 84/12/04 09:42:37 lwall
- * Branch for sdcrdcf changes.
- *
- * Revision 1.2 84/11/29 13:29:51 lwall
- * Linted. Identifiers uniqified. Fixed i_ptr malloc() bug. Fixed
- * multiple calls to mktemp(). Will now work on machines that can only
- * read 32767 chars. Added -R option for diffs with new and old swapped.
- * Various cosmetic changes.
- *
- * Revision 1.1 84/11/09 17:03:58 lwall
- * Initial revision
- *
- */
-
-#include <paths.h>
-#include "INTERN.h"
-#include "common.h"
-#include "EXTERN.h"
-#include "version.h"
-#include "util.h"
-#include "pch.h"
-#include "inp.h"
-#include "backupfile.h"
-#include "getopt.h"
-
-/* procedures */
-
-void reinitialize_almost_everything(void);
-void get_some_switches(void);
-LINENUM locate_hunk(LINENUM _fuzz);
-void abort_hunk(void);
-void apply_hunk(LINENUM _where);
-void init_output(char *_name);
-void init_reject(char *_name);
-void copy_till(LINENUM _lastline);
-void spew_output(void);
-void dump_line(LINENUM _line);
-bool patch_match(LINENUM _base, LINENUM _offset, LINENUM _fuzz);
-bool similar(char *_a, char *_b, int _len);
-void my_exit(int _status);
-
-
-/* TRUE if -E was specified on command line. */
-static int remove_empty_files = FALSE;
-
-/* TRUE if -R was specified on command line. */
-static int reverse_flag_specified = FALSE;
-
-/* TRUE if -C was specified on command line. */
-int check_patch = FALSE;
-
-/* TRUE if -I was specified on command line */
-/* or PATCH_INDEX_FIRST env. variable is set */
-int index_first;
-
-/* TRUE if -S was specified on command line. */
-int skip_flag_specified = FALSE;
-
-/* Apply a set of diffs as appropriate. */
-
-int
-main(argc,argv)
-int argc;
-char **argv;
-{
- LINENUM where;
- LINENUM newwhere;
- LINENUM fuzz;
- LINENUM mymaxfuzz;
- int hunk = 0;
- int failed = 0;
- int failtotal = 0;
- bool rev_okayed = 0;
- int i;
-
- setbuf(stderr, serrbuf);
- for (i = 0; i<MAXFILEC; i++)
- filearg[i] = Nullch;
-
- buf_size = INITLINELEN;
- buf = malloc((MEM)(buf_size));
- if (buf == Nullch)
- fatal1("out of memory\n");
-
- myuid = getuid();
-
- index_first = getenv ("PATCH_INDEX_FIRST") != 0;
-
- /* Cons up the names of the temporary files. */
- {
- /* Directory for temporary files. */
- char *tmpdir;
- int tmpname_len;
-
- tmpdir = getenv ("TMPDIR");
- if (tmpdir == NULL) {
- tmpdir = _PATH_TMP;
- }
- tmpname_len = strlen (tmpdir) + 20;
-
- TMPOUTNAME = (char *) malloc (tmpname_len);
- strcpy (TMPOUTNAME, tmpdir);
- strcat (TMPOUTNAME, "/patchoXXXXXX");
- Mktemp(TMPOUTNAME);
-
- TMPINNAME = (char *) malloc (tmpname_len);
- strcpy (TMPINNAME, tmpdir);
- strcat (TMPINNAME, "/patchiXXXXXX");
- Mktemp(TMPINNAME);
-
- TMPREJNAME = (char *) malloc (tmpname_len);
- strcpy (TMPREJNAME, tmpdir);
- strcat (TMPREJNAME, "/patchrXXXXXX");
- Mktemp(TMPREJNAME);
-
- TMPPATNAME = (char *) malloc (tmpname_len);
- strcpy (TMPPATNAME, tmpdir);
- strcat (TMPPATNAME, "/patchpXXXXXX");
- Mktemp(TMPPATNAME);
- }
-
- {
- char *v;
-
- v = getenv ("SIMPLE_BACKUP_SUFFIX");
- if (v)
- simple_backup_suffix = v;
- else
- simple_backup_suffix = ".orig";
-#ifndef NODIR
- v = getenv ("VERSION_CONTROL");
- backup_type = get_version (v); /* OK to pass NULL. */
-#endif
- }
-
- /* parse switches */
- Argc = argc;
- Argv = argv;
- get_some_switches();
-
- /* make sure we clean up /tmp in case of disaster */
- set_signals(0);
-
- for (
- open_patch_file(filearg[1]);
- there_is_another_patch();
- reinitialize_almost_everything()
- ) { /* for each patch in patch file */
-
- if (outname == Nullch)
- outname = savestr(filearg[0]);
-
- /* for ed script just up and do it and exit */
- if (diff_type == ED_DIFF) {
- do_ed_script();
- continue;
- }
-
- /* initialize the patched file */
- if (!skip_rest_of_patch)
- init_output(TMPOUTNAME);
-
- /* initialize reject file */
- init_reject(TMPREJNAME);
-
- /* find out where all the lines are */
- if (!skip_rest_of_patch)
- scan_input(filearg[0]);
-
- /* from here on, open no standard i/o files, because malloc */
- /* might misfire and we can't catch it easily */
-
- /* apply each hunk of patch */
- hunk = 0;
- failed = 0;
- rev_okayed = FALSE;
- out_of_mem = FALSE;
- while (another_hunk()) {
- hunk++;
- fuzz = Nulline;
- mymaxfuzz = pch_context();
- if (maxfuzz < mymaxfuzz)
- mymaxfuzz = maxfuzz;
- if (!skip_rest_of_patch) {
- do {
- where = locate_hunk(fuzz);
- if (hunk == 1 && where == Nulline && !(force|rev_okayed)) {
- /* dwim for reversed patch? */
- if (!pch_swap()) {
- if (fuzz == Nulline)
- say1(
-"Not enough memory to try swapped hunk! Assuming unswapped.\n");
- continue;
- }
- reverse = !reverse;
- where = locate_hunk(fuzz); /* try again */
- if (where == Nulline) { /* didn't find it swapped */
- if (!pch_swap()) /* put it back to normal */
- fatal1("lost hunk on alloc error!\n");
- reverse = !reverse;
- }
- else if (noreverse) {
- if (!pch_swap()) /* put it back to normal */
- fatal1("lost hunk on alloc error!\n");
- reverse = !reverse;
- say1(
-"Ignoring previously applied (or reversed) patch.\n");
- skip_rest_of_patch = TRUE;
- }
- else if (batch) {
- if (verbose)
- say3(
-"%seversed (or previously applied) patch detected! %s -R.",
- reverse ? "R" : "Unr",
- reverse ? "Assuming" : "Ignoring");
- }
- else {
- (void) ask3(
-"%seversed (or previously applied) patch detected! %s -R? [y] ",
- reverse ? "R" : "Unr",
- reverse ? "Assume" : "Ignore");
- if (*buf == 'n') {
- (void) ask1("Apply anyway? [n] ");
- if (*buf == 'y')
- rev_okayed = TRUE;
- else
- skip_rest_of_patch = TRUE;
- where = Nulline;
- reverse = !reverse;
- if (!pch_swap()) /* put it back to normal */
- fatal1("lost hunk on alloc error!\n");
- }
- }
- }
- } while (!skip_rest_of_patch && where == Nulline &&
- ++fuzz <= mymaxfuzz);
-
- if (skip_rest_of_patch) { /* just got decided */
- Fclose(ofp);
- ofp = Nullfp;
- }
- }
-
- newwhere = pch_newfirst() + last_offset;
- if (skip_rest_of_patch) {
- abort_hunk();
- if (! skip_flag_specified)
- failed++;
- if (verbose)
- say3("Hunk #%d ignored at %ld.\n", hunk, newwhere);
- }
- else if (where == Nulline) {
- abort_hunk();
- failed++;
- if (verbose)
- say3("Hunk #%d failed at %ld.\n", hunk, newwhere);
- }
- else {
- apply_hunk(where);
- if (verbose) {
- say3("Hunk #%d succeeded at %ld", hunk, newwhere);
- if (fuzz)
- say2(" with fuzz %ld", fuzz);
- if (last_offset)
- say3(" (offset %ld line%s)",
- last_offset, last_offset==1L?"":"s");
- say1(".\n");
- }
- }
- }
-
- if (out_of_mem && using_plan_a) {
- optind = optind_last;
- say1("\n\nRan out of memory using Plan A--trying again...\n\n");
- if (ofp)
- Fclose(ofp);
- ofp = Nullfp;
- if (rejfp)
- Fclose(rejfp);
- rejfp = Nullfp;
- continue;
- }
-
- assert(hunk);
-
- /* finish spewing out the new file */
- if (!skip_rest_of_patch)
- spew_output();
-
- /* and put the output where desired */
- ignore_signals();
- if (!skip_rest_of_patch) {
- struct stat statbuf;
- char *realout = outname;
-
- if (check_patch) {
- ;
- } else if (move_file(TMPOUTNAME, outname) < 0) {
- toutkeep = TRUE;
- realout = TMPOUTNAME;
- chmod(TMPOUTNAME, filemode);
- }
- else
- chmod(outname, filemode);
-
- if (remove_empty_files && stat(realout, &statbuf) == 0
- && statbuf.st_size == 0) {
- if (verbose)
- say2("Removing %s (empty after patching).\n", realout);
- while (unlink(realout) >= 0) ; /* while is for Eunice. */
- }
- }
- Fclose(rejfp);
- rejfp = Nullfp;
- if (failed) {
- failtotal += failed;
- if (!*rejname) {
- Strlcpy(rejname, outname, sizeof(rejname));
- addext(rejname, ".rej", '#');
- }
- if (skip_rest_of_patch) {
- say4("%d out of %d hunks ignored--saving rejects to %s\n",
- failed, hunk, rejname);
- }
- else {
- say4("%d out of %d hunks failed--saving rejects to %s\n",
- failed, hunk, rejname);
- }
- if (check_patch) {
- ;
- } else if (move_file(TMPREJNAME, rejname) < 0)
- trejkeep = TRUE;
- }
- set_signals(1);
- }
- my_exit(failtotal);
- return (failtotal);
-}
-
-/* Prepare to find the next patch to do in the patch file. */
-
-void
-reinitialize_almost_everything(void)
-{
- re_patch();
- re_input();
-
- input_lines = 0;
- last_frozen_line = 0;
-
- filec = 0;
- if (filearg[0] != Nullch && !out_of_mem) {
- free(filearg[0]);
- filearg[0] = Nullch;
- }
-
- if (outname != Nullch) {
- free(outname);
- outname = Nullch;
- }
-
- last_offset = 0;
-
- diff_type = 0;
-
- if (revision != Nullch) {
- free(revision);
- revision = Nullch;
- }
-
- reverse = reverse_flag_specified;
- skip_rest_of_patch = FALSE;
- skip_flag_specified = FALSE;
-
- get_some_switches();
-
- if (filec >= 2)
- fatal1("you may not change to a different patch file\n");
-}
-
-static char *shortopts = "-b:B:cCd:D:eEfF:i:IlnNo:p::r:RsStuvV:x:";
-static struct option longopts[] =
-{
- {"suffix", 1, NULL, 'b'},
- {"prefix", 1, NULL, 'B'},
- {"check", 0, NULL, 'C'},
- {"context", 0, NULL, 'c'},
- {"directory", 1, NULL, 'd'},
- {"ifdef", 1, NULL, 'D'},
- {"ed", 0, NULL, 'e'},
- {"remove-empty-files", 0, NULL, 'E'},
- {"force", 0, NULL, 'f'},
- {"fuzz", 1, NULL, 'F'},
- {"index-first", 0, NULL, 'I'},
- {"ignore-whitespace", 0, NULL, 'l'},
- {"normal", 0, NULL, 'n'},
- {"forward", 0, NULL, 'N'},
- {"output", 1, NULL, 'o'},
- {"strip", 2, NULL, 'p'},
- {"reject-file", 1, NULL, 'r'},
- {"reverse", 0, NULL, 'R'},
- {"quiet", 0, NULL, 's'},
- {"silent", 0, NULL, 's'},
- {"skip", 0, NULL, 'S'},
- {"batch", 0, NULL, 't'},
- {"unified", 0, NULL, 'u'},
- {"version", 0, NULL, 'v'},
- {"version-control", 1, NULL, 'V'},
- {"debug", 1, NULL, 'x'},
- {0, 0, 0, 0}
-};
-
-/* Process switches and filenames up to next '+' or end of list. */
-
-void
-get_some_switches(void)
-{
- Reg1 int optc;
-
- rejname[0] = '\0';
- optind_last = optind;
- if (optind == Argc)
- return;
- while ((optc = getopt_long (Argc, Argv, shortopts, longopts, (int *) 0))
- != -1) {
- if (optc == 1) {
- if (strEQ(optarg, "+"))
- return;
- if (filec == MAXFILEC)
- fatal1("too many file arguments\n");
- filearg[filec++] = savestr(optarg);
- }
- else {
- switch (optc) {
- case 'b':
- simple_backup_suffix = savestr(optarg);
- break;
- case 'B':
- origprae = savestr(optarg);
- break;
- case 'c':
- diff_type = CONTEXT_DIFF;
- break;
- case 'C':
- check_patch = TRUE;
- break;
- case 'd':
- if (chdir(optarg) < 0)
- pfatal2("can't cd to %s", optarg);
- break;
- case 'D':
- do_defines = TRUE;
- if (!isalpha((unsigned char)*optarg) && '_' != *optarg)
- fatal1("argument to -D is not an identifier\n");
- Snprintf(if_defined, sizeof(if_defined), "#ifdef %s\n", optarg);
- Snprintf(not_defined, sizeof(not_defined), "#ifndef %s\n", optarg);
- Snprintf(end_defined, sizeof(end_defined), "#endif /* %s */\n", optarg);
- break;
- case 'e':
- diff_type = ED_DIFF;
- break;
- case 'E':
- remove_empty_files = TRUE;
- break;
- case 'f':
- force = TRUE;
- break;
- case 'F':
- maxfuzz = atoi(optarg);
- break;
- case 'i':
- filearg[1] = savestr(optarg);
- break;
- case 'I':
- index_first = TRUE;
- break;
- case 'l':
- canonicalize = TRUE;
- break;
- case 'n':
- diff_type = NORMAL_DIFF;
- break;
- case 'N':
- noreverse = TRUE;
- break;
- case 'o':
- outname = savestr(optarg);
- break;
- case 'p':
- if (optarg)
- strippath = atoi(optarg);
- else
- strippath = 0;
- break;
- case 'r':
- Strlcpy(rejname, optarg, sizeof(rejname));
- break;
- case 'R':
- reverse = TRUE;
- reverse_flag_specified = TRUE;
- break;
- case 's':
- verbose = FALSE;
- break;
- case 'S':
- skip_rest_of_patch = TRUE;
- skip_flag_specified = TRUE;
- break;
- case 't':
- batch = TRUE;
- break;
- case 'u':
- diff_type = UNI_DIFF;
- break;
- case 'v':
- version();
- break;
- case 'V':
-#ifndef NODIR
- backup_type = get_version (optarg);
-#endif
- break;
-#ifdef DEBUGGING
- case 'x':
- debug = atoi(optarg);
- break;
-#endif
- default:
- fprintf(stderr, "\
-Usage: %s [options] [origfile [patchfile]] [+ [options] [origfile]]...\n",
- Argv[0]);
- fprintf(stderr, "\
-Options:\n\
- [-cCeEflnNRsStuv] [-b backup-ext] [-B backup-prefix] [-d directory]\n\
- [-D symbol] [-F max-fuzz] [-i patchfile] [-o out-file] [-p[strip-count]]\n\
- [-r rej-name] [-V {numbered,existing,simple}] [--check] [--context]\n\
- [--prefix=backup-prefix] [--suffix=backup-ext] [--ifdef=symbol]\n\
- [--directory=directory] [--ed] [--fuzz=max-fuzz] [--force] [--batch]\n\
- [--ignore-whitespace] [--forward] [--reverse] [--output=out-file]\n");
- fprintf(stderr, "\
- [--strip[=strip-count]] [--normal] [--reject-file=rej-name] [--skip]\n\
- [--remove-empty-files] [--quiet] [--silent] [--unified] [--version]\n\
- [--version-control={numbered,existing,simple}] [--index-first]\n");
- my_exit(1);
- }
- }
- }
-
- /* Process any filename args given after "--". */
- for (; optind < Argc; ++optind) {
- if (filec == MAXFILEC)
- fatal1("too many file arguments\n");
- filearg[filec++] = savestr(Argv[optind]);
- }
-}
-
-/*
- * Attempt to find the right place to apply this hunk of patch.
- */
-LINENUM
-locate_hunk(LINENUM fuzz)
-{
- Reg1 LINENUM first_guess = pch_first() + last_offset;
- Reg2 LINENUM offset;
- LINENUM pat_lines = pch_ptrn_lines();
- Reg3 LINENUM max_pos_offset = input_lines - first_guess
- - pat_lines + 1;
- Reg4 LINENUM max_neg_offset = first_guess - last_frozen_line - 1
- + pch_context();
-
- if (!pat_lines) /* null range matches always */
- return first_guess;
- if (max_neg_offset >= first_guess) /* do not try lines < 0 */
- max_neg_offset = first_guess - 1;
- if (first_guess <= input_lines && patch_match(first_guess, Nulline, fuzz))
- return first_guess;
- for (offset = 1; ; offset++) {
- Reg5 bool check_after = (offset <= max_pos_offset);
- Reg6 bool check_before = (offset <= max_neg_offset);
-
- if (check_after && patch_match(first_guess, offset, fuzz)) {
-#ifdef DEBUGGING
- if (debug & 1)
- say3("Offset changing from %ld to %ld\n", last_offset, offset);
-#endif
- last_offset = offset;
- return first_guess+offset;
- }
- else if (check_before && patch_match(first_guess, -offset, fuzz)) {
-#ifdef DEBUGGING
- if (debug & 1)
- say3("Offset changing from %ld to %ld\n", last_offset, -offset);
-#endif
- last_offset = -offset;
- return first_guess-offset;
- }
- else if (!check_before && !check_after)
- return Nulline;
- }
-}
-
-/* We did not find the pattern, dump out the hunk so they can handle it. */
-
-void
-abort_hunk(void)
-{
- Reg1 LINENUM i;
- Reg2 LINENUM pat_end = pch_end();
- /* add in last_offset to guess the same as the previous successful hunk */
- LINENUM oldfirst = pch_first() + last_offset;
- LINENUM newfirst = pch_newfirst() + last_offset;
- LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1;
- LINENUM newlast = newfirst + pch_repl_lines() - 1;
- char *stars = (diff_type >= NEW_CONTEXT_DIFF ? " ****" : "");
- char *minuses = (diff_type >= NEW_CONTEXT_DIFF ? " ----" : " -----");
-
- fprintf(rejfp, "***************\n");
- for (i=0; i<=pat_end; i++) {
- switch (pch_char(i)) {
- case '*':
- if (oldlast < oldfirst)
- fprintf(rejfp, "*** 0%s\n", stars);
- else if (oldlast == oldfirst)
- fprintf(rejfp, "*** %ld%s\n", oldfirst, stars);
- else
- fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars);
- break;
- case '=':
- if (newlast < newfirst)
- fprintf(rejfp, "--- 0%s\n", minuses);
- else if (newlast == newfirst)
- fprintf(rejfp, "--- %ld%s\n", newfirst, minuses);
- else
- fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses);
- break;
- case '\n':
- fprintf(rejfp, "%s", pfetch(i));
- break;
- case ' ': case '-': case '+': case '!':
- fprintf(rejfp, "%c %s", pch_char(i), pfetch(i));
- break;
- default:
- fatal1("fatal internal error in abort_hunk\n");
- }
- }
-}
-
-/*
- * We found where to apply it (we hope), so do it.
- */
-void
-apply_hunk(LINENUM where)
-{
- Reg1 LINENUM old = 1;
- Reg2 LINENUM lastline = pch_ptrn_lines();
- Reg3 LINENUM new = lastline+1;
-#define OUTSIDE 0
-#define IN_IFNDEF 1
-#define IN_IFDEF 2
-#define IN_ELSE 3
- Reg4 int def_state = OUTSIDE;
- Reg5 bool R_do_defines = do_defines;
- Reg6 LINENUM pat_end = pch_end();
-
- where--;
- while (pch_char(new) == '=' || pch_char(new) == '\n')
- new++;
-
- while (old <= lastline) {
- if (pch_char(old) == '-') {
- copy_till(where + old - 1);
- if (R_do_defines) {
- if (def_state == OUTSIDE) {
- fputs(not_defined, ofp);
- def_state = IN_IFNDEF;
- }
- else if (def_state == IN_IFDEF) {
- fputs(else_defined, ofp);
- def_state = IN_ELSE;
- }
- fputs(pfetch(old), ofp);
- }
- last_frozen_line++;
- old++;
- }
- else if (new > pat_end) {
- break;
- }
- else if (pch_char(new) == '+') {
- copy_till(where + old - 1);
- if (R_do_defines) {
- if (def_state == IN_IFNDEF) {
- fputs(else_defined, ofp);
- def_state = IN_ELSE;
- }
- else if (def_state == OUTSIDE) {
- fputs(if_defined, ofp);
- def_state = IN_IFDEF;
- }
- }
- fputs(pfetch(new), ofp);
- new++;
- }
- else if (pch_char(new) != pch_char(old)) {
- say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
- pch_hunk_beg() + old,
- pch_hunk_beg() + new);
-#ifdef DEBUGGING
- say3("oldchar = '%c', newchar = '%c'\n",
- pch_char(old), pch_char(new));
-#endif
- my_exit(1);
- }
- else if (pch_char(new) == '!') {
- copy_till(where + old - 1);
- if (R_do_defines) {
- fputs(not_defined, ofp);
- def_state = IN_IFNDEF;
- }
- while (pch_char(old) == '!') {
- if (R_do_defines) {
- fputs(pfetch(old), ofp);
- }
- last_frozen_line++;
- old++;
- }
- if (R_do_defines) {
- fputs(else_defined, ofp);
- def_state = IN_ELSE;
- }
- while (pch_char(new) == '!') {
- fputs(pfetch(new), ofp);
- new++;
- }
- }
- else {
- assert(pch_char(new) == ' ');
- old++;
- new++;
- if (R_do_defines && def_state != OUTSIDE) {
- fputs(end_defined, ofp);
- def_state = OUTSIDE;
- }
- }
- }
- if (new <= pat_end && pch_char(new) == '+') {
- copy_till(where + old - 1);
- if (R_do_defines) {
- if (def_state == OUTSIDE) {
- fputs(if_defined, ofp);
- def_state = IN_IFDEF;
- }
- else if (def_state == IN_IFNDEF) {
- fputs(else_defined, ofp);
- def_state = IN_ELSE;
- }
- }
- while (new <= pat_end && pch_char(new) == '+') {
- fputs(pfetch(new), ofp);
- new++;
- }
- }
- if (R_do_defines && def_state != OUTSIDE) {
- fputs(end_defined, ofp);
- }
-}
-
-/* Open the new file. */
-
-void
-init_output(char *name)
-{
- ofp = fopen(name, "w");
- if (ofp == Nullfp)
- pfatal2("can't create %s", name);
-}
-
-/* Open a file to put hunks we can't locate. */
-
-void
-init_reject(char *name)
-{
- rejfp = fopen(name, "w");
- if (rejfp == Nullfp)
- pfatal2("can't create %s", name);
-}
-
-/* Copy input file to output, up to wherever hunk is to be applied. */
-
-void
-copy_till(LINENUM lastline)
-{
- Reg2 LINENUM R_last_frozen_line = last_frozen_line;
-
- if (R_last_frozen_line > lastline)
- fatal1("misordered hunks! output would be garbled\n");
- while (R_last_frozen_line < lastline) {
- dump_line(++R_last_frozen_line);
- }
- last_frozen_line = R_last_frozen_line;
-}
-
-/* Finish copying the input file to the output file. */
-
-void
-spew_output(void)
-{
-#ifdef DEBUGGING
- if (debug & 256)
- say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line);
-#endif
- if (input_lines)
- copy_till(input_lines); /* dump remainder of file */
- Fclose(ofp);
- ofp = Nullfp;
-}
-
-/* Copy one line from input to output. */
-
-void
-dump_line(LINENUM line)
-{
- Reg1 char *s;
- Reg2 char R_newline = '\n';
-
- /* Note: string is not null terminated. */
- for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ;
-}
-
-/* Does the patch pattern match at line base+offset? */
-
-bool
-patch_match(LINENUM base, LINENUM offset, LINENUM fuzz)
-{
- Reg1 LINENUM pline = 1 + fuzz;
- Reg2 LINENUM iline;
- Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz;
-
- for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) {
- if (canonicalize) {
- if (!similar(ifetch(iline, (offset >= 0)),
- pfetch(pline),
- pch_line_len(pline) ))
- return FALSE;
- }
- else if (strnNE(ifetch(iline, (offset >= 0)),
- pfetch(pline),
- pch_line_len(pline) ))
- return FALSE;
- }
- return TRUE;
-}
-
-/* Do two lines match with canonicalized white space? */
-
-bool
-similar(char *a, char *b, int len)
-{
- while (len) {
- if (isspace((unsigned char)*b)) { /* whitespace (or \n) to match? */
- if (!isspace((unsigned char)*a)) /* no corresponding whitespace? */
- return FALSE;
- while (len && isspace((unsigned char)*b) && *b != '\n')
- b++,len--; /* skip pattern whitespace */
- while (isspace((unsigned char)*a) && *a != '\n')
- a++; /* skip target whitespace */
- if (*a == '\n' || *b == '\n')
- return (*a == *b); /* should end in sync */
- }
- else if (*a++ != *b++) /* match non-whitespace chars */
- return FALSE;
- else
- len--; /* probably not necessary */
- }
- return TRUE; /* actually, this is not reached */
- /* since there is always a \n */
-}
-
-/* Exit with cleanup. */
-
-void
-my_exit(int status)
-{
- Unlink(TMPINNAME);
- if (!toutkeep) {
- Unlink(TMPOUTNAME);
- }
- if (!trejkeep) {
- Unlink(TMPREJNAME);
- }
- Unlink(TMPPATNAME);
- exit(status);
-}
diff --git a/gnu/usr.bin/patch/patchlevel.h b/gnu/usr.bin/patch/patchlevel.h
deleted file mode 100644
index d5de3a9..0000000
--- a/gnu/usr.bin/patch/patchlevel.h
+++ /dev/null
@@ -1 +0,0 @@
-#define PATCH_VERSION "2.1"
diff --git a/gnu/usr.bin/patch/pch.c b/gnu/usr.bin/patch/pch.c
deleted file mode 100644
index 37bbe56..0000000
--- a/gnu/usr.bin/patch/pch.c
+++ /dev/null
@@ -1,1449 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: pch.c,v $
- * Revision 2.0.2.0 90/05/01 22:17:51 davison
- * patch12u: unidiff support added
- *
- * Revision 2.0.1.7 88/06/03 15:13:28 lwall
- * patch10: Can now find patches in shar scripts.
- * patch10: Hunks that swapped and then swapped back could core dump.
- *
- * Revision 2.0.1.6 87/06/04 16:18:13 lwall
- * pch_swap didn't swap p_bfake and p_efake.
- *
- * Revision 2.0.1.5 87/01/30 22:47:42 lwall
- * Improved responses to mangled patches.
- *
- * Revision 2.0.1.4 87/01/05 16:59:53 lwall
- * New-style context diffs caused double call to free().
- *
- * Revision 2.0.1.3 86/11/14 10:08:33 lwall
- * Fixed problem where a long pattern wouldn't grow the hunk.
- * Also restored p_input_line when backtracking so error messages are right.
- *
- * Revision 2.0.1.2 86/11/03 17:49:52 lwall
- * New-style delete triggers spurious assertion error.
- *
- * Revision 2.0.1.1 86/10/29 15:52:08 lwall
- * Could falsely report new-style context diff.
- *
- * Revision 2.0 86/09/17 15:39:37 lwall
- * Baseline for netwide release.
- *
- */
-
-#include "EXTERN.h"
-#include "common.h"
-#include "util.h"
-#include "INTERN.h"
-#include "pch.h"
-
-/* Patch (diff listing) abstract type. */
-
-static long p_filesize; /* size of the patch file */
-static LINENUM p_first; /* 1st line number */
-static LINENUM p_newfirst; /* 1st line number of replacement */
-static LINENUM p_ptrn_lines; /* # lines in pattern */
-static LINENUM p_repl_lines; /* # lines in replacement text */
-static LINENUM p_end = -1; /* last line in hunk */
-static LINENUM p_max; /* max allowed value of p_end */
-static LINENUM p_context = 3; /* # of context lines */
-static LINENUM p_input_line = 0; /* current line # from patch file */
-static char **p_line = Null(char**); /* the text of the hunk */
-static short *p_len = Null(short*); /* length of each line */
-static char *p_Char = Nullch; /* +, -, and ! */
-static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
-static int p_indent; /* indent to patch */
-static LINENUM p_base; /* where to intuit this time */
-static LINENUM p_bline; /* line # of p_base */
-static LINENUM p_start; /* where intuit found a patch */
-static LINENUM p_sline; /* and the line number for it */
-static LINENUM p_hunk_beg; /* line number of current hunk */
-static LINENUM p_efake = -1; /* end of faked up lines--don't free */
-static LINENUM p_bfake = -1; /* beg of faked up lines */
-
-/*
- * Prepare to look for the next patch in the patch file.
- */
-void
-re_patch(void)
-{
- p_first = Nulline;
- p_newfirst = Nulline;
- p_ptrn_lines = Nulline;
- p_repl_lines = Nulline;
- p_end = (LINENUM)-1;
- p_max = Nulline;
- p_indent = 0;
-}
-
-/*
- * Open the patch file at the beginning of time.
- */
-void
-open_patch_file(char *filename)
-{
- int nr, nw;
-
- if (filename == Nullch || !*filename || strEQ(filename, "-")) {
- pfp = fopen(TMPPATNAME, "w");
- if (pfp == Nullfp)
- pfatal2("can't create %s", TMPPATNAME);
- while ((nr = fread(buf, 1, buf_size, stdin)) > 0) {
- nw = fwrite(buf, 1, nr, pfp);
- if (nr != nw)
- pfatal2("write error to %s", TMPPATNAME);
- }
- Fclose(pfp);
- filename = TMPPATNAME;
- }
- pfp = fopen(filename, "r");
- if (pfp == Nullfp)
- pfatal2("patch file %s not found", filename);
- Fstat(fileno(pfp), &filestat);
- p_filesize = filestat.st_size;
- next_intuit_at(0L,1L); /* start at the beginning */
- set_hunkmax();
-}
-
-/*
- * Make sure our dynamically realloced tables are malloced to begin with.
- */
-void
-set_hunkmax(void)
-{
-#ifndef lint
- if (p_line == Null(char**))
- p_line = (char**) malloc((MEM)hunkmax * sizeof(char *));
- if (p_len == Null(short*))
- p_len = (short*) malloc((MEM)hunkmax * sizeof(short));
-#endif
- if (p_Char == Nullch)
- p_Char = (char*) malloc((MEM)hunkmax * sizeof(char));
-}
-
-/*
- * Enlarge the arrays containing the current hunk of patch.
- */
-void
-grow_hunkmax(void)
-{
- hunkmax *= 2;
- /*
- * Note that on most systems, only the p_line array ever gets
- * fresh memory since p_len can move into p_line's old space,
- * and p_Char can move into p_len's old space. Not on PDP-11's
- * however. But it doesn't matter.
- */
- assert(p_line != Null(char**) && p_len != Null(short*) &&
- p_Char != Nullch);
-#ifndef lint
- p_line = (char**) realloc((char*)p_line, (MEM)hunkmax * sizeof(char *));
- p_len = (short*) realloc((char*)p_len, (MEM)hunkmax * sizeof(short));
- p_Char = (char*) realloc((char*)p_Char, (MEM)hunkmax * sizeof(char));
-#endif
- if (p_line != Null(char**) && p_len != Null(short*) && p_Char != Nullch)
- return;
- if (!using_plan_a)
- fatal1("out of memory\n");
- out_of_mem = TRUE; /* whatever is null will be allocated again */
- /* from within plan_a(), of all places */
-}
-
-/*
- * True if the remainder of the patch file contains a diff of some sort.
- */
-bool
-there_is_another_patch(void)
-{
- if (p_base != 0L && p_base >= p_filesize) {
- if (verbose)
- say1("done\n");
- return FALSE;
- }
- if (verbose)
- say1("Hmm...");
- diff_type = intuit_diff_type();
- if (!diff_type) {
- if (p_base != 0L) {
- if (verbose)
- say1(" Ignoring the trailing garbage.\ndone\n");
- }
- else
- say1(" I can't seem to find a patch in there anywhere.\n");
- return FALSE;
- }
- if (verbose)
- say3(" %sooks like %s to me...\n",
- (p_base == 0L ? "L" : "The next patch l"),
- diff_type == UNI_DIFF ? "a unified diff" :
- diff_type == CONTEXT_DIFF ? "a context diff" :
- diff_type == NEW_CONTEXT_DIFF ?
- "a new-style context diff" :
- diff_type == NORMAL_DIFF ? "a normal diff" :
- "an ed script" );
- if (p_indent && verbose)
- say3("(Patch is indented %d space%s.)\n",
- p_indent, p_indent==1?"":"s");
- skip_to(p_start,p_sline);
- while (filearg[0] == Nullch) {
- if (force || batch || skip_rest_of_patch) {
- say1("No file to patch. Skipping...\n");
- filearg[0] = savestr(bestguess);
- skip_rest_of_patch = TRUE;
- return TRUE;
- }
- (void) ask1("File to patch: ");
- if (*buf != '\n') {
- if (bestguess)
- free(bestguess);
- bestguess = savestr(buf);
- filearg[0] = fetchname(buf, 0, FALSE);
- }
- if (filearg[0] == Nullch) {
- if (ask1("No file found--skip this patch? [n] ")) {
- if (*buf != 'y') {
- continue;
- }
- }
- if (verbose)
- say1("Skipping patch...\n");
- filearg[0] = fetchname(bestguess, 0, TRUE);
- skip_rest_of_patch = TRUE;
- return TRUE;
- }
- }
- return TRUE;
-}
-
-static char *
-p4_savestr(char *str)
-{
- char *t, *h;
-
- /* Leading whitespace. */
- while (isspace((unsigned char)*str))
- str++;
-
- /* Remove the file revision number. */
- for (t = str, h = NULL; *t != '\0' && !isspace((unsigned char)*t); t++)
- if (*t == '#')
- h = t;
- if (h != NULL)
- *h = '\0';
-
- return savestr(str);
-}
-
-/*
- * Determine what kind of diff is in the remaining part of the patch file.
- */
-int
-intuit_diff_type(void)
-{
- Reg4 long this_line = 0;
- Reg5 long previous_line;
- Reg6 long first_command_line = -1;
- long fcl_line;
- Reg7 bool last_line_was_command = FALSE;
- Reg8 bool this_is_a_command = FALSE;
- Reg9 bool stars_last_line = FALSE;
- Reg10 bool stars_this_line = FALSE;
- Reg3 int indent;
- Reg1 char *s;
- Reg2 char *t;
- char *indtmp = Nullch;
- char *oldtmp = Nullch;
- char *newtmp = Nullch;
- char *indname = Nullch;
- char *oldname = Nullch;
- char *newname = Nullch;
- Reg11 int retval;
- bool no_filearg = (filearg[0] == Nullch);
- extern int index_first;
-
- ok_to_create_file = FALSE;
- Fseek(pfp, p_base, 0);
- p_input_line = p_bline - 1;
- for (;;) {
- previous_line = this_line;
- last_line_was_command = this_is_a_command;
- stars_last_line = stars_this_line;
- this_line = ftell(pfp);
- indent = 0;
- p_input_line++;
- if (pgets(FALSE) == 0) {
- if (first_command_line >= 0L) {
- /* nothing but deletes!? */
- p_start = first_command_line;
- p_sline = fcl_line;
- retval = ED_DIFF;
- goto scan_exit;
- }
- else {
- p_start = this_line;
- p_sline = p_input_line;
- retval = 0;
- goto scan_exit;
- }
- }
- for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
- if (*s == '\t')
- indent += 8 - (indent % 8);
- else
- indent++;
- }
- for (t=s; isdigit((unsigned char)*t) || *t == ','; t++)
- ;
- this_is_a_command = (isdigit((unsigned char)*s) &&
- (*t == 'd' || *t == 'c' || *t == 'a') );
- if (first_command_line < 0L && this_is_a_command) {
- first_command_line = this_line;
- fcl_line = p_input_line;
- p_indent = indent; /* assume this for now */
- }
- if (!stars_last_line && strnEQ(s, "*** ", 4))
- oldtmp = savestr(s+4);
- else if (strnEQ(s, "--- ", 4))
- newtmp = savestr(s+4);
- else if (strnEQ(s, "+++ ", 4))
- oldtmp = savestr(s+4); /* pretend it is the old name */
- else if (strnEQ(s, "Index:", 6))
- indtmp = savestr(s+6);
- else if (strnEQ(s, "Prereq:", 7)) {
- for (t = s + 7; isspace((unsigned char)*t); t++)
- ;
- revision = savestr(t);
- for (t = revision; *t && !isspace((unsigned char)*t);
- t++)
- ;
- *t = '\0';
- if (!*revision) {
- free(revision);
- revision = Nullch;
- }
- } else if (strnEQ(s, "==== ", 5)) {
- /* Perforce-style diffs. */
- if ((t = strstr(s + 5, " - ")) != NULL)
- newtmp = p4_savestr(t + 3);
- oldtmp = p4_savestr(s + 5);
- }
- if ((!diff_type || diff_type == ED_DIFF) &&
- first_command_line >= 0L &&
- strEQ(s, ".\n") ) {
- p_indent = indent;
- p_start = first_command_line;
- p_sline = fcl_line;
- retval = ED_DIFF;
- goto scan_exit;
- }
- if ((!diff_type || diff_type == UNI_DIFF) &&
- strnEQ(s, "@@ -", 4)) {
- if (!atol(s+3))
- ok_to_create_file = TRUE;
- p_indent = indent;
- p_start = this_line;
- p_sline = p_input_line;
- retval = UNI_DIFF;
- goto scan_exit;
- }
- stars_this_line = strnEQ(s, "********", 8);
- if ((!diff_type || diff_type == CONTEXT_DIFF) &&
- stars_last_line &&
- strnEQ(s, "*** ", 4)) {
- if (!atol(s+4))
- ok_to_create_file = TRUE;
- /*
- * If this is a new context diff the character just
- * before the newline is a '*'.
- */
- while (*s != '\n')
- s++;
- p_indent = indent;
- p_start = previous_line;
- p_sline = p_input_line - 1;
- retval = (*(s-1) == '*' ?
- NEW_CONTEXT_DIFF : CONTEXT_DIFF);
- goto scan_exit;
- }
- if ((!diff_type || diff_type == NORMAL_DIFF) &&
- last_line_was_command &&
- (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2)) ) {
- p_start = previous_line;
- p_sline = p_input_line - 1;
- p_indent = indent;
- retval = NORMAL_DIFF;
- goto scan_exit;
- }
- }
- scan_exit:
- if (no_filearg) {
- if (indtmp != Nullch)
- indname = fetchname(indtmp, strippath,
- ok_to_create_file);
- if (oldtmp != Nullch)
- oldname = fetchname(oldtmp, strippath,
- ok_to_create_file);
- if (newtmp != Nullch)
- newname = fetchname(newtmp, strippath,
- ok_to_create_file);
- if (index_first && indname)
- filearg[0] = savestr(indname);
- else if (oldname && newname) {
- if (strlen(oldname) < strlen(newname))
- filearg[0] = savestr(oldname);
- else
- filearg[0] = savestr(newname);
- } else if (indname)
- filearg[0] = savestr(indname);
- else if (oldname)
- filearg[0] = savestr(oldname);
- else if (newname)
- filearg[0] = savestr(newname);
- }
- if (bestguess) {
- free(bestguess);
- bestguess = Nullch;
- }
- if (filearg[0] != Nullch)
- bestguess = savestr(filearg[0]);
- else if (indtmp != Nullch)
- bestguess = fetchname(indtmp, strippath, TRUE);
- else {
- if (oldtmp != Nullch)
- oldname = fetchname(oldtmp, strippath, TRUE);
- if (newtmp != Nullch)
- newname = fetchname(newtmp, strippath, TRUE);
- if (oldname && newname) {
- if (strlen(oldname) < strlen(newname))
- bestguess = savestr(oldname);
- else
- bestguess = savestr(newname);
- }
- else if (oldname)
- bestguess = savestr(oldname);
- else if (newname)
- bestguess = savestr(newname);
- }
- if (indtmp != Nullch)
- free(indtmp);
- if (oldtmp != Nullch)
- free(oldtmp);
- if (newtmp != Nullch)
- free(newtmp);
- if (indname != Nullch)
- free(indname);
- if (oldname != Nullch)
- free(oldname);
- if (newname != Nullch)
- free(newname);
- return retval;
-}
-
-/*
- * Remember where this patch ends so we know where to start up again.
- */
-void
-next_intuit_at(long file_pos, long file_line)
-{
- p_base = file_pos;
- p_bline = file_line;
-}
-
-/*
- * Basically a verbose fseek() to the actual diff listing.
- */
-void
-skip_to(long file_pos, long file_line)
-{
- size_t len;
-
- assert(p_base <= file_pos);
- if (verbose && p_base < file_pos) {
- Fseek(pfp, p_base, 0);
- say1("The text leading up to this was:\n--------------------------\n");
- while (ftell(pfp) < file_pos) {
- len = pgets(FALSE);
- assert(len != 0);
- say2("|%s", buf);
- }
- say1("--------------------------\n");
- }
- else
- Fseek(pfp, file_pos, 0);
- p_input_line = file_line - 1;
-}
-
-/*
- * Make this a function for better debugging.
- */
-static void
-malformed(void)
-{
- fatal3("malformed patch at line %ld: %s", p_input_line, buf);
- /* about as informative as "Syntax error" in C */
-}
-
-/*
- * True if the line has been discarded (i.e. it is a line saying
- * "\ No newline at end of file".)
- */
-static bool
-remove_special_line(void)
-{
- int c;
-
- c = fgetc(pfp);
- if (c == '\\') {
- do {
- c = fgetc(pfp);
- } while (c != EOF && c != '\n');
-
- return TRUE;
- }
-
- if (c != EOF)
- fseek(pfp, -1, SEEK_CUR);
-
- return FALSE;
-}
-
-/*
- * True if there is more of the current diff listing to process.
- */
-bool
-another_hunk(void)
-{
- Reg1 char *s;
- size_t len;
- Reg2 int context = 0;
-
- while (p_end >= 0) {
- if (p_end == p_efake)
- p_end = p_bfake; /* don't free twice */
- else
- free(p_line[p_end]);
- p_end--;
- }
- assert(p_end == -1);
- p_efake = -1;
-
- p_max = hunkmax; /* gets reduced when --- found */
- if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
- long line_beginning = ftell(pfp);
- /* file pos of the current line */
- LINENUM repl_beginning = 0; /* index of --- line */
- Reg4 LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */
- Reg5 LINENUM fillsrc; /* index of first line to copy */
- Reg6 LINENUM filldst; /* index of first missing line */
- bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */
- Reg9 bool repl_could_be_missing = TRUE;
- /* no + or ! lines in this hunk */
- bool repl_missing = FALSE; /* we are now backtracking */
- long repl_backtrack_position = 0;
- /* file pos of first repl line */
- LINENUM repl_patch_line; /* input line number for same */
- Reg7 LINENUM ptrn_copiable = 0;
- /* # of copiable lines in ptrn */
-
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0 || strnNE(buf, "********", 8)) {
- next_intuit_at(line_beginning,p_input_line);
- return FALSE;
- }
- p_context = 100;
- p_hunk_beg = p_input_line + 1;
- while (p_end < p_max) {
- line_beginning = ftell(pfp);
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0) {
- if (p_max - p_end < 4)
- Strcpy(buf, " \n"); /* assume blank lines got chopped */
- else {
- if (repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- fatal1("unexpected end of file in patch\n");
- }
- }
- p_end++;
- assert(p_end < hunkmax);
- p_Char[p_end] = *buf;
-#ifdef zilog
- p_line[(short)p_end] = Nullch;
-#else
- p_line[p_end] = Nullch;
-#endif
- switch (*buf) {
- case '*':
- if (strnEQ(buf, "********", 8)) {
- if (repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- else
- fatal2("unexpected end of hunk at line %ld\n",
- p_input_line);
- }
- if (p_end != 0) {
- if (repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- fatal3("unexpected *** at line %ld: %s", p_input_line, buf);
- }
- context = 0;
- p_line[p_end] = savestr(buf);
- if (out_of_mem) {
- p_end--;
- return FALSE;
- }
- for (s=buf; *s && !isdigit((unsigned char)*s); s++) ;
- if (!*s)
- malformed ();
- if (strnEQ(s,"0,0",3))
- strcpy(s,s+2);
- p_first = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s)) s++;
- if (*s == ',') {
- for (; *s && !isdigit((unsigned char)*s); s++) ;
- if (!*s)
- malformed ();
- p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
- }
- else if (p_first)
- p_ptrn_lines = 1;
- else {
- p_ptrn_lines = 0;
- p_first = 1;
- }
- p_max = p_ptrn_lines + 6; /* we need this much at least */
- while (p_max >= hunkmax)
- grow_hunkmax();
- p_max = hunkmax;
- break;
- case '-':
- if (buf[1] == '-') {
- if (repl_beginning ||
- (p_end != p_ptrn_lines + 1 + (p_Char[p_end-1] == '\n')))
- {
- if (p_end == 1) {
- /* `old' lines were omitted - set up to fill */
- /* them in from 'new' context lines. */
- p_end = p_ptrn_lines + 1;
- fillsrc = p_end + 1;
- filldst = 1;
- fillcnt = p_ptrn_lines;
- }
- else {
- if (repl_beginning) {
- if (repl_could_be_missing){
- repl_missing = TRUE;
- goto hunk_done;
- }
- fatal3(
-"duplicate \"---\" at line %ld--check line numbers at line %ld\n",
- p_input_line, p_hunk_beg + repl_beginning);
- }
- else {
- fatal4(
-"%s \"---\" at line %ld--check line numbers at line %ld\n",
- (p_end <= p_ptrn_lines
- ? "Premature"
- : "Overdue" ),
- p_input_line, p_hunk_beg);
- }
- }
- }
- repl_beginning = p_end;
- repl_backtrack_position = ftell(pfp);
- repl_patch_line = p_input_line;
- p_line[p_end] = savestr(buf);
- if (out_of_mem) {
- p_end--;
- return FALSE;
- }
- p_Char[p_end] = '=';
- for (s=buf; *s && !isdigit((unsigned char)*s); s++) ;
- if (!*s)
- malformed ();
- p_newfirst = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s)) s++;
- if (*s == ',') {
- for (; *s && !isdigit((unsigned char)*s); s++) ;
- if (!*s)
- malformed ();
- p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1;
- }
- else if (p_newfirst)
- p_repl_lines = 1;
- else {
- p_repl_lines = 0;
- p_newfirst = 1;
- }
- p_max = p_repl_lines + p_end;
- if (p_max > MAXHUNKSIZE)
- fatal4("hunk too large (%ld lines) at line %ld: %s",
- p_max, p_input_line, buf);
- while (p_max >= hunkmax)
- grow_hunkmax();
- if (p_repl_lines != ptrn_copiable
- && (p_context != 0 || p_repl_lines != 1))
- repl_could_be_missing = FALSE;
- break;
- }
- goto change_line;
- case '+': case '!':
- repl_could_be_missing = FALSE;
- change_line:
- if (buf[1] == '\n' && canonicalize)
- strcpy(buf+1," \n");
- if (!isspace((unsigned char)buf[1]) && buf[1] != '>' && buf[1] != '<' &&
- repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- if (context >= 0) {
- if (context < p_context)
- p_context = context;
- context = -1000;
- }
- p_line[p_end] = savestr(buf+2);
- if (out_of_mem) {
- p_end--;
- return FALSE;
- }
- if (p_end == p_ptrn_lines)
- {
- if (remove_special_line()) {
- int len;
-
- len = strlen(p_line[p_end]) - 1;
- (p_line[p_end])[len] = 0;
- }
- }
- break;
- case '\t': case '\n': /* assume the 2 spaces got eaten */
- if (repl_beginning && repl_could_be_missing &&
- (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF) ) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- p_line[p_end] = savestr(buf);
- if (out_of_mem) {
- p_end--;
- return FALSE;
- }
- if (p_end != p_ptrn_lines + 1) {
- ptrn_spaces_eaten |= (repl_beginning != 0);
- context++;
- if (!repl_beginning)
- ptrn_copiable++;
- p_Char[p_end] = ' ';
- }
- break;
- case ' ':
- if (!isspace((unsigned char)buf[1]) &&
- repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- context++;
- if (!repl_beginning)
- ptrn_copiable++;
- p_line[p_end] = savestr(buf+2);
- if (out_of_mem) {
- p_end--;
- return FALSE;
- }
- break;
- default:
- if (repl_beginning && repl_could_be_missing) {
- repl_missing = TRUE;
- goto hunk_done;
- }
- malformed ();
- }
- /* set up p_len for strncmp() so we don't have to */
- /* assume null termination */
- if (p_line[p_end])
- p_len[p_end] = strlen(p_line[p_end]);
- else
- p_len[p_end] = 0;
- }
-
- hunk_done:
- if (p_end >=0 && !repl_beginning)
- fatal2("no --- found in patch at line %ld\n", pch_hunk_beg());
-
- if (repl_missing) {
-
- /* reset state back to just after --- */
- p_input_line = repl_patch_line;
- for (p_end--; p_end > repl_beginning; p_end--)
- free(p_line[p_end]);
- Fseek(pfp, repl_backtrack_position, 0);
-
- /* redundant 'new' context lines were omitted - set */
- /* up to fill them in from the old file context */
- if (!p_context && p_repl_lines == 1) {
- p_repl_lines = 0;
- p_max--;
- }
- fillsrc = 1;
- filldst = repl_beginning+1;
- fillcnt = p_repl_lines;
- p_end = p_max;
- }
- else if (!p_context && fillcnt == 1) {
- /* the first hunk was a null hunk with no context */
- /* and we were expecting one line -- fix it up. */
- while (filldst < p_end) {
- p_line[filldst] = p_line[filldst+1];
- p_Char[filldst] = p_Char[filldst+1];
- p_len[filldst] = p_len[filldst+1];
- filldst++;
- }
-#if 0
- repl_beginning--; /* this doesn't need to be fixed */
-#endif
- p_end--;
- p_first++; /* do append rather than insert */
- fillcnt = 0;
- p_ptrn_lines = 0;
- }
-
- if (diff_type == CONTEXT_DIFF &&
- (fillcnt || (p_first > 1 && ptrn_copiable > 2*p_context)) ) {
- if (verbose)
- say4("%s\n%s\n%s\n",
-"(Fascinating--this is really a new-style context diff but without",
-"the telltale extra asterisks on the *** line that usually indicate",
-"the new style...)");
- diff_type = NEW_CONTEXT_DIFF;
- }
-
- /* if there were omitted context lines, fill them in now */
- if (fillcnt) {
- p_bfake = filldst; /* remember where not to free() */
- p_efake = filldst + fillcnt - 1;
- while (fillcnt-- > 0) {
- while (fillsrc <= p_end && p_Char[fillsrc] != ' ')
- fillsrc++;
- if (fillsrc > p_end)
- fatal2("replacement text or line numbers mangled in hunk at line %ld\n",
- p_hunk_beg);
- p_line[filldst] = p_line[fillsrc];
- p_Char[filldst] = p_Char[fillsrc];
- p_len[filldst] = p_len[fillsrc];
- fillsrc++; filldst++;
- }
- while (fillsrc <= p_end && fillsrc != repl_beginning &&
- p_Char[fillsrc] != ' ')
- fillsrc++;
-#ifdef DEBUGGING
- if (debug & 64)
- printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n",
- fillsrc,filldst,repl_beginning,p_end+1);
-#endif
- assert(fillsrc==p_end+1 || fillsrc==repl_beginning);
- assert(filldst==p_end+1 || filldst==repl_beginning);
- }
-
- if (p_line[p_end] != NULL)
- {
- if (remove_special_line()) {
- p_len[p_end] -= 1;
- (p_line[p_end])[p_len[p_end]] = 0;
- }
- }
- }
- else if (diff_type == UNI_DIFF) {
- long line_beginning = ftell(pfp);
- /* file pos of the current line */
- Reg4 LINENUM fillsrc; /* index of old lines */
- Reg5 LINENUM filldst; /* index of new lines */
- char ch;
-
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0 || strnNE(buf, "@@ -", 4)) {
- next_intuit_at(line_beginning,p_input_line);
- return FALSE;
- }
- s = buf+4;
- if (!*s)
- malformed ();
- p_first = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s)) s++;
- if (*s == ',') {
- p_ptrn_lines = (LINENUM) atol(++s);
- while (isdigit((unsigned char)*s)) s++;
- } else
- p_ptrn_lines = 1;
- if (*s == ' ') s++;
- if (*s != '+' || !*++s)
- malformed ();
- p_newfirst = (LINENUM) atol(s);
- while (isdigit((unsigned char)*s)) s++;
- if (*s == ',') {
- p_repl_lines = (LINENUM) atol(++s);
- while (isdigit((unsigned char)*s)) s++;
- } else
- p_repl_lines = 1;
- if (*s == ' ') s++;
- if (*s != '@')
- malformed ();
- if (!p_ptrn_lines)
- p_first++; /* do append rather than insert */
- p_max = p_ptrn_lines + p_repl_lines + 1;
- while (p_max >= hunkmax)
- grow_hunkmax();
- fillsrc = 1;
- filldst = fillsrc + p_ptrn_lines;
- p_end = filldst + p_repl_lines;
- Sprintf(buf,"*** %ld,%ld ****\n",p_first,p_first + p_ptrn_lines - 1);
- p_line[0] = savestr(buf);
- if (out_of_mem) {
- p_end = -1;
- return FALSE;
- }
- p_Char[0] = '*';
- Sprintf(buf,"--- %ld,%ld ----\n",p_newfirst,p_newfirst+p_repl_lines-1);
- p_line[filldst] = savestr(buf);
- if (out_of_mem) {
- p_end = 0;
- return FALSE;
- }
- p_Char[filldst++] = '=';
- p_context = 100;
- context = 0;
- p_hunk_beg = p_input_line + 1;
- while (fillsrc <= p_ptrn_lines || filldst <= p_end) {
- line_beginning = ftell(pfp);
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0) {
- if (p_max - filldst < 3)
- Strcpy(buf, " \n"); /* assume blank lines got chopped */
- else {
- fatal1("unexpected end of file in patch\n");
- }
- }
- if (*buf == '\t' || *buf == '\n') {
- ch = ' '; /* assume the space got eaten */
- s = savestr(buf);
- }
- else {
- ch = *buf;
- s = savestr(buf+1);
- }
- if (out_of_mem) {
- while (--filldst > p_ptrn_lines)
- free(p_line[filldst]);
- p_end = fillsrc-1;
- return FALSE;
- }
- switch (ch) {
- case '-':
- if (fillsrc > p_ptrn_lines) {
- free(s);
- p_end = filldst-1;
- malformed ();
- }
- p_Char[fillsrc] = ch;
- p_line[fillsrc] = s;
- p_len[fillsrc++] = strlen(s);
- if (fillsrc > p_ptrn_lines) {
- if (remove_special_line()) {
- p_len[fillsrc - 1] -= 1;
- s[p_len[fillsrc - 1]] = 0;
- }
- }
- break;
- case '=':
- ch = ' ';
- /* FALLTHROUGH */
- case ' ':
- if (fillsrc > p_ptrn_lines) {
- free(s);
- while (--filldst > p_ptrn_lines)
- free(p_line[filldst]);
- p_end = fillsrc-1;
- malformed ();
- }
- context++;
- p_Char[fillsrc] = ch;
- p_line[fillsrc] = s;
- p_len[fillsrc++] = strlen(s);
- s = savestr(s);
- if (out_of_mem) {
- while (--filldst > p_ptrn_lines)
- free(p_line[filldst]);
- p_end = fillsrc-1;
- return FALSE;
- }
- /* FALLTHROUGH */
- case '+':
- if (filldst > p_end) {
- free(s);
- while (--filldst > p_ptrn_lines)
- free(p_line[filldst]);
- p_end = fillsrc-1;
- malformed ();
- }
- p_Char[filldst] = ch;
- p_line[filldst] = s;
- p_len[filldst++] = strlen(s);
- if (fillsrc > p_ptrn_lines) {
- if (remove_special_line()) {
- p_len[filldst - 1] -= 1;
- s[p_len[filldst - 1]] = 0;
- }
- }
- break;
- default:
- p_end = filldst;
- malformed ();
- }
- if (ch != ' ' && context > 0) {
- if (context < p_context)
- p_context = context;
- context = -1000;
- }
- }/* while */
- }
- else { /* normal diff--fake it up */
- char hunk_type;
- Reg3 int i;
- LINENUM min, max;
- long line_beginning = ftell(pfp);
-
- p_context = 0;
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0 || !isdigit((unsigned char)*buf)) {
- next_intuit_at(line_beginning,p_input_line);
- return FALSE;
- }
- p_first = (LINENUM)atol(buf);
- for (s=buf; isdigit((unsigned char)*s); s++) ;
- if (*s == ',') {
- p_ptrn_lines = (LINENUM)atol(++s) - p_first + 1;
- while (isdigit((unsigned char)*s)) s++;
- }
- else
- p_ptrn_lines = (*s != 'a');
- hunk_type = *s;
- if (hunk_type == 'a')
- p_first++; /* do append rather than insert */
- min = (LINENUM)atol(++s);
- for (; isdigit((unsigned char)*s); s++) ;
- if (*s == ',')
- max = (LINENUM)atol(++s);
- else
- max = min;
- if (hunk_type == 'd')
- min++;
- p_end = p_ptrn_lines + 1 + max - min + 1;
- if (p_end > MAXHUNKSIZE)
- fatal4("hunk too large (%ld lines) at line %ld: %s",
- p_end, p_input_line, buf);
- while (p_end >= hunkmax)
- grow_hunkmax();
- p_newfirst = min;
- p_repl_lines = max - min + 1;
- Sprintf(buf, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1);
- p_line[0] = savestr(buf);
- if (out_of_mem) {
- p_end = -1;
- return FALSE;
- }
- p_Char[0] = '*';
- for (i=1; i<=p_ptrn_lines; i++) {
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0)
- fatal2("unexpected end of file in patch at line %ld\n",
- p_input_line);
- if (*buf != '<')
- fatal2("< expected at line %ld of patch\n", p_input_line);
- p_line[i] = savestr(buf+2);
- if (out_of_mem) {
- p_end = i-1;
- return FALSE;
- }
- p_len[i] = strlen(p_line[i]);
- p_Char[i] = '-';
- }
-
- if (remove_special_line()) {
- p_len[i-1] -= 1;
- (p_line[i-1])[p_len[i-1]] = 0;
- }
-
- if (hunk_type == 'c') {
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0)
- fatal2("unexpected end of file in patch at line %ld\n",
- p_input_line);
- if (*buf != '-')
- fatal2("--- expected at line %ld of patch\n", p_input_line);
- }
- Sprintf(buf, "--- %ld,%ld\n", min, max);
- p_line[i] = savestr(buf);
- if (out_of_mem) {
- p_end = i-1;
- return FALSE;
- }
- p_Char[i] = '=';
- for (i++; i<=p_end; i++) {
- len = pgets(TRUE);
- p_input_line++;
- if (len == 0)
- fatal2("unexpected end of file in patch at line %ld\n",
- p_input_line);
- if (*buf != '>')
- fatal2("> expected at line %ld of patch\n", p_input_line);
- p_line[i] = savestr(buf+2);
- if (out_of_mem) {
- p_end = i-1;
- return FALSE;
- }
- p_len[i] = strlen(p_line[i]);
- p_Char[i] = '+';
- }
-
- if (remove_special_line()) {
- p_len[i-1] -= 1;
- (p_line[i-1])[p_len[i-1]] = 0;
- }
- }
- if (reverse) /* backwards patch? */
- if (!pch_swap())
- say1("Not enough memory to swap next hunk!\n");
-#ifdef DEBUGGING
- if (debug & 2) {
- int i;
- char special;
-
- for (i=0; i <= p_end; i++) {
- if (i == p_ptrn_lines)
- special = '^';
- else
- special = ' ';
- fprintf(stderr, "%3d %c %c %s", i, p_Char[i], special, p_line[i]);
- Fflush(stderr);
- }
- }
-#endif
- if (p_end+1 < hunkmax) /* paranoia reigns supreme... */
- p_Char[p_end+1] = '^'; /* add a stopper for apply_hunk */
- return TRUE;
-}
-
-/*
- * Input a line from the patch file.
- * Worry about indentation if do_indent is true.
- * The line is read directly into the buf global variable which
- * is resized if necessary in order to hold the complete line.
- * Returns the number of characters read including the terminating
- * '\n', if any.
- */
-size_t
-pgets(bool do_indent)
-{
- char *line;
- size_t len;
- int indent = 0, skipped = 0;
-
- line = fgetln(pfp, &len);
- if (line != Nullch) {
- if (len + 1 > buf_size) {
- while (len + 1 > buf_size)
- buf_size *= 2;
- free(buf);
- buf = malloc(buf_size);
- if (buf == Nullch)
- fatal1("out of memory\n");
- }
- if (do_indent == TRUE && p_indent) {
- for (;
- indent < p_indent && (*line == ' ' || *line == '\t' || *line == 'X');
- line++, skipped++) {
- if (*line == '\t')
- indent += 8 - (indent %7);
- else
- indent++;
- }
- }
- memcpy(buf, line, len - skipped);
- buf[len - skipped] = '\0';
- }
- return len;
-}
-
-/*
- * Reverse the old and new portions of the current hunk.
- */
-bool
-pch_swap(void)
-{
- char **tp_line; /* the text of the hunk */
- short *tp_len; /* length of each line */
- char *tp_char; /* +, -, and ! */
- Reg1 LINENUM i;
- Reg2 LINENUM n;
- bool blankline = FALSE;
- Reg3 char *s;
-
- i = p_first;
- p_first = p_newfirst;
- p_newfirst = i;
-
- /* make a scratch copy */
-
- tp_line = p_line;
- tp_len = p_len;
- tp_char = p_Char;
- p_line = Null(char**); /* force set_hunkmax to allocate again */
- p_len = Null(short*);
- p_Char = Nullch;
- set_hunkmax();
- if (p_line == Null(char**) || p_len == Null(short*) || p_Char == Nullch) {
-#ifndef lint
- if (p_line == Null(char**))
- free((char*)p_line);
- p_line = tp_line;
- if (p_len == Null(short*))
- free((char*)p_len);
- p_len = tp_len;
-#endif
- if (p_Char == Nullch)
- free((char*)p_Char);
- p_Char = tp_char;
- return FALSE; /* not enough memory to swap hunk! */
- }
-
- /* now turn the new into the old */
-
- i = p_ptrn_lines + 1;
- if (tp_char[i] == '\n') { /* account for possible blank line */
- blankline = TRUE;
- i++;
- }
- if (p_efake >= 0) { /* fix non-freeable ptr range */
- if (p_efake <= i)
- n = p_end - i + 1;
- else
- n = -i;
- p_efake += n;
- p_bfake += n;
- }
- for (n=0; i <= p_end; i++,n++) {
- p_line[n] = tp_line[i];
- p_Char[n] = tp_char[i];
- if (p_Char[n] == '+')
- p_Char[n] = '-';
- p_len[n] = tp_len[i];
- }
- if (blankline) {
- i = p_ptrn_lines + 1;
- p_line[n] = tp_line[i];
- p_Char[n] = tp_char[i];
- p_len[n] = tp_len[i];
- n++;
- }
- assert(p_Char[0] == '=');
- p_Char[0] = '*';
- for (s=p_line[0]; *s; s++)
- if (*s == '-')
- *s = '*';
-
- /* now turn the old into the new */
-
- assert(tp_char[0] == '*');
- tp_char[0] = '=';
- for (s=tp_line[0]; *s; s++)
- if (*s == '*')
- *s = '-';
- for (i=0; n <= p_end; i++,n++) {
- p_line[n] = tp_line[i];
- p_Char[n] = tp_char[i];
- if (p_Char[n] == '-')
- p_Char[n] = '+';
- p_len[n] = tp_len[i];
- }
- assert(i == p_ptrn_lines + 1);
- i = p_ptrn_lines;
- p_ptrn_lines = p_repl_lines;
- p_repl_lines = i;
-#ifndef lint
- if (tp_line == Null(char**))
- free((char*)tp_line);
- if (tp_len == Null(short*))
- free((char*)tp_len);
-#endif
- if (tp_char == Nullch)
- free((char*)tp_char);
- return TRUE;
-}
-
-/*
- * Return the specified line position in the old file of the old context.
- */
-LINENUM
-pch_first(void)
-{
- return p_first;
-}
-
-/*
- * Return the number of lines of old context.
- */
-LINENUM
-pch_ptrn_lines(void)
-{
- return p_ptrn_lines;
-}
-
-/*
- * Return the probable line position in the new file of the first line.
- */
-LINENUM
-pch_newfirst(void)
-{
- return p_newfirst;
-}
-
-/*
- * Return the number of lines in the replacement text including context.
- */
-LINENUM
-pch_repl_lines(void)
-{
- return p_repl_lines;
-}
-
-/*
- * Return the number of lines in the whole hunk.
- */
-LINENUM
-pch_end(void)
-{
- return p_end;
-}
-
-/*
- * Return the number of context lines before the first changed line.
- */
-LINENUM
-pch_context(void)
-{
- return p_context;
-}
-
-/*
- * Return the length of a particular patch line.
- */
-short
-pch_line_len(LINENUM line)
-{
- return p_len[line];
-}
-
-/*
- * Return the control character (+, -, *, !, etc) for a patch line.
- */
-char
-pch_char(LINENUM line)
-{
- return p_Char[line];
-}
-
-/*
- * Return a pointer to a particular patch line.
- */
-char *
-pfetch(LINENUM line)
-{
- return p_line[line];
-}
-
-/*
- * Return where in the patch file this hunk began, for error messages.
- */
-LINENUM
-pch_hunk_beg(void)
-{
- return p_hunk_beg;
-}
-
-/*
- * Apply an ed script by feeding ed itself.
- */
-void
-do_ed_script(void)
-{
- Reg1 char *t;
- Reg2 long beginning_of_this_line;
- Reg3 bool this_line_is_command = FALSE;
- Reg4 FILE *pipefp;
-
- if (!skip_rest_of_patch) {
- Unlink(TMPOUTNAME);
- copy_file(filearg[0], TMPOUTNAME);
- if (verbose)
- Sprintf(buf, "/bin/ed %s", TMPOUTNAME);
- else
- Sprintf(buf, "/bin/ed - %s", TMPOUTNAME);
- pipefp = popen(buf, "w");
- }
- for (;;) {
- beginning_of_this_line = ftell(pfp);
- if (pgets(TRUE) == 0) {
- next_intuit_at(beginning_of_this_line, p_input_line);
- break;
- }
- p_input_line++;
- for (t=buf; isdigit((unsigned char)*t) || *t == ','; t++)
- ;
- this_line_is_command = (isdigit((unsigned char)*buf) &&
- (*t == 'd' || *t == 'c' || *t == 'a') );
- if (this_line_is_command) {
- if (!skip_rest_of_patch)
- fputs(buf, pipefp);
- if (*t != 'd') {
- while (pgets(TRUE) != 0) {
- p_input_line++;
- if (!skip_rest_of_patch)
- fputs(buf, pipefp);
- if (strEQ(buf, ".\n"))
- break;
- }
- }
- }
- else {
- next_intuit_at(beginning_of_this_line,p_input_line);
- break;
- }
- }
- if (skip_rest_of_patch)
- return;
- fprintf(pipefp, "w\n");
- fprintf(pipefp, "q\n");
- Fflush(pipefp);
- Pclose(pipefp);
- ignore_signals();
- if (move_file(TMPOUTNAME, outname) < 0) {
- toutkeep = TRUE;
- chmod(TMPOUTNAME, filemode);
- }
- else
- chmod(outname, filemode);
- set_signals(1);
-}
diff --git a/gnu/usr.bin/patch/pch.h b/gnu/usr.bin/patch/pch.h
deleted file mode 100644
index 0393dea..0000000
--- a/gnu/usr.bin/patch/pch.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: pch.h,v $
- * Revision 2.0.1.1 87/01/30 22:47:16 lwall
- * Added do_ed_script().
- *
- * Revision 2.0 86/09/17 15:39:57 lwall
- * Baseline for netwide release.
- *
- */
-
-EXT FILE *pfp INIT(Nullfp); /* patch file pointer */
-
-void re_patch(void);
-void open_patch_file(char *_filename);
-void set_hunkmax(void);
-void grow_hunkmax(void);
-bool there_is_another_patch(void);
-int intuit_diff_type(void);
-void next_intuit_at(long _file_pos, long _file_line);
-void skip_to(long _file_pos, long _file_line);
-bool another_hunk(void);
-bool pch_swap(void);
-char *pfetch(LINENUM _line);
-short pch_line_len(LINENUM _line);
-LINENUM pch_first(void);
-LINENUM pch_ptrn_lines(void);
-LINENUM pch_newfirst(void);
-LINENUM pch_repl_lines(void);
-LINENUM pch_end(void);
-LINENUM pch_context(void);
-LINENUM pch_hunk_beg(void);
-char pch_char(LINENUM _line);
-char *pfetch(LINENUM _line);
-size_t pgets(bool _do_indent);
-void do_ed_script(void);
diff --git a/gnu/usr.bin/patch/util.c b/gnu/usr.bin/patch/util.c
deleted file mode 100644
index 5a76a03..0000000
--- a/gnu/usr.bin/patch/util.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* $FreeBSD$ */
-
-#include <paths.h>
-
-#include "EXTERN.h"
-#include "common.h"
-#include "INTERN.h"
-#include "util.h"
-#include "backupfile.h"
-
-void my_exit(int _status); /* in patch.c */
-
-#ifndef HAVE_STRERROR
-static char *
-private_strerror (errnum)
- int errnum;
-{
- extern char *sys_errlist[];
- extern int sys_nerr;
-
- if (errnum > 0 && errnum <= sys_nerr)
- return sys_errlist[errnum];
- return "Unknown system error";
-}
-#define strerror private_strerror
-#endif /* !HAVE_STRERROR */
-
-/*
- * Rename a file, copying it if necessary.
- */
-int
-move_file(char *from, char *to)
-{
- char bakname[512];
- Reg1 char *s;
- Reg2 int i;
- Reg3 int fromfd;
-
- /* to stdout? */
-
- if (strEQ(to, "-")) {
-#ifdef DEBUGGING
- if (debug & 4)
- say2("Moving %s to stdout.\n", from);
-#endif
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal2("internal error, can't reopen %s", from);
- while ((i = read(fromfd, buf, buf_size)) > 0)
- if (write(1, buf, i) != 1)
- pfatal1("write failed");
- Close(fromfd);
- return 0;
- }
-
- if (origprae) {
- Strcpy(bakname, origprae);
- Strcat(bakname, to);
- } else {
-#ifndef NODIR
- char *backupname = find_backup_file_name(to);
- if (backupname == (char *) 0)
- fatal1("out of memory\n");
- Strcpy(bakname, backupname);
- free(backupname);
-#else /* NODIR */
- Strcpy(bakname, to);
- Strcat(bakname, simple_backup_suffix);
-#endif /* NODIR */
- }
-
- if (stat(to, &filestat) == 0) { /* output file exists */
- dev_t to_device = filestat.st_dev;
- ino_t to_inode = filestat.st_ino;
- char *simplename = bakname;
-
- for (s = bakname; *s; s++) {
- if (*s == '/')
- simplename = s + 1;
- }
- /*
- * Find a backup name that is not the same file.
- * Change the first lowercase char into uppercase;
- * if that isn't sufficient, chop off the first char
- * and try again.
- */
- while (stat(bakname, &filestat) == 0 &&
- to_device == filestat.st_dev &&
- to_inode == filestat.st_ino) {
- /* Skip initial non-lowercase chars. */
- for (s=simplename; *s && !islower((unsigned char)*s);
- s++)
- ;
- if (*s)
- *s = toupper((unsigned char)*s);
- else
- Strcpy(simplename, simplename + 1);
- }
- while (unlink(bakname) >= 0)
- ; /* while() is for benefit of Eunice */
-#ifdef DEBUGGING
- if (debug & 4)
- say3("Moving %s to %s.\n", to, bakname);
-#endif
- if (rename(to, bakname) < 0) {
- say4("Can't backup %s, output is in %s: %s\n", to, from,
- strerror(errno));
- return -1;
- }
- while (unlink(to) >= 0)
- ;
- }
-#ifdef DEBUGGING
- if (debug & 4)
- say3("Moving %s to %s.\n", from, to);
-#endif
- if (rename(from, to) < 0) { /* different file system? */
- Reg4 int tofd;
-
- tofd = creat(to, 0666);
- if (tofd < 0) {
- say4("Can't create %s, output is in %s: %s\n",
- to, from, strerror(errno));
- return -1;
- }
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal2("internal error, can't reopen %s", from);
- while ((i = read(fromfd, buf, buf_size)) > 0)
- if (write(tofd, buf, i) != i)
- pfatal1("write failed");
- Close(fromfd);
- Close(tofd);
- }
- Unlink(from);
- return 0;
-}
-
-/*
- * Copy a file.
- */
-void
-copy_file(char *from, char *to)
-{
- Reg3 int tofd;
- Reg2 int fromfd;
- Reg1 int i;
-
- tofd = creat(to, 0666);
- if (tofd < 0)
- pfatal2("can't create %s", to);
- fromfd = open(from, 0);
- if (fromfd < 0)
- pfatal2("internal error, can't reopen %s", from);
- while ((i = read(fromfd, buf, buf_size)) > 0)
- if (write(tofd, buf, i) != i)
- pfatal2("write to %s failed", to);
- Close(fromfd);
- Close(tofd);
-}
-
-/*
- * Allocate a unique area for a string.
- */
-char *
-savestr(char *s)
-{
- Reg3 char *rv;
- Reg2 char *t;
-
- if (!s)
- s = "Oops";
- t = s;
- while (*t++)
- ;
- rv = malloc((MEM) (t - s));
- if (rv == Nullch) {
- if (using_plan_a)
- out_of_mem = TRUE;
- else
- fatal1("out of memory\n");
- } else {
- t = rv;
- while ((*t++ = *s++));
- }
- return rv;
-}
-
-#if defined(lint) && defined(CANVARARG)
-
-/*VARARGS ARGSUSED*/
-say(pat) char *pat; { ; }
-/*VARARGS ARGSUSED*/
-fatal(pat) char *pat; { ; }
-/*VARARGS ARGSUSED*/
-pfatal(pat) char *pat; { ; }
-/*VARARGS ARGSUSED*/
-ask(pat) char *pat; { ; }
-
-#else
-
-/*
- * Vanilla terminal output (buffered).
- */
-void
-say(pat,arg1,arg2,arg3)
-char *pat;
-long arg1,arg2,arg3;
-{
- fprintf(stderr, pat, arg1, arg2, arg3);
- Fflush(stderr);
-}
-
-/*
- * Terminal output, pun intended.
- */
-void /* very void */
-fatal(pat,arg1,arg2,arg3)
-char *pat;
-long arg1,arg2,arg3;
-{
- fprintf(stderr, "patch: **** ");
- fprintf(stderr, pat, arg1, arg2, arg3);
- my_exit(1);
-}
-
-/*
- * Say something from patch, something from the system, then silence...
- */
-void /* very void */
-pfatal(pat,arg1,arg2,arg3)
-char *pat;
-long arg1,arg2,arg3;
-{
- int errnum = errno;
-
- fprintf(stderr, "patch: **** ");
- fprintf(stderr, pat, arg1, arg2, arg3);
- fprintf(stderr, ": %s\n", strerror(errnum));
- my_exit(1);
-}
-
-/*
- * Get a response from the user, somehow or other.
- */
-int
-ask(pat,arg1,arg2,arg3)
-char *pat;
-long arg1,arg2,arg3;
-{
- int ttyfd;
- int r;
- bool tty2 = isatty(2);
-
- Sprintf(buf, pat, arg1, arg2, arg3);
- Fflush(stderr);
- write(2, buf, strlen(buf));
- if (tty2) { /* might be redirected to a file */
- r = read(2, buf, buf_size);
- } else if (isatty(1)) { /* this may be new file output */
- Fflush(stdout);
- write(1, buf, strlen(buf));
- r = read(1, buf, buf_size);
- } else if ((ttyfd = open(_PATH_TTY, 2)) >= 0 && isatty(ttyfd)) {
- /* might be deleted or unwriteable */
- write(ttyfd, buf, strlen(buf));
- r = read(ttyfd, buf, buf_size);
- Close(ttyfd);
- } else if (isatty(0)) { /* this is probably patch input */
- Fflush(stdin);
- write(0, buf, strlen(buf));
- r = read(0, buf, buf_size);
- } else { /* no terminal at all--default it */
- buf[0] = '\n';
- buf[1] = 0;
- say1(buf);
- return 0; /* signal possible error */
- }
- if (r <= 0)
- buf[0] = 0;
- else
- buf[r] = '\0';
- if (!tty2)
- say1(buf);
-
- if (r <= 0)
- return 0; /* if there was an error, return it */
- else
- return 1;
-}
-#endif /* lint */
-
-/*
- * How to handle certain events when not in a critical region.
- */
-void
-set_signals(int reset)
-{
-#ifndef lint
- static RETSIGTYPE (*hupval)(),(*intval)();
-
- if (!reset) {
- hupval = signal(SIGHUP, SIG_IGN);
- if (hupval != SIG_IGN)
- hupval = (RETSIGTYPE(*)())my_exit;
- intval = signal(SIGINT, SIG_IGN);
- if (intval != SIG_IGN)
- intval = (RETSIGTYPE(*)())my_exit;
- }
- Signal(SIGHUP, hupval);
- Signal(SIGINT, intval);
-#endif
-}
-
-/*
- * How to handle certain events when in a critical region.
- */
-void
-ignore_signals(void)
-{
-#ifndef lint
- Signal(SIGHUP, SIG_IGN);
- Signal(SIGINT, SIG_IGN);
-#endif
-}
-
-/*
- * Make sure we'll have the directories to create a file.
- * If `striplast' is TRUE, ignore the last element of `filename'.
- */
-void
-makedirs(filename,striplast)
-Reg1 char *filename;
-bool striplast;
-{
- char tmpbuf[256];
- Reg2 char *s = tmpbuf;
- char *dirv[20]; /* Point to the NULs between elements. */
- Reg3 int i;
- Reg4 int dirvp = 0; /* Number of finished entries in dirv. */
-
- /*
- * Copy `filename' into `tmpbuf' with a NUL instead of a slash
- * between the directories.
- */
- while (*filename) {
- if (*filename == '/') {
- filename++;
- dirv[dirvp++] = s;
- *s++ = '\0';
- } else {
- *s++ = *filename++;
- }
- }
- *s = '\0';
- dirv[dirvp] = s;
- if (striplast)
- dirvp--;
- if (dirvp < 0)
- return;
-
- strcpy(buf, "mkdir");
- s = buf;
- for (i = 0; i <= dirvp; i++) {
- struct stat sbuf;
-
- if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
- while (*s)
- s++;
- *s++ = ' ';
- strcpy(s, tmpbuf);
- }
- *dirv[i] = '/';
- }
- if (s != buf)
- system(buf);
-}
-
-/*
- * Make filenames more reasonable.
- */
-char *
-fetchname(char *at, int strip_leading, int assume_exists)
-{
- char *fullname;
- char *name;
- Reg1 char *t;
- char tmpbuf[200];
- int sleading = strip_leading;
-
- if (!at)
- return Nullch;
- while (isspace((unsigned char)*at))
- at++;
-#ifdef DEBUGGING
- if (debug & 128)
- say4("fetchname %s %d %d\n",at,strip_leading,assume_exists);
-#endif
- if (strnEQ(at, _PATH_DEVNULL, sizeof _PATH_DEVNULL - 1))
- /* So files can be created by diffing against /dev/null. */
- return Nullch;
- name = fullname = t = savestr(at);
-
- /* Strip off up to `sleading' leading slashes and null terminate. */
- for (; *t && !isspace((unsigned char)*t); t++)
- if (*t == '/')
- if (--sleading >= 0)
- name = t + 1;
- *t = '\0';
-
- /*
- * If no -p option was given (957 is the default value!),
- * we were given a relative pathname,
- * and the leading directories that we just stripped off all exist,
- * put them back on.
- */
- if (strip_leading == 957 && name != fullname && *fullname != '/') {
- name[-1] = '\0';
- if (stat(fullname, &filestat) == 0 &&
- S_ISDIR(filestat.st_mode)) {
- name[-1] = '/';
- name = fullname;
- }
- }
-
- name = savestr(name);
- free(fullname);
-
- if (stat(name, &filestat) && !assume_exists) {
- char *filebase = basename(name);
- int pathlen = filebase - name;
-
- /* Put any leading path into `tmpbuf'. */
- strncpy(tmpbuf, name, pathlen);
-
-#define try(f, a1, a2) \
- (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
- if (try("RCS/%s%s", filebase, RCSSUFFIX) ||
- try("RCS/%s%s", filebase, "") ||
- try( "%s%s", filebase, RCSSUFFIX) ||
- try("SCCS/%s%s", SCCSPREFIX, filebase) ||
- try( "%s%s", SCCSPREFIX, filebase))
- return name;
- free(name);
- name = Nullch;
- }
-
- return name;
-}
-
-char *
-xmalloc(unsigned int size)
-{
- register char *p = (char *) malloc (size);
- if (!p)
- fatal("out of memory");
- return p;
-}
diff --git a/gnu/usr.bin/patch/util.h b/gnu/usr.bin/patch/util.h
deleted file mode 100644
index f31f2e2..0000000
--- a/gnu/usr.bin/patch/util.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: util.h,v $
- * Revision 2.0 86/09/17 15:40:06 lwall
- * Baseline for netwide release.
- *
- */
-
-/* and for those machine that can't handle a variable argument list */
-
-#ifdef CANVARARG
-
-#define say1 say
-#define say2 say
-#define say3 say
-#define say4 say
-#define ask1 ask
-#define ask2 ask
-#define ask3 ask
-#define ask4 ask
-#define fatal1 fatal
-#define fatal2 fatal
-#define fatal3 fatal
-#define fatal4 fatal
-#define pfatal1 pfatal
-#define pfatal2 pfatal
-#define pfatal3 pfatal
-#define pfatal4 pfatal
-
-#else /* hope they allow multi-line macro actual arguments */
-
-#ifdef lint
-
-#define say1(a) say(a, 0, 0, 0)
-#define say2(a,b) say(a, (b)==(b), 0, 0)
-#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0)
-#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d))
-#define ask1(a) ask(a, 0, 0, 0)
-#define ask2(a,b) ask(a, (b)==(b), 0, 0)
-#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0)
-#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d))
-#define fatal1(a) fatal(a, 0, 0, 0)
-#define fatal2(a,b) fatal(a, (b)==(b), 0, 0)
-#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0)
-#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d))
-#define pfatal1(a) pfatal(a, 0, 0, 0)
-#define pfatal2(a,b) pfatal(a, (b)==(b), 0, 0)
-#define pfatal3(a,b,c) pfatal(a, (b)==(b), (c)==(c), 0)
-#define pfatal4(a,b,c,d) pfatal(a, (b)==(b), (c)==(c), (d)==(d))
-
-#else /* lint */
- /* if this doesn't work, try defining CANVARARG above */
-#define say1(a) say(a, Nullch, Nullch, Nullch)
-#define say2(a,b) say(a, b, Nullch, Nullch)
-#define say3(a,b,c) say(a, b, c, Nullch)
-#define say4 say
-#define ask1(a) ask(a, Nullch, Nullch, Nullch)
-#define ask2(a,b) ask(a, b, Nullch, Nullch)
-#define ask3(a,b,c) ask(a, b, c, Nullch)
-#define ask4 ask
-#define fatal1(a) fatal(a, Nullch, Nullch, Nullch)
-#define fatal2(a,b) fatal(a, b, Nullch, Nullch)
-#define fatal3(a,b,c) fatal(a, b, c, Nullch)
-#define fatal4 fatal
-#define pfatal1(a) pfatal(a, Nullch, Nullch, Nullch)
-#define pfatal2(a,b) pfatal(a, b, Nullch, Nullch)
-#define pfatal3(a,b,c) pfatal(a, b, c, Nullch)
-#define pfatal4 pfatal
-
-#endif /* lint */
-
-/* if neither of the above work, join all multi-line macro calls. */
-#endif
-
-EXT char serrbuf[BUFSIZ]; /* buffer for stderr */
-
-char *fetchname(char *_at, int _strip_leading, int _assume_exists);
-int move_file(char *_from, char *_to);
-void copy_file(char *_from, char *_to);
-void say(/*const char *pat, long _arg1, long _arg2, long _arg3*/);
-void fatal();
-void pfatal();
-int ask(/*const char *pat, long _arg1, long _arg2, long _arg3*/);
-char *savestr(char *_s);
-void set_signals(int _reset);
-void ignore_signals(void);
-void makedirs(/*char *_filename, bool _striplast*/);
-char *basename();
diff --git a/gnu/usr.bin/patch/version.c b/gnu/usr.bin/patch/version.c
deleted file mode 100644
index 753dbfb..0000000
--- a/gnu/usr.bin/patch/version.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: version.c,v $
- * Revision 2.0 86/09/17 15:40:11 lwall
- * Baseline for netwide release.
- *
- */
-
-#include "EXTERN.h"
-#include "common.h"
-#include "util.h"
-#include "INTERN.h"
-#include "patchlevel.h"
-#include "version.h"
-
-void my_exit(int _status); /* in patch.c */
-
-/* Print out the version number and die. */
-
-void
-version(void)
-{
- fprintf(stderr, "Patch version %s\n", PATCH_VERSION);
- my_exit(0);
-}
diff --git a/gnu/usr.bin/patch/version.h b/gnu/usr.bin/patch/version.h
deleted file mode 100644
index faddf7c..0000000
--- a/gnu/usr.bin/patch/version.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* $FreeBSD$
- *
- * $Log: version.h,v $
- * Revision 2.0 86/09/17 15:40:14 lwall
- * Baseline for netwide release.
- *
- */
-
-void version(void);
diff --git a/include/iconv.h b/include/iconv.h
index 3423a24..69cc2c7 100644
--- a/include/iconv.h
+++ b/include/iconv.h
@@ -35,7 +35,6 @@
#include <sys/cdefs.h>
#include <sys/types.h>
-#include <stdbool.h>
#include <wchar.h>
#include <sys/cdefs.h>
@@ -48,6 +47,13 @@
#define libiconv iconv
#define libiconv_t iconv_t
#endif
+#ifdef __cplusplus
+typedef bool __iconv_bool;
+#elif __STDC_VERSION__ >= 199901L
+typedef _Bool __iconv_bool;
+#else
+typedef int __iconv_bool;
+#endif
struct __tag_iconv_t;
typedef struct __tag_iconv_t *iconv_t;
@@ -61,7 +67,7 @@ int iconv_close(iconv_t);
/*
* non-portable interfaces for iconv
*/
-int __iconv_get_list(char ***, size_t *, bool);
+int __iconv_get_list(char ***, size_t *, __iconv_bool);
void __iconv_free_list(char **, size_t);
size_t __iconv(iconv_t, const char **, size_t *, char **,
size_t *, __uint32_t, size_t *);
diff --git a/lib/Makefile b/lib/Makefile
index 6e64925..feca8d3 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -72,6 +72,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
libdwarf \
libedit \
${_libefi} \
+ libexecinfo \
libexpat \
libfetch \
libgeom \
diff --git a/lib/libc++/Makefile b/lib/libc++/Makefile
index d540ca2..567144a 100644
--- a/lib/libc++/Makefile
+++ b/lib/libc++/Makefile
@@ -165,6 +165,7 @@ RT_HEADERS= cxxabi.h\
.for hdr in ${STD_HEADERS}
STD+= ${HDRDIR}/${hdr}
+INCSLINKS+= ${CXXINCLUDEDIR}/${hdr} ${CXXINCLUDEDIR}/tr1/${hdr}
.endfor
.for hdr in ${RT_HEADERS}
STD+= ${LIBCXXRTDIR}/${hdr}
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index cf2d2aa..2806cc7 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -100,6 +100,7 @@ NOASM=
CFLAGS+= -DYP
.include "${.CURDIR}/yp/Makefile.inc"
.endif
+.include "${.CURDIR}/capability/Makefile.inc"
.if ${MK_HESIOD} != "no"
CFLAGS+= -DHESIOD
.endif
diff --git a/lib/libc/capability/Makefile.inc b/lib/libc/capability/Makefile.inc
new file mode 100644
index 0000000..934fc8b
--- /dev/null
+++ b/lib/libc/capability/Makefile.inc
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+# capability sources
+.PATH: ${.CURDIR}/../../sys/kern
+
+SRCS+= subr_capability.c
+
+SYM_MAPS+= ${.CURDIR}/capability/Symbol.map
+
+#MAN+= cap_rights_init.3
+
+#MLINKS+=cap_rights_init.3 cap_rights_set.3
+#MLINKS+=cap_rights_init.3 cap_rights_clear.3
+#MLINKS+=cap_rights_init.3 cap_rights_is_set.3
+#MLINKS+=cap_rights_init.3 cap_rights_is_valid.3
+#MLINKS+=cap_rights_init.3 cap_rights_merge.3
+#MLINKS+=cap_rights_init.3 cap_rights_remove.3
+#MLINKS+=cap_rights_init.3 cap_rights_contains.3
+
diff --git a/lib/libc/capability/Symbol.map b/lib/libc/capability/Symbol.map
new file mode 100644
index 0000000..c5c18c2
--- /dev/null
+++ b/lib/libc/capability/Symbol.map
@@ -0,0 +1,14 @@
+/*
+ * $FreeBSD$
+ */
+
+FBSD_1.3 {
+ __cap_rights_clear;
+ cap_rights_contains;
+ __cap_rights_init;
+ __cap_rights_is_set;
+ cap_rights_is_valid;
+ cap_rights_merge;
+ cap_rights_remove;
+ __cap_rights_set;
+};
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
index a41d258..ea6df44 100644
--- a/lib/libc/gen/signal.3
+++ b/lib/libc/gen/signal.3
@@ -132,6 +132,7 @@ is possible on a descriptor (see
.It 30 Ta Dv SIGUSR1 Ta "terminate process" Ta "User defined signal 1"
.It 31 Ta Dv SIGUSR2 Ta "terminate process" Ta "User defined signal 2"
.It 32 Ta Dv SIGTHR Ta "terminate process" Ta "thread interrupt"
+.It 33 Ta Dv SIGLIBRT Ta "terminate process" Ta "real-time library interrupt"
.El
.Pp
The
diff --git a/lib/libc/iconv/citrus_iconv_local.h b/lib/libc/iconv/citrus_iconv_local.h
index 52ac825..e673c9a 100644
--- a/lib/libc/iconv/citrus_iconv_local.h
+++ b/lib/libc/iconv/citrus_iconv_local.h
@@ -31,6 +31,7 @@
#define _CITRUS_ICONV_LOCAL_H_
#include <iconv.h>
+#include <stdbool.h>
#define _CITRUS_ICONV_GETOPS_FUNC_BASE(_n_) \
int _n_(struct _citrus_iconv_ops *)
diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h
index 3739fe1..7694540 100644
--- a/lib/libc/include/compat.h
+++ b/lib/libc/include/compat.h
@@ -42,8 +42,6 @@ __sym_compat(__semctl, freebsd7___semctl, FBSD_1.0);
__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0);
__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0);
-__sym_compat(cap_getrights, cap_rights_get, FBSD_1.2);
-
#undef __sym_compat
#endif /* __LIBC_COMPAT_H__ */
diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c
index 1878c2f..b7552a4 100644
--- a/lib/libc/stdio/flags.c
+++ b/lib/libc/stdio/flags.c
@@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
int
__sflags(const char *mode, int *optr)
{
- int ret, m, o;
+ int ret, m, o, known;
switch (*mode++) {
@@ -78,34 +78,35 @@ __sflags(const char *mode, int *optr)
return (0);
}
- /* 'b' (binary) is ignored */
- if (*mode == 'b')
- mode++;
-
- /* [rwa][b]\+ means read and write */
- if (*mode == '+') {
- mode++;
- ret = __SRW;
- m = O_RDWR;
- }
-
- /* 'b' (binary) can appear here, too -- and is ignored again */
- if (*mode == 'b')
- mode++;
-
- /* 'x' means exclusive (fail if the file exists) */
- if (*mode == 'x') {
- mode++;
- if (m == O_RDONLY) {
- errno = EINVAL;
- return (0);
+ do {
+ known = 1;
+ switch (*mode++) {
+ case 'b':
+ /* 'b' (binary) is ignored */
+ break;
+ case '+':
+ /* [rwa][b]\+ means read and write */
+ ret = __SRW;
+ m = O_RDWR;
+ break;
+ case 'x':
+ /* 'x' means exclusive (fail if the file exists) */
+ o |= O_EXCL;
+ break;
+ case 'e':
+ /* set close-on-exec */
+ o |= O_CLOEXEC;
+ break;
+ default:
+ known = 0;
+ break;
}
- o |= O_EXCL;
- }
+ } while (known);
- /* set close-on-exec */
- if (*mode == 'e')
- o |= O_CLOEXEC;
+ if ((o & O_EXCL) != 0 && m == O_RDONLY) {
+ errno = EINVAL;
+ return (0);
+ }
*optr = m | o;
return (ret);
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c
index 64a5447..e018e6f 100644
--- a/lib/libc/stdlib/system.c
+++ b/lib/libc/stdlib/system.c
@@ -59,6 +59,8 @@ __system(const char *command)
(void)sigemptyset(&newsigblock);
(void)sigaddset(&newsigblock, SIGCHLD);
+ (void)sigaddset(&newsigblock, SIGINT);
+ (void)sigaddset(&newsigblock, SIGQUIT);
(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
switch(pid = vfork()) {
case -1: /* error */
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index 4f1104e..222f5f0 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -363,7 +363,6 @@ FBSD_1.1 {
FBSD_1.2 {
cap_enter;
cap_getmode;
- cap_new;
getloginclass;
pdfork;
pdgetpid;
@@ -385,7 +384,7 @@ FBSD_1.3 {
cap_fcntls_limit;
cap_ioctls_get;
cap_ioctls_limit;
- cap_rights_get;
+ __cap_rights_get;
cap_rights_limit;
cap_sandboxed;
chflagsat;
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
index d975ef9..5c784f6 100644
--- a/lib/libc/sys/sigaction.2
+++ b/lib/libc/sys/sigaction.2
@@ -28,7 +28,7 @@
.\" From: @(#)sigaction.2 8.2 (Berkeley) 4/3/94
.\" $FreeBSD$
.\"
-.Dd June 8, 2013
+.Dd September 6, 2013
.Dt SIGACTION 2
.Os
.Sh NAME
@@ -55,7 +55,7 @@ struct sigaction {
.Sh DESCRIPTION
The system defines a set of signals that may be delivered to a process.
Signal delivery resembles the occurrence of a hardware interrupt:
-the signal is normally blocked from further occurrence, the current process
+the signal is normally blocked from further occurrence, the current thread
context is saved, and a new one is built.
A process may specify a
.Em handler
@@ -64,13 +64,14 @@ to which a signal is delivered, or specify that a signal is to be
A process may also specify that a default action is to be taken
by the system when a signal occurs.
A signal may also be
-.Em blocked ,
-in which case its delivery is postponed until it is
+.Em blocked
+for a thread,
+in which case it will not be delivered to that thread until it is
.Em unblocked .
The action to be taken on delivery is determined at the time
of delivery.
Normally, signal handlers execute on the current stack
-of the process.
+of the thread.
This may be changed, on a per-handler basis,
so that signals are taken on a special
.Em "signal stack" .
@@ -82,20 +83,30 @@ but other signals may yet occur.
A global
.Em "signal mask"
defines the set of signals currently blocked from delivery
-to a process.
-The signal mask for a process is initialized
+to a thread.
+The signal mask for a thread is initialized
from that of its parent (normally empty).
It may be changed with a
.Xr sigprocmask 2
-call, or when a signal is delivered to the process.
+or
+.Xr pthread_sigmask 3
+call, or when a signal is delivered to the thread.
.Pp
When a signal
-condition arises for a process, the signal is added to a set of
-signals pending for the process.
-If the signal is not currently
+condition arises for a process or thread, the signal is added to a set of
+signals pending for the process or thread.
+Whether the signal is directed at the process in general or at a specific
+thread depends on how it is generated.
+For signals directed at a specific thread,
+if the signal is not currently
.Em blocked
-by the process then it is delivered to the process.
-Signals may be delivered any time a process enters the operating system
+by the thread then it is delivered to the thread.
+For signals directed at the process,
+if the signal is not currently
+.Em blocked
+by all threads then it is delivered to one thread that does not have it blocked
+(the selection of which is unspecified).
+Signals may be delivered any time a thread enters the operating system
(e.g., during a system call, page fault or trap, or clock interrupt).
If multiple signals are ready to be delivered at the same time,
any signals that could be caused by traps are delivered first.
@@ -106,17 +117,17 @@ The set of pending signals is returned by the
.Xr sigpending 2
system call.
When a caught signal
-is delivered, the current state of the process is saved,
+is delivered, the current state of the thread is saved,
a new signal mask is calculated (as described below),
and the signal handler is invoked.
The call to the handler
is arranged so that if the signal handling routine returns
-normally the process will resume execution in the context
+normally the thread will resume execution in the context
from before the signal's delivery.
-If the process wishes to resume in a different context, then it
+If the thread wishes to resume in a different context, then it
must arrange to restore the previous context itself.
.Pp
-When a signal is delivered to a process a new signal mask is
+When a signal is delivered to a thread a new signal mask is
installed for the duration of the process' signal handler
(or until a
.Xr sigprocmask 2
@@ -218,7 +229,7 @@ to
If this bit is set, the system will deliver the signal to the process
on a
.Em "signal stack" ,
-specified with
+specified by each thread with
.Xr sigaltstack 2 .
.It Dv SA_NODEFER
If this bit is set, further occurrences of the delivered signal are
@@ -272,6 +283,11 @@ However, calls that have already committed are not restarted,
but instead return a partial success (for example, a short read count).
.Pp
After a
+.Xr pthread_create 3
+the signal mask is inherited by the new thread and
+the set of pending signals and the signal stack for the new thread are empty.
+.Pp
+After a
.Xr fork 2
or
.Xr vfork 2
diff --git a/lib/libc/sys/sigpending.2 b/lib/libc/sys/sigpending.2
index 37f92d8..06ecc00 100644
--- a/lib/libc/sys/sigpending.2
+++ b/lib/libc/sys/sigpending.2
@@ -31,7 +31,7 @@
.\" @(#)sigpending.2 8.3 (Berkeley) 1/12/94
.\" $FreeBSD$
.\"
-.Dd January 12, 1994
+.Dd September 6, 2013
.Dt SIGPENDING 2
.Os
.Sh NAME
@@ -47,7 +47,7 @@
The
.Fn sigpending
system call returns a mask of the signals pending for delivery
-to the calling process in the location indicated by
+to the calling thread or the calling process in the location indicated by
.Fa set .
Signals may be pending because they are currently masked,
or transiently before delivery (although the latter case is not
diff --git a/lib/libc/sys/sigreturn.2 b/lib/libc/sys/sigreturn.2
index 13d76f6..1b76468 100644
--- a/lib/libc/sys/sigreturn.2
+++ b/lib/libc/sys/sigreturn.2
@@ -28,7 +28,7 @@
.\" @(#)sigreturn.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd September 6, 2013
.Dt SIGRETURN 2
.Os
.Sh NAME
@@ -46,7 +46,7 @@ The
system call
allows users to atomically unmask, switch stacks,
and return from a signal context.
-The processes signal mask and stack status are
+The thread's signal mask and stack status are
restored from the context structure pointed to by
.Fa scp .
The system call does not return;
@@ -65,7 +65,7 @@ is set to indicate the error.
The
.Fn sigreturn
system call
-will fail and the process context will remain unchanged
+will fail and the thread context will remain unchanged
if one of the following occurs.
.Bl -tag -width Er
.It Bq Er EFAULT
diff --git a/lib/libc/sys/sigwait.2 b/lib/libc/sys/sigwait.2
index 525bffb..4da64a9 100644
--- a/lib/libc/sys/sigwait.2
+++ b/lib/libc/sys/sigwait.2
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 27, 2012
+.Dd September 6, 2013
.Dt SIGWAIT 2
.Os
.Sh NAME
@@ -50,7 +50,7 @@ waits until one or more of the selected signals has been generated.
Then
.Fn sigwait
atomically clears one of the selected signals from the set of pending signals
-for the process and sets the location pointed to by
+(for the process or for the current thread) and sets the location pointed to by
.Fa sig
to the signal number that was cleared.
.Pp
diff --git a/lib/libexecinfo/Makefile b/lib/libexecinfo/Makefile
index 4b2778c..81fa82a 100644
--- a/lib/libexecinfo/Makefile
+++ b/lib/libexecinfo/Makefile
@@ -3,12 +3,16 @@
LIBEXECINFO= ${.CURDIR}/../../contrib/libexecinfo
LIB= execinfo
+SHLIB_MAJOR= 1
.PATH: ${LIBEXECINFO}
-INCS= execinfo.h symtab.h unwind.h
+INCS= execinfo.h
SRCS= backtrace.c symtab.c unwind.c
+DPADD= ${LIBELF}
+LDADD= -lelf
+
MAN= backtrace.3
MLINKS+= backtrace.3 backtrace_symbols.3
diff --git a/lib/libiconv_modules/Makefile.inc b/lib/libiconv_modules/Makefile.inc
index 9949390..3b25374 100644
--- a/lib/libiconv_modules/Makefile.inc
+++ b/lib/libiconv_modules/Makefile.inc
@@ -5,6 +5,9 @@
SHLIB_MAJOR= 4
WARNS?= 6
CFLAGS+= -I${.CURDIR}/../../libc/iconv
+
+CFLAGS+= -Dbool=_Bool
+
.if !defined(COMPAT_32BIT)
SHLIBDIR= /usr/lib/i18n
.else
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index dfb5ed3..9056151 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -378,7 +378,7 @@ procstat_freefiles(struct procstat *procstat, struct filestat_list *head)
static struct filestat *
filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags,
- int refcount, off_t offset, char *path, cap_rights_t cap_rights)
+ int refcount, off_t offset, char *path, cap_rights_t *cap_rightsp)
{
struct filestat *entry;
@@ -395,7 +395,7 @@ filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags,
entry->fs_ref_count = refcount;
entry->fs_offset = offset;
entry->fs_path = path;
- entry->fs_cap_rights = cap_rights;
+ entry->fs_cap_rights = *cap_rightsp;
return (entry);
}
@@ -851,7 +851,7 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp,
* Create filestat entry.
*/
entry = filestat_new_entry(kif, type, fd, fflags, uflags,
- refcount, offset, path, cap_rights);
+ refcount, offset, path, &cap_rights);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index 65a5eb9..7af6ccb 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -36,6 +36,7 @@
#ifndef ZFS
#include <sys/elf.h>
#endif
+#include <sys/caprights.h>
/*
* Vnode types.
diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
index 341bfb6..e40bc07 100644
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -697,7 +697,7 @@ ugen20_detach_kernel_driver(struct libusb20_device *pdev,
if (ioctl(pdev->file_ctrl, IOUSB(USB_IFACE_DRIVER_DETACH), &temp)) {
return (LIBUSB20_ERROR_OTHER);
}
- return (0); /* kernel driver is active */
+ return (0); /* kernel driver is detached */
}
static int
@@ -724,7 +724,7 @@ ugen20_do_request_sync(struct libusb20_device *pdev,
/* get actual length */
*pactlen = req.ucr_actlen;
}
- return (0); /* kernel driver is active */
+ return (0); /* request was successful */
}
static int
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index 14db97e..629d523 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -53,6 +53,7 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
e_pow.c e_powf.c e_rem_pio2.c \
e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c fenv.c \
+ imprecise.c \
k_cos.c k_cosf.c k_exp.c k_expf.c k_rem_pio2.c k_sin.c k_sinf.c \
k_tan.c k_tanf.c \
s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_carg.c s_cargf.c s_cargl.c \
diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map
index f244af4..5b75f08 100644
--- a/lib/msun/Symbol.map
+++ b/lib/msun/Symbol.map
@@ -270,4 +270,13 @@ FBSD_1.3 {
log1pl;
log2l;
logl;
+ # Implemented as weak aliases for imprecise versions
+ coshl;
+ erfcl;
+ erfl;
+ lgammal;
+ powl;
+ sinhl;
+ tanhl;
+ tgammal;
};
diff --git a/lib/msun/src/imprecise.c b/lib/msun/src/imprecise.c
new file mode 100644
index 0000000..a7503bf
--- /dev/null
+++ b/lib/msun/src/imprecise.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2013 David Chisnall
+ * 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 <float.h>
+#include <math.h>
+
+/*
+ * If long double is not the same size as double, then these will lose
+ * precision and we should emit a warning whenever something links against
+ * them.
+ */
+#if (LDBL_MANT_DIG > 53)
+#define WARN_IMPRECISE(x) \
+ __warn_references(x, # x " has lower than advertised precision");
+#else
+#define WARN_IMPRECISE(x)
+#endif
+/*
+ * Declare the functions as weak variants so that other libraries providing
+ * real versions can override them.
+ */
+#define DECLARE_WEAK(x)\
+ __weak_reference(imprecise_## x, x);\
+ WARN_IMPRECISE(x)
+
+long double
+imprecise_powl(long double x, long double y)
+{
+
+ return pow(x, y);
+}
+DECLARE_WEAK(powl);
+
+#define DECLARE_IMPRECISE(f) \
+ long double imprecise_ ## f ## l(long double v) { return f(v); }\
+ DECLARE_WEAK(f ## l)
+
+DECLARE_IMPRECISE(cosh);
+DECLARE_IMPRECISE(erfc);
+DECLARE_IMPRECISE(erf);
+DECLARE_IMPRECISE(lgamma);
+DECLARE_IMPRECISE(sinh);
+DECLARE_IMPRECISE(tanh);
+DECLARE_IMPRECISE(tgamma);
diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd
index 095a6ef..1bebc87 100755
--- a/release/picobsd/build/picobsd
+++ b/release/picobsd/build/picobsd
@@ -693,17 +693,22 @@ populate_mfs_tree() {
# rm $a # do not remove!
) || fail $? crunch
- if [ -f ${dst}/stand/sshd ] ; then
- log "Setting up host key for sshd:"
- if [ -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key.gz ] ; then
- log "Using existing host key"
+ log "Setting up host key for sshd:"
+ for K in rsa1 rsa dsa ; do
+ if [ $K = rsa1 ] ; then
+ i=ssh_host_key
else
- log "Generating new host key"
- ssh-keygen -t rsa1 -f ${BUILDDIR}/floppy.tree/etc/ssh_host_key \
- -N "" -C "root@picobsd"
- gzip -9 ${BUILDDIR}/floppy.tree/etc/ssh_host_key* || true
+ i=ssh_host_${K}_key
fi
- fi
+ if [ -f ${BUILDDIR}/floppy.tree/etc/$i.gz ] ; then
+ log "Using existing host key $i"
+ else
+ log "Generating new host key $i"
+ ssh-keygen -t $K -f ${BUILDDIR}/floppy.tree/etc/$i \
+ -N "" -C "root@picobsd"
+ gzip -9 ${BUILDDIR}/floppy.tree/etc/${i}* || true
+ fi
+ done
log "Copy generic and site-specific MFS tree..."
for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
@@ -880,9 +885,11 @@ fill_floppy_image() {
mkdir -p ${dst}/boot/kernel
# XXX loader.conf does not work unless we also load the .4th files
- echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf
- echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf
- cp -p /boot/loader ${dst}/boot/loader || fail $? no_space "copying bootloader"
+ # echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf
+ # echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf
+ local blf="loader* *.4th" # loader.rc loader.4th support.4th"
+ (cd /boot; cp -p loader ${dst}/boot) || fail $? no_space "copying bootloader"
+ cp ${MY_TREE}/floppy.tree/boot/loader.conf ${dst}/boot || true
gzip -c kernel > ${dst}/boot/kernel/kernel.gz || fail $? no_space "copying kernel"
# now transfer the floppy tree. If it is already in mfs, dont bother.
@@ -972,6 +979,8 @@ set_build_parameters() {
#-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m`
# export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers"
eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\""
+ [ "$BINMAKE" = "" ] && \
+ eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\""
fi
if [ "${o_init_src}" != "" ] ; then
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
index df0b3e7..6879568 100644
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -207,6 +207,19 @@
.Op Fl w
.Op Fl y
.Nm
+.Ic sanitize
+.Op device id
+.Op generic args
+.Aq Fl a Ar overwrite | block | crypto | exitfailure
+.Op Fl c Ar passes
+.Op Fl I
+.Op Fl P Ar pattern
+.Op Fl q
+.Op Fl U
+.Op Fl r
+.Op Fl w
+.Op Fl y
+.Nm
.Ic idle
.Op device id
.Op generic args
@@ -1088,6 +1101,116 @@ The user
will not be asked about the timeout if a timeout is specified on the
command line.
.El
+.It Ic sanitize
+Issue the
+.Tn SCSI
+SANITIZE command to the named device.
+.Pp
+.Em WARNING! WARNING! WARNING!
+.Pp
+ALL data in the cache and on the disk will be destroyed or made inaccessible.
+Recovery of the data is not possible.
+Use extreme caution when issuing this command.
+.Pp
+The
+.Sq sanitize
+subcommand takes several arguments that modify its default behavior.
+The
+.Fl q
+and
+.Fl y
+arguments can be useful for scripts.
+.Bl -tag -width 6n
+.It Fl a Ar operation
+Specify the sanitize operation to perform.
+.Bl -tag -width 16n
+.It overwrite
+Perform an overwrite operation by writing a user supplied
+data pattern to the device one or more times.
+The pattern is given by the
+.Fl P
+argument.
+The number of times is given by the
+.Fl c
+argument.
+.It block
+Perform a block erase operation.
+All the device's blocks are set to a vendor defined
+value, typically zero.
+.It crypto
+Perform a cryptographic erase operation.
+The encryption keys are changed to prevent the decryption
+of the data.
+.It exitfailure
+Exits a previously failed sanitize operation.
+A failed sanitize operation can only be exited if it was
+run in the unrestricted completion mode, as provided by the
+.Fl U
+argument.
+.El
+.It Fl c Ar passes
+The number of passes when performing an
+.Sq overwrite
+operation.
+Valid values are between 1 and 31. The default is 1.
+.It Fl I
+When performing an
+.Sq overwrite
+operation, the pattern is inverted between consecutive passes.
+.It Fl P Ar pattern
+Path to the file containing the pattern to use when
+performing an
+.Sq overwrite
+operation.
+The pattern is repeated as needed to fill each block.
+.It Fl q
+Be quiet, do not print any status messages.
+This option will not disable
+the questions, however.
+To disable questions, use the
+.Fl y
+argument, below.
+.It Fl U
+Perform the sanitize in the unrestricted completion mode.
+If the operation fails, it can later be exited with the
+.Sq exitfailure
+operation.
+.It Fl r
+Run in
+.Dq report only
+mode.
+This will report status on a sanitize that is already running on the drive.
+.It Fl w
+Issue a non-immediate sanitize command.
+By default,
+.Nm
+issues the SANITIZE command with the immediate bit set.
+This tells the
+device to immediately return the sanitize command, before
+the sanitize has actually completed.
+Then,
+.Nm
+gathers
+.Tn SCSI
+sense information from the device every second to determine how far along
+in the sanitize process it is.
+If the
+.Fl w
+argument is specified,
+.Nm
+will issue a non-immediate sanitize command, and will be unable to print any
+information to let the user know what percentage of the disk has been
+sanitized.
+.It Fl y
+Do not ask any questions.
+By default,
+.Nm
+will ask the user if he/she really wants to sanitize the disk in question,
+and also if the default sanitize command timeout is acceptable.
+The user
+will not be asked about the timeout if a timeout is specified on the
+command line.
+.El
.It Ic idle
Put ATA device into IDLE state. Optional parameter
.Pq Fl t
@@ -1300,6 +1423,8 @@ PLEXTOR
.It
QUANTUM
.It
+SAMSUNG
+.It
SEAGATE
.El
.Pp
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 76b3939..e80c549 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <sys/stdint.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/endian.h>
#include <sys/sbuf.h>
@@ -93,7 +94,8 @@ typedef enum {
CAM_CMD_SMP_MANINFO = 0x0000001b,
CAM_CMD_DOWNLOAD_FW = 0x0000001c,
CAM_CMD_SECURITY = 0x0000001d,
- CAM_CMD_HPA = 0x0000001e
+ CAM_CMD_HPA = 0x0000001e,
+ CAM_CMD_SANITIZE = 0x0000001f,
} cam_cmdmask;
typedef enum {
@@ -209,6 +211,7 @@ static struct camcontrol_opts option_table[] = {
{"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts},
{"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"},
{"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"},
+ {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"},
{"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"},
{"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"},
{"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""},
@@ -301,6 +304,8 @@ static int ratecontrol(struct cam_device *device, int retry_count,
int timeout, int argc, char **argv, char *combinedopt);
static int scsiformat(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout);
+static int scsisanitize(struct cam_device *device, int argc, char **argv,
+ char *combinedopt, int retry_count, int timeout);
static int scsireportluns(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout);
static int scsireadcapacity(struct cam_device *device, int argc, char **argv,
@@ -5537,6 +5542,402 @@ scsiformat_bailout:
}
static int
+scsisanitize(struct cam_device *device, int argc, char **argv,
+ char *combinedopt, int retry_count, int timeout)
+{
+ union ccb *ccb;
+ u_int8_t action = 0;
+ int c;
+ int ycount = 0, quiet = 0;
+ int error = 0, retval = 0;
+ int use_timeout = 10800 * 1000;
+ int immediate = 1;
+ int invert = 0;
+ int passes = 0;
+ int ause = 0;
+ int fd = -1;
+ const char *pattern = NULL;
+ u_int8_t *data_ptr = NULL;
+ u_int32_t dxfer_len = 0;
+ u_int8_t byte2 = 0;
+ int num_warnings = 0;
+ int reportonly = 0;
+
+ ccb = cam_getccb(device);
+
+ if (ccb == NULL) {
+ warnx("scsisanitize: error allocating ccb");
+ return(1);
+ }
+
+ bzero(&(&ccb->ccb_h)[1],
+ sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
+
+ while ((c = getopt(argc, argv, combinedopt)) != -1) {
+ switch(c) {
+ case 'a':
+ if (strcasecmp(optarg, "overwrite") == 0)
+ action = SSZ_SERVICE_ACTION_OVERWRITE;
+ else if (strcasecmp(optarg, "block") == 0)
+ action = SSZ_SERVICE_ACTION_BLOCK_ERASE;
+ else if (strcasecmp(optarg, "crypto") == 0)
+ action = SSZ_SERVICE_ACTION_CRYPTO_ERASE;
+ else if (strcasecmp(optarg, "exitfailure") == 0)
+ action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE;
+ else {
+ warnx("invalid service operation \"%s\"",
+ optarg);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ break;
+ case 'c':
+ passes = strtol(optarg, NULL, 0);
+ if (passes < 1 || passes > 31) {
+ warnx("invalid passes value %d", passes);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ break;
+ case 'I':
+ invert = 1;
+ break;
+ case 'P':
+ pattern = optarg;
+ break;
+ case 'q':
+ quiet++;
+ break;
+ case 'U':
+ ause = 1;
+ break;
+ case 'r':
+ reportonly = 1;
+ break;
+ case 'w':
+ immediate = 0;
+ break;
+ case 'y':
+ ycount++;
+ break;
+ }
+ }
+
+ if (reportonly)
+ goto doreport;
+
+ if (action == 0) {
+ warnx("an action is required");
+ error = 1;
+ goto scsisanitize_bailout;
+ } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) {
+ struct scsi_sanitize_parameter_list *pl;
+ struct stat sb;
+ ssize_t sz, amt;
+
+ if (pattern == NULL) {
+ warnx("overwrite action requires -P argument");
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ fd = open(pattern, O_RDONLY);
+ if (fd < 0) {
+ warn("cannot open pattern file %s", pattern);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ if (fstat(fd, &sb) < 0) {
+ warn("cannot stat pattern file %s", pattern);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ sz = sb.st_size;
+ if (sz > SSZPL_MAX_PATTERN_LENGTH) {
+ warnx("pattern file size exceeds maximum value %d",
+ SSZPL_MAX_PATTERN_LENGTH);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ dxfer_len = sizeof(*pl) + sz;
+ data_ptr = calloc(1, dxfer_len);
+ if (data_ptr == NULL) {
+ warnx("cannot allocate parameter list buffer");
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+
+ amt = read(fd, data_ptr + sizeof(*pl), sz);
+ if (amt < 0) {
+ warn("cannot read pattern file");
+ error = 1;
+ goto scsisanitize_bailout;
+ } else if (amt != sz) {
+ warnx("short pattern file read");
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+
+ pl = (struct scsi_sanitize_parameter_list *)data_ptr;
+ if (passes == 0)
+ pl->byte1 = 1;
+ else
+ pl->byte1 = passes;
+ if (invert != 0)
+ pl->byte1 |= SSZPL_INVERT;
+ scsi_ulto2b(sz, pl->length);
+ } else {
+ const char *arg;
+
+ if (passes != 0)
+ arg = "-c";
+ else if (invert != 0)
+ arg = "-I";
+ else if (pattern != NULL)
+ arg = "-P";
+ else
+ arg = NULL;
+ if (arg != NULL) {
+ warnx("%s argument only valid with overwrite "
+ "operation", arg);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ }
+
+ if (quiet == 0) {
+ fprintf(stdout, "You are about to REMOVE ALL DATA from the "
+ "following device:\n");
+
+ error = scsidoinquiry(device, argc, argv, combinedopt,
+ retry_count, timeout);
+
+ if (error != 0) {
+ warnx("scsisanitize: error sending inquiry");
+ goto scsisanitize_bailout;
+ }
+ }
+
+ if (ycount == 0) {
+ if (!get_confirmation()) {
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ }
+
+ if (timeout != 0)
+ use_timeout = timeout;
+
+ if (quiet == 0) {
+ fprintf(stdout, "Current sanitize timeout is %d seconds\n",
+ use_timeout / 1000);
+ }
+
+ /*
+ * If the user hasn't disabled questions and didn't specify a
+ * timeout on the command line, ask them if they want the current
+ * timeout.
+ */
+ if ((ycount == 0)
+ && (timeout == 0)) {
+ char str[1024];
+ int new_timeout = 0;
+
+ fprintf(stdout, "Enter new timeout in seconds or press\n"
+ "return to keep the current timeout [%d] ",
+ use_timeout / 1000);
+
+ if (fgets(str, sizeof(str), stdin) != NULL) {
+ if (str[0] != '\0')
+ new_timeout = atoi(str);
+ }
+
+ if (new_timeout != 0) {
+ use_timeout = new_timeout * 1000;
+ fprintf(stdout, "Using new timeout value %d\n",
+ use_timeout / 1000);
+ }
+ }
+
+ byte2 = action;
+ if (ause != 0)
+ byte2 |= SSZ_UNRESTRICTED_EXIT;
+ if (immediate != 0)
+ byte2 |= SSZ_IMMED;
+
+ scsi_sanitize(&ccb->csio,
+ /* retries */ retry_count,
+ /* cbfcnp */ NULL,
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
+ /* byte2 */ byte2,
+ /* control */ 0,
+ /* data_ptr */ data_ptr,
+ /* dxfer_len */ dxfer_len,
+ /* sense_len */ SSD_FULL_SIZE,
+ /* timeout */ use_timeout);
+
+ /* Disable freezing the device queue */
+ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
+
+ if (arglist & CAM_ARG_ERR_RECOVER)
+ ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
+
+ if (((retval = cam_send_ccb(device, ccb)) < 0)
+ || ((immediate == 0)
+ && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) {
+ const char errstr[] = "error sending sanitize command";
+
+ if (retval < 0)
+ warn(errstr);
+ else
+ warnx(errstr);
+
+ if (arglist & CAM_ARG_VERBOSE) {
+ cam_error_print(device, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+ }
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+
+ /*
+ * If we ran in non-immediate mode, we already checked for errors
+ * above and printed out any necessary information. If we're in
+ * immediate mode, we need to loop through and get status
+ * information periodically.
+ */
+ if (immediate == 0) {
+ if (quiet == 0) {
+ fprintf(stdout, "Sanitize Complete\n");
+ }
+ goto scsisanitize_bailout;
+ }
+
+doreport:
+ do {
+ cam_status status;
+
+ bzero(&(&ccb->ccb_h)[1],
+ sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
+
+ /*
+ * There's really no need to do error recovery or
+ * retries here, since we're just going to sit in a
+ * loop and wait for the device to finish sanitizing.
+ */
+ scsi_test_unit_ready(&ccb->csio,
+ /* retries */ 0,
+ /* cbfcnp */ NULL,
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
+ /* sense_len */ SSD_FULL_SIZE,
+ /* timeout */ 5000);
+
+ /* Disable freezing the device queue */
+ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
+
+ retval = cam_send_ccb(device, ccb);
+
+ /*
+ * If we get an error from the ioctl, bail out. SCSI
+ * errors are expected.
+ */
+ if (retval < 0) {
+ warn("error sending CAMIOCOMMAND ioctl");
+ if (arglist & CAM_ARG_VERBOSE) {
+ cam_error_print(device, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+ }
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+
+ status = ccb->ccb_h.status & CAM_STATUS_MASK;
+
+ if ((status != CAM_REQ_CMP)
+ && (status == CAM_SCSI_STATUS_ERROR)
+ && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) {
+ struct scsi_sense_data *sense;
+ int error_code, sense_key, asc, ascq;
+
+ sense = &ccb->csio.sense_data;
+ scsi_extract_sense_len(sense, ccb->csio.sense_len -
+ ccb->csio.sense_resid, &error_code, &sense_key,
+ &asc, &ascq, /*show_errors*/ 1);
+
+ /*
+ * According to the SCSI-3 spec, a drive that is in the
+ * middle of a sanitize should return NOT READY with an
+ * ASC of "logical unit not ready, sanitize in
+ * progress". The sense key specific bytes will then
+ * be a progress indicator.
+ */
+ if ((sense_key == SSD_KEY_NOT_READY)
+ && (asc == 0x04) && (ascq == 0x1b)) {
+ uint8_t sks[3];
+
+ if ((scsi_get_sks(sense, ccb->csio.sense_len -
+ ccb->csio.sense_resid, sks) == 0)
+ && (quiet == 0)) {
+ int val;
+ u_int64_t percentage;
+
+ val = scsi_2btoul(&sks[1]);
+ percentage = 10000 * val;
+
+ fprintf(stdout,
+ "\rSanitizing: %ju.%02u %% "
+ "(%d/%d) done",
+ (uintmax_t)(percentage /
+ (0x10000 * 100)),
+ (unsigned)((percentage /
+ 0x10000) % 100),
+ val, 0x10000);
+ fflush(stdout);
+ } else if ((quiet == 0)
+ && (++num_warnings <= 1)) {
+ warnx("Unexpected SCSI Sense Key "
+ "Specific value returned "
+ "during sanitize:");
+ scsi_sense_print(device, &ccb->csio,
+ stderr);
+ warnx("Unable to print status "
+ "information, but sanitze will "
+ "proceed.");
+ warnx("will exit when sanitize is "
+ "complete");
+ }
+ sleep(1);
+ } else {
+ warnx("Unexpected SCSI error during sanitize");
+ cam_error_print(device, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+
+ } else if (status != CAM_REQ_CMP) {
+ warnx("Unexpected CAM status %#x", status);
+ if (arglist & CAM_ARG_VERBOSE)
+ cam_error_print(device, ccb, CAM_ESF_ALL,
+ CAM_EPF_ALL, stderr);
+ error = 1;
+ goto scsisanitize_bailout;
+ }
+ } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP);
+
+ if (quiet == 0)
+ fprintf(stdout, "\nSanitize Complete\n");
+
+scsisanitize_bailout:
+ if (fd >= 0)
+ close(fd);
+ if (data_ptr != NULL)
+ free(data_ptr);
+ cam_freeccb(ccb);
+
+ return(error);
+}
+
+static int
scsireportluns(struct cam_device *device, int argc, char **argv,
char *combinedopt, int retry_count, int timeout)
{
@@ -7361,6 +7762,10 @@ usage(int printlong)
" [-q][-R syncrate][-v][-T <enable|disable>]\n"
" [-U][-W bus_width]\n"
" camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n"
+" camcontrol sanitize [dev_id][generic args]\n"
+" [-a overwrite|block|crypto|exitfailure]\n"
+" [-c passes][-I][-P pattern][-q][-U][-r][-w]\n"
+" [-y]\n"
" camcontrol idle [dev_id][generic args][-t time]\n"
" camcontrol standby [dev_id][generic args][-t time]\n"
" camcontrol sleep [dev_id][generic args]\n"
@@ -7403,6 +7808,7 @@ usage(int printlong)
"tags report or set the number of transaction slots for a device\n"
"negotiate report or set device negotiation parameters\n"
"format send the SCSI FORMAT UNIT command to the named device\n"
+"sanitize send the SCSI SANITIZE command to the named device\n"
"idle send the ATA IDLE command to the named device\n"
"standby send the ATA STANDBY command to the named device\n"
"sleep send the ATA SLEEP command to the named device\n"
@@ -7498,6 +7904,16 @@ usage(int printlong)
"-r run in report only mode\n"
"-w don't send immediate format command\n"
"-y don't ask any questions\n"
+"sanitize arguments:\n"
+"-a operation operation mode: overwrite, block, crypto or exitfailure\n"
+"-c passes overwrite passes to perform (1 to 31)\n"
+"-I invert overwrite pattern after each pass\n"
+"-P pattern path to overwrite pattern file\n"
+"-q be quiet, don't print status messages\n"
+"-r run in report only mode\n"
+"-U run operation in unrestricted completion exit mode\n"
+"-w don't send immediate sanitize command\n"
+"-y don't ask any questions\n"
"idle/standby arguments:\n"
"-t <arg> number of seconds before respective state.\n"
"fwdownload arguments:\n"
@@ -7860,6 +8276,10 @@ main(int argc, char **argv)
arglist & CAM_ARG_VERBOSE, retry_count, timeout,
get_disk_type(cam_dev));
break;
+ case CAM_CMD_SANITIZE:
+ error = scsisanitize(cam_dev, argc, argv,
+ combinedopt, retry_count, timeout);
+ break;
#endif /* MINIMALISTIC */
case CAM_CMD_USAGE:
usage(1);
diff --git a/sbin/camcontrol/fwdownload.c b/sbin/camcontrol/fwdownload.c
index 2fa9ba4..7e57d32 100644
--- a/sbin/camcontrol/fwdownload.c
+++ b/sbin/camcontrol/fwdownload.c
@@ -77,6 +77,7 @@ typedef enum {
VENDOR_PLEXTOR,
VENDOR_QUALSTAR,
VENDOR_QUANTUM,
+ VENDOR_SAMSUNG,
VENDOR_SEAGATE,
VENDOR_UNKNOWN
} fw_vendor_t;
@@ -98,6 +99,7 @@ static const struct fw_vendor vendors_list[] = {
{VENDOR_PLEXTOR, "PLEXTOR", 0x2000, 0x04, 0x05, 0, 1},
{VENDOR_QUALSTAR, "QUALSTAR", 0x2030, 0x05, 0x05, 0, 0},
{VENDOR_QUANTUM, "QUANTUM", 0x2000, 0x04, 0x05, 0, 1},
+ {VENDOR_SAMSUNG, "SAMSUNG", 0x8000, 0x07, 0x07, 0, 1},
{VENDOR_SEAGATE, "SEAGATE", 0x8000, 0x07, 0x07, 0, 1},
/* the next 2 are SATA disks going through SAS HBA */
{VENDOR_SEAGATE, "ATA ST", 0x8000, 0x07, 0x07, 0, 1},
diff --git a/sbin/dhclient/bpf.c b/sbin/dhclient/bpf.c
index f435028..c0a1720 100644
--- a/sbin/dhclient/bpf.c
+++ b/sbin/dhclient/bpf.c
@@ -43,6 +43,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/capability.h>
+
#include "dhcpd.h"
#include "privsep.h"
#include <sys/capability.h>
@@ -132,6 +134,7 @@ int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn);
void
if_register_send(struct interface_info *info)
{
+ cap_rights_t rights;
struct bpf_version v;
struct bpf_program p;
int sock, on = 1;
@@ -160,7 +163,8 @@ if_register_send(struct interface_info *info)
if (ioctl(info->wfdesc, BIOCLOCK, NULL) < 0)
error("Cannot lock bpf");
- if (cap_rights_limit(info->wfdesc, CAP_WRITE) < 0 && errno != ENOSYS)
+ cap_rights_init(&rights, CAP_WRITE);
+ if (cap_rights_limit(info->wfdesc, &rights) < 0 && errno != ENOSYS)
error("Can't limit bpf descriptor: %m");
/*
@@ -213,6 +217,7 @@ void
if_register_receive(struct interface_info *info)
{
static const unsigned long cmds[2] = { SIOCGIFFLAGS, SIOCGIFMEDIA };
+ cap_rights_t rights;
struct bpf_version v;
struct bpf_program p;
int flag = 1, sz;
@@ -264,10 +269,9 @@ if_register_receive(struct interface_info *info)
if (ioctl(info->rfdesc, BIOCLOCK, NULL) < 0)
error("Cannot lock bpf");
- if (cap_rights_limit(info->rfdesc,
- CAP_IOCTL | CAP_POLL_EVENT | CAP_READ) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_IOCTL, CAP_POLL_EVENT, CAP_READ);
+ if (cap_rights_limit(info->rfdesc, &rights) < 0 && errno != ENOSYS)
error("Can't limit bpf descriptor: %m");
- }
if (cap_ioctls_limit(info->rfdesc, cmds, 2) < 0 && errno != ENOSYS)
error("Can't limit ioctls for bpf descriptor: %m");
}
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index c8f05b5..e16e464 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -56,6 +56,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/capability.h>
+
#include "dhcpd.h"
#include "privsep.h"
@@ -346,6 +348,7 @@ main(int argc, char *argv[])
int immediate_daemon = 0;
struct passwd *pw;
pid_t otherpid;
+ cap_rights_t rights;
/* Initially, log errors to stderr as well as to syslogd. */
openlog(__progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY);
@@ -477,10 +480,9 @@ main(int argc, char *argv[])
close(pipe_fd[0]);
privfd = pipe_fd[1];
- if (cap_rights_limit(privfd, CAP_READ | CAP_WRITE) < 0 &&
- errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_READ, CAP_WRITE);
+ if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS)
error("can't limit private descriptor: %m");
- }
if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
error("can't open and lock %s: %m", path_dhclient_db);
@@ -492,10 +494,9 @@ main(int argc, char *argv[])
add_protocol("AF_ROUTE", routefd, routehandler, ifi);
if (shutdown(routefd, SHUT_WR) < 0)
error("can't shutdown route socket: %m");
- if (cap_rights_limit(routefd, CAP_POLL_EVENT | CAP_READ) < 0 &&
- errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_POLL_EVENT, CAP_READ);
+ if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
error("can't limit route socket: %m");
- }
if (chroot(_PATH_VAREMPTY) == -1)
error("chroot");
@@ -1840,13 +1841,15 @@ void
rewrite_client_leases(void)
{
struct client_lease *lp;
+ cap_rights_t rights;
if (!leaseFile) {
leaseFile = fopen(path_dhclient_db, "w");
if (!leaseFile)
error("can't create %s: %m", path_dhclient_db);
- if (cap_rights_limit(fileno(leaseFile), CAP_FSTAT | CAP_FSYNC |
- CAP_FTRUNCATE | CAP_SEEK | CAP_WRITE) < 0 &&
+ cap_rights_init(&rights, CAP_FSTAT, CAP_FSYNC, CAP_FTRUNCATE,
+ CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
errno != ENOSYS) {
error("can't limit lease descriptor: %m");
}
@@ -2354,6 +2357,7 @@ void
go_daemon(void)
{
static int state = 0;
+ cap_rights_t rights;
if (no_daemon || state)
return;
@@ -2366,9 +2370,11 @@ go_daemon(void)
if (daemon(1, 0) == -1)
error("daemon");
+ cap_rights_init(&rights);
+
if (pidfile != NULL) {
pidfile_write(pidfile);
- if (cap_rights_limit(pidfile_fileno(pidfile), CAP_NONE) < 0 &&
+ if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
errno != ENOSYS) {
error("can't limit pidfile descriptor: %m");
}
@@ -2383,11 +2389,12 @@ go_daemon(void)
nullfd = -1;
}
- if (cap_rights_limit(STDIN_FILENO, CAP_NONE) < 0 && errno != ENOSYS)
+ if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
error("can't limit stdin: %m");
- if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE) < 0 && errno != ENOSYS)
+ cap_rights_init(&rights, CAP_WRITE);
+ if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
error("can't limit stdout: %m");
- if (cap_rights_limit(STDERR_FILENO, CAP_WRITE) < 0 && errno != ENOSYS)
+ if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
error("can't limit stderr: %m");
}
diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c
index 440061e..0e9930b 100644
--- a/sbin/hastd/subr.c
+++ b/sbin/hastd/subr.c
@@ -231,6 +231,7 @@ drop_privs(const struct hast_resource *res)
pjdlog_common(LOG_DEBUG, 1, errno,
"Unable to sandbox using capsicum");
} else if (res != NULL) {
+ cap_rights_t rights;
static const unsigned long geomcmds[] = {
DIOCGDELETE,
DIOCGFLUSH
@@ -239,8 +240,9 @@ drop_privs(const struct hast_resource *res)
PJDLOG_ASSERT(res->hr_role == HAST_ROLE_PRIMARY ||
res->hr_role == HAST_ROLE_SECONDARY);
- if (cap_rights_limit(res->hr_localfd,
- CAP_FLOCK | CAP_IOCTL | CAP_PREAD | CAP_PWRITE) == -1) {
+ cap_rights_init(&rights, CAP_FLOCK, CAP_IOCTL, CAP_PREAD,
+ CAP_PWRITE);
+ if (cap_rights_limit(res->hr_localfd, &rights) == -1) {
pjdlog_errno(LOG_ERR,
"Unable to limit capability rights on local descriptor");
}
@@ -258,7 +260,8 @@ drop_privs(const struct hast_resource *res)
G_GATE_CMD_DESTROY
};
- if (cap_rights_limit(res->hr_ggatefd, CAP_IOCTL) == -1) {
+ cap_rights_init(&rights, CAP_IOCTL);
+ if (cap_rights_limit(res->hr_ggatefd, &rights) == -1) {
pjdlog_errno(LOG_ERR,
"Unable to limit capability rights to CAP_IOCTL on ggate descriptor");
}
diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c
index d93277c..bf621c1 100644
--- a/sbin/swapon/swapon.c
+++ b/sbin/swapon/swapon.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -83,16 +83,16 @@ main(int argc, char **argv)
struct fstab *fsp;
const char *swfile;
char *ptr;
- int ret;
- int ch, doall;
- int sflag = 0, lflag = 0, late = 0, hflag = 0;
+ int ret, ch, doall;
+ int sflag, lflag, late, hflag;
const char *etc_fstab;
+ sflag = lflag = late = hflag = 0;
if ((ptr = strrchr(argv[0], '/')) == NULL)
ptr = argv[0];
- if (strstr(ptr, "swapon"))
+ if (strstr(ptr, "swapon") != NULL)
which_prog = SWAPON;
- else if (strstr(ptr, "swapoff"))
+ else if (strstr(ptr, "swapoff") != NULL)
which_prog = SWAPOFF;
orig_prog = which_prog;
@@ -104,9 +104,8 @@ main(int argc, char **argv)
if (which_prog == SWAPCTL) {
doall = 1;
which_prog = SWAPON;
- } else {
+ } else
usage();
- }
break;
case 'a':
if (which_prog == SWAPON || which_prog == SWAPOFF)
@@ -149,9 +148,8 @@ main(int argc, char **argv)
if (which_prog == SWAPCTL) {
doall = 1;
which_prog = SWAPOFF;
- } else {
+ } else
usage();
- }
break;
case 'F':
etc_fstab = optarg;
@@ -170,13 +168,20 @@ main(int argc, char **argv)
if (which_prog == SWAPON || which_prog == SWAPOFF) {
if (doall) {
while ((fsp = getfsent()) != NULL) {
- if (strcmp(fsp->fs_type, FSTAB_SW))
+ if (strcmp(fsp->fs_type, FSTAB_SW) != 0)
continue;
- if (strstr(fsp->fs_mntops, "noauto"))
+ if (strstr(fsp->fs_mntops, "noauto") != NULL)
continue;
+ /*
+ * Forcibly enable "late" option when file= is
+ * specified. This is because mounting file
+ * systems with rw option is typically
+ * required to make the backing store ready.
+ */
if (which_prog != SWAPOFF &&
- strstr(fsp->fs_mntops, "late") &&
- !late)
+ (strstr(fsp->fs_mntops, "late") != NULL ||
+ strstr(fsp->fs_mntops, "file=") != NULL) &&
+ late == 0)
continue;
swfile = swap_on_off(fsp->fs_spec, 1,
fsp->fs_mntops);
@@ -184,15 +189,14 @@ main(int argc, char **argv)
ret = 1;
continue;
}
- if (!qflag) {
+ if (qflag == 0) {
printf("%s: %sing %s as swap device\n",
getprogname(),
(which_prog == SWAPOFF) ?
"remov" : "add", swfile);
}
}
- }
- else if (!*argv)
+ } else if (*argv == NULL)
usage();
for (; *argv; ++argv) {
swfile = swap_on_off(*argv, 0, NULL);
@@ -281,7 +285,7 @@ swap_on_off_gbde(const char *name, int doingall)
if (error) {
/* bde device found. Ignore it. */
free(dname);
- if (!qflag)
+ if (qflag == 0)
warnx("%s: Device already in use", name);
return (NULL);
}
@@ -301,7 +305,7 @@ swap_on_off_gbde(const char *name, int doingall)
free(dname);
if (error) {
/* bde device not found. Ignore it. */
- if (!qflag)
+ if (qflag == 0)
warnx("%s: Device not found", name);
return (NULL);
}
@@ -316,18 +320,16 @@ swap_on_geli_args(const char *mntops)
{
const char *aalgo, *ealgo, *keylen_str, *sectorsize_str;
const char *aflag, *eflag, *lflag, *sflag;
- char *p;
- char *args;
- char *token, *string, *ops;
+ char *p, *args, *token, *string, *ops;
int argsize, pagesize;
size_t pagesize_len;
u_long ul;
- /* Use built-in defaults for geli(8) */
+ /* Use built-in defaults for geli(8). */
aalgo = ealgo = keylen_str = "";
aflag = eflag = lflag = "";
- /* We will always specify sectorsize */
+ /* We will always specify sectorsize. */
sflag = " -s ";
sectorsize_str = NULL;
@@ -364,7 +366,8 @@ swap_on_geli_args(const char *mntops)
errno = EINVAL;
}
if (errno) {
- warn("Invalid sectorsize: %s", sectorsize_str);
+ warn("Invalid sectorsize: %s",
+ sectorsize_str);
free(ops);
return (NULL);
}
@@ -382,7 +385,7 @@ swap_on_geli_args(const char *mntops)
* pagesize as sector size.
*/
if (sectorsize_str == NULL) {
- /* Use pagesize as default sectorsize */
+ /* Use pagesize as default sectorsize. */
pagesize = getpagesize();
pagesize_len = snprintf(NULL, 0, "%d", pagesize) + 1;
p = alloca(pagesize_len);
@@ -401,15 +404,14 @@ swap_on_geli_args(const char *mntops)
static const char *
swap_on_off_geli(const char *name, char *mntops, int doingall)
{
- char *dname;
- char *args;
struct stat sb;
+ char *dname, *args;
int error;
error = stat(name, &sb);
if (which_prog == SWAPON) do {
- /* Skip if the .eli device already exists */
+ /* Skip if the .eli device already exists. */
if (error == 0)
break;
@@ -430,8 +432,8 @@ swap_on_off_geli(const char *name, char *mntops, int doingall)
free(args);
if (error) {
- /* error occured during creation */
- if (!qflag)
+ /* error occured during creation. */
+ if (qflag == 0)
warnx("%s: Invalid parameters", name);
return (NULL);
}
@@ -536,7 +538,7 @@ swap_on_off_md(const char *name, char *mntops, int doingall)
if (error == 0) {
/* md device found. Ignore it. */
close(fd);
- if (!qflag)
+ if (qflag == 0)
warnx("md%d on %s: Device already "
"in use", mdunit, vnodefile);
free(vnodefile);
@@ -719,13 +721,13 @@ swap_on_off_sfile(const char *name, int doingall)
if (error == -1) {
switch (errno) {
case EBUSY:
- if (!doingall)
+ if (doingall == 0)
warnx("%s: Device already in use", name);
break;
case EINVAL:
if (which_prog == SWAPON)
warnx("%s: NSWAPDEV limit reached", name);
- else if (!doingall)
+ else if (doingall == 0)
warn("%s", name);
break;
default:
@@ -740,6 +742,7 @@ swap_on_off_sfile(const char *name, int doingall)
static void
usage(void)
{
+
fprintf(stderr, "usage: %s ", getprogname());
switch(orig_prog) {
case SWAPON:
@@ -757,16 +760,14 @@ static void
sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen,
long blocksize)
{
+ char tmp[16];
if (hflag == 'H') {
- char tmp[16];
-
humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE,
HN_B | HN_NOSPACE | HN_DECIMAL);
snprintf(buf, bufsize, "%*s", hlen, tmp);
- } else {
+ } else
snprintf(buf, bufsize, "%*lld", hlen, val / blocksize);
- }
}
static void
@@ -785,32 +786,32 @@ swaplist(int lflag, int sflag, int hflag)
pagesize = getpagesize();
switch(hflag) {
case 'G':
- blocksize = 1024 * 1024 * 1024;
- strlcpy(buf, "1GB-blocks", sizeof(buf));
- hlen = 10;
- break;
+ blocksize = 1024 * 1024 * 1024;
+ strlcpy(buf, "1GB-blocks", sizeof(buf));
+ hlen = 10;
+ break;
case 'H':
- blocksize = -1;
- strlcpy(buf, "Bytes", sizeof(buf));
- hlen = 10;
- break;
+ blocksize = -1;
+ strlcpy(buf, "Bytes", sizeof(buf));
+ hlen = 10;
+ break;
case 'K':
- blocksize = 1024;
- strlcpy(buf, "1kB-blocks", sizeof(buf));
- hlen = 10;
- break;
+ blocksize = 1024;
+ strlcpy(buf, "1kB-blocks", sizeof(buf));
+ hlen = 10;
+ break;
case 'M':
- blocksize = 1024 * 1024;
- strlcpy(buf, "1MB-blocks", sizeof(buf));
- hlen = 10;
- break;
+ blocksize = 1024 * 1024;
+ strlcpy(buf, "1MB-blocks", sizeof(buf));
+ hlen = 10;
+ break;
default:
- getbsize(&hlen, &blocksize);
- snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
- break;
+ getbsize(&hlen, &blocksize);
+ snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
+ break;
}
- mibsize = sizeof mib / sizeof mib[0];
+ mibsize = nitems(mib);
if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
err(1, "sysctlnametomib()");
diff --git a/share/man/man4/capsicum.4 b/share/man/man4/capsicum.4
index 8f38dc4..84ddb91 100644
--- a/share/man/man4/capsicum.4
+++ b/share/man/man4/capsicum.4
@@ -100,7 +100,7 @@ associated with file descriptors; described in greater detail in
.Xr read 2 ,
.Xr shm_open 2 ,
.Xr write 2 ,
-.Xr procdesc 4 ,
+.Xr procdesc 4
.Sh HISTORY
.Nm
first appeared in
diff --git a/share/man/man4/netgraph.4 b/share/man/man4/netgraph.4
index ebd0aa5..6783973 100644
--- a/share/man/man4/netgraph.4
+++ b/share/man/man4/netgraph.4
@@ -1284,7 +1284,7 @@ link between two machines.
There is a full multilink PPP implementation that runs in
.Nm .
The
-.Pa net/mpd
+.Pa net/mpd5
port can use these modules to make a very low latency high
capacity PPP system.
It also supports
@@ -1423,6 +1423,7 @@ common networking problems, solved using
.Xr ng_bridge 4 ,
.Xr ng_bt3c 4 ,
.Xr ng_btsocket 4 ,
+.Xr ng_car 4 ,
.Xr ng_cisco 4 ,
.Xr ng_device 4 ,
.Xr ng_echo 4 ,
@@ -1439,13 +1440,16 @@ common networking problems, solved using
.Xr ng_hub 4 ,
.Xr ng_iface 4 ,
.Xr ng_ip_input 4 ,
+.Xr ng_ipfw 4 ,
.Xr ng_ksocket 4 ,
.Xr ng_l2cap 4 ,
.Xr ng_l2tp 4 ,
.Xr ng_lmi 4 ,
.Xr ng_mppc 4 ,
+.Xr ng_nat 4 ,
.Xr ng_netflow 4 ,
.Xr ng_one2many 4 ,
+.Xr ng_patch 4 ,
.Xr ng_ppp 4 ,
.Xr ng_pppoe 4 ,
.Xr ng_pptpgre 4 ,
diff --git a/share/man/man4/ntb.4 b/share/man/man4/ntb.4
index c576526..ac16c61 100644
--- a/share/man/man4/ntb.4
+++ b/share/man/man4/ntb.4
@@ -71,7 +71,7 @@ This needs to be done on both systems.
Each system needs to have a different IP address assigned.
The MAC address is randomly generated.
Also for maximum performance, the MTU should be set to 16 kiB.
-This can be down by adding the line below to
+This can be done by adding the line below to
.Xr rc.conf 5 :
.Bd -literal -offset indent
ifconfig_ntb0="inet 192.168.1.10 netmask 255.255.255.0 mtu 16384"
diff --git a/share/man/man4/procdesc.4 b/share/man/man4/procdesc.4
index f7477da..9bd3102 100644
--- a/share/man/man4/procdesc.4
+++ b/share/man/man4/procdesc.4
@@ -68,7 +68,7 @@ Given a process descriptor, it is possible to query its conventional PID using
.Xr pdfork 2 ,
.Xr pdgetpid 2 ,
.Xr pdkill 2 ,
-.Xr pdwait4 ,
+.Xr pdwait4 2 ,
.Xr capsicum 4
.Sh HISTORY
.Nm
diff --git a/share/man/man5/periodic.conf.5 b/share/man/man5/periodic.conf.5
index b7f42e8..b773c57 100644
--- a/share/man/man5/periodic.conf.5
+++ b/share/man/man5/periodic.conf.5
@@ -482,6 +482,242 @@ This variable behaves in the same way as the
.Va *_output
variables above, namely it can be set either to one or more email addresses
or to an absolute file name.
+.It Va daily_status_mail_rejects_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to summarise mail rejections logged to
+.Pa /var/log/maillog
+for the previous day.
+.It Va daily_status_mail_rejects_logs
+.Pq Vt num
+Set to the number of maillog files that should be checked
+for yesterday's mail rejects.
+.It Va daily_status_named_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to summarise denied zone transfers (AXFR and IXFR)
+for the previous day.
+.It Va daily_status_named_usedns
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to enable reverse DNS lookups.
+.It Va daily_status_ntpd
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to enable NTP status check.
+.It Va daily_queuerun_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to manually run the mail queue at least once a day.
+.It Va daily_submit_queuerun
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you also want to manually run the submit mail queue at least once a day
+when
+.Va daily_queuerun_enable
+is set to
+.Dq Li YES .
+.It Va daily_scrub_zfs_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to run a zfs scrub periodically.
+.It Va daily_scrub_zfs_pools
+.Pq Vt str
+A space separated list of names of zfs pools to scrub.
+If the list is empty or not set, all zfs pools are scrubbed.
+.It Va daily_scrub_zfs_default_threshold
+.Pq Vt int
+Number of days between a scrub if no pool-specific threshold is set.
+If not set, the default value is 35, corresponding to 5 weeks.
+.It Va daily_scrub_zfs_ Ns Ao Ar poolname Ac Ns Va _threshold
+.Pq Vt int
+The same as
+.Va daily_scrub_zfs_default_threshold
+but specific to the pool
+.Ao Ar poolname Ac Ns .
+.It Va daily_local
+.Pq Vt str
+Set to a list of extra scripts that should be run after all other
+daily scripts.
+All scripts must be absolute path names.
+.El
+.Pp
+The following variables are used by the standard scripts that reside in
+.Pa /etc/periodic/weekly :
+.Bl -tag -offset 4n -width 2n
+.It Va weekly_locate_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to run
+.Pa /usr/libexec/locate.updatedb .
+This script is run using
+.Nm nice Fl 5
+as user
+.Dq Li nobody ,
+and generates the table used by the
+.Xr locate 1
+command.
+.It Va weekly_whatis_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to run
+.Pa /usr/libexec/makewhatis.local .
+This script regenerates the database used by the
+.Xr apropos 1
+command.
+.It Va weekly_catman_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to run
+.Pa /usr/libexec/catman.local .
+This script processes all out of date manual pages, speeding up the
+.Xr man 1
+command at the expense of disk space.
+.It Va weekly_noid_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to locate orphaned files on the system.
+An orphaned file is one with an invalid owner or group.
+.It Va weekly_noid_dirs
+.Pq Vt str
+A list of directories under which orphaned files are searched for.
+This would usually be set to
+.Pa / .
+.It Va weekly_status_security_enable
+.Pq Vt bool
+Weekly counterpart of
+.Va daily_status_securiy_enable .
+.It Va weekly_status_security_inline
+.Pq Vt bool
+Weekly counterpart of
+.Va daily_status_securiy_inline .
+.It Va weekly_status_security_output
+.Pq Vt str
+Weekly counterpart of
+.Va daily_status_securiy_output .
+.It Va weekly_status_pkg_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to use
+.Xr pkg_version 1
+to list installed packages which are out of date.
+.It Va pkg_version
+.Pq Vt str
+When
+.Va weekly_status_pkg_enable
+is set to
+.Dq Li YES ,
+this variable specifies the program that is used to determine the out of
+date packages.
+If unset, the
+.Xr pkg_version 1
+program is used.
+As an example, this variable might be set to
+.Dq Li portversion
+if the
+.Pa ports/sysutils/portupgrade
+port has been installed.
+.It Va pkg_version_index
+.Pq Vt str
+This variable specifies the
+.Pa INDEX
+file from
+.Pa /usr/ports
+that should be used by
+.Xr pkg_version 1 .
+Because the dependency tree may be substantially different between versions of
+.Fx ,
+there may be more than one
+.Pa INDEX
+file in
+.Pa /usr/ports .
+.Pp
+Note, if the
+.Va pkg_version
+variable is set to
+.Dq Li portversion ,
+it will also be necessary to arrange that the correct
+.Pa INDEX
+file is specified
+using environment variables and that
+.Va pkg_version_index
+is cleared in
+.Pa /etc/periodic.conf
+.Pq Dq Li pkg_version_index= .
+.It Va weekly_local
+.Pq Vt str
+Set to a list of extra scripts that should be run after all other
+weekly scripts.
+All scripts must be absolute path names.
+.El
+.Pp
+The following variables are used by the standard scripts that reside in
+.Pa /etc/periodic/monthly :
+.Bl -tag -offset 4n -width 2n
+.It Va monthly_accounting_enable
+.Pq Vt bool
+Set to
+.Dq Li YES
+if you want to do login accounting using the
+.Xr ac 8
+command.
+.It Va monthly_status_security_enable
+.Pq Vt bool
+Monthly counterpart of
+.Va daily_status_securiy_enable .
+.It Va monthly_status_security_inline
+.Pq Vt bool
+Monthly counterpart of
+.Va daily_status_securiy_inline .
+.It Va monthly_status_security_output
+.Pq Vt str
+Monthly counterpart of
+.Va daily_status_securiy_output .
+.It Va monthly_local
+.Pq Vt str
+Set to a list of extra scripts that should be run after all other
+monthly scripts.
+All scripts must be absolute path names.
+.El
+.Pp
+The following variables are used by the standard scripts that reside in
+.Pa /etc/periodic/security .
+Those scripts are usually run from daily
+.Pq Va daily_status_security_enable ,
+weekly
+.Pq Va weekly_status_security_enable ,
+and monthly
+.Pq Va monthly_status_security_enable
+periodic hooks.
+The
+.Va ..._period
+of each script can be configured as
+.Dq daily ,
+.Dq weekly ,
+.Dq monthly
+or
+.Dq NO .
+Note that when periodic security scripts are run from
+.Xr crontab 5 ,
+they will be always run unless their
+.Va ..._enable
+or
+.Va ..._period
+variable is set to
+.Dq No .
+.Bl -tag -offset 4n -width 2n
.It Va security_status_diff_flags
.Pq Vt str
Set to the arguments to pass to the
@@ -709,214 +945,6 @@ Set to either
.Dq Li monthly
or
.Dq Li NO .
-.It Va daily_status_mail_rejects_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to summarise mail rejections logged to
-.Pa /var/log/maillog
-for the previous day.
-.It Va daily_status_mail_rejects_logs
-.Pq Vt num
-Set to the number of maillog files that should be checked
-for yesterday's mail rejects.
-.It Va daily_status_named_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to summarise denied zone transfers (AXFR and IXFR)
-for the previous day.
-.It Va daily_status_named_usedns
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to enable reverse DNS lookups.
-.It Va daily_status_ntpd
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to enable NTP status check.
-.It Va daily_queuerun_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to manually run the mail queue at least once a day.
-.It Va daily_submit_queuerun
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you also want to manually run the submit mail queue at least once a day
-when
-.Va daily_queuerun_enable
-is set to
-.Dq Li YES .
-.It Va daily_scrub_zfs_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to run a zfs scrub periodically.
-.It Va daily_scrub_zfs_pools
-.Pq Vt str
-A space separated list of names of zfs pools to scrub.
-If the list is empty or not set, all zfs pools are scrubbed.
-.It Va daily_scrub_zfs_default_threshold
-.Pq Vt int
-Number of days between a scrub if no pool-specific threshold is set.
-If not set, the default value is 35, corresponding to 5 weeks.
-.It Va daily_scrub_zfs_ Ns Ao Ar poolname Ac Ns Va _threshold
-.Pq Vt int
-The same as
-.Va daily_scrub_zfs_default_threshold
-but specific to the pool
-.Ao Ar poolname Ac Ns .
-.It Va daily_local
-.Pq Vt str
-Set to a list of extra scripts that should be run after all other
-daily scripts.
-All scripts must be absolute path names.
-.El
-.Pp
-The following variables are used by the standard scripts that reside in
-.Pa /etc/periodic/weekly :
-.Bl -tag -offset 4n -width 2n
-.It Va weekly_locate_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to run
-.Pa /usr/libexec/locate.updatedb .
-This script is run using
-.Nm nice Fl 5
-as user
-.Dq Li nobody ,
-and generates the table used by the
-.Xr locate 1
-command.
-.It Va weekly_whatis_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to run
-.Pa /usr/libexec/makewhatis.local .
-This script regenerates the database used by the
-.Xr apropos 1
-command.
-.It Va weekly_catman_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to run
-.Pa /usr/libexec/catman.local .
-This script processes all out of date manual pages, speeding up the
-.Xr man 1
-command at the expense of disk space.
-.It Va weekly_noid_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to locate orphaned files on the system.
-An orphaned file is one with an invalid owner or group.
-.It Va weekly_noid_dirs
-.Pq Vt str
-A list of directories under which orphaned files are searched for.
-This would usually be set to
-.Pa / .
-.It Va weekly_status_security_enable
-.Pq Vt bool
-Weekly counterpart of
-.Va daily_status_securiy_enable .
-.It Va weekly_status_security_inline
-.Pq Vt bool
-Weekly counterpart of
-.Va daily_status_securiy_inline .
-.It Va weekly_status_security_output
-.Pq Vt str
-Weekly counterpart of
-.Va daily_status_securiy_output .
-.It Va weekly_status_pkg_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to use
-.Xr pkg_version 1
-to list installed packages which are out of date.
-.It Va pkg_version
-.Pq Vt str
-When
-.Va weekly_status_pkg_enable
-is set to
-.Dq Li YES ,
-this variable specifies the program that is used to determine the out of
-date packages.
-If unset, the
-.Xr pkg_version 1
-program is used.
-As an example, this variable might be set to
-.Dq Li portversion
-if the
-.Pa ports/sysutils/portupgrade
-port has been installed.
-.It Va pkg_version_index
-.Pq Vt str
-This variable specifies the
-.Pa INDEX
-file from
-.Pa /usr/ports
-that should be used by
-.Xr pkg_version 1 .
-Because the dependency tree may be substantially different between versions of
-.Fx ,
-there may be more than one
-.Pa INDEX
-file in
-.Pa /usr/ports .
-.Pp
-Note, if the
-.Va pkg_version
-variable is set to
-.Dq Li portversion ,
-it will also be necessary to arrange that the correct
-.Pa INDEX
-file is specified
-using environment variables and that
-.Va pkg_version_index
-is cleared in
-.Pa /etc/periodic.conf
-.Pq Dq Li pkg_version_index= .
-.It Va weekly_local
-.Pq Vt str
-Set to a list of extra scripts that should be run after all other
-weekly scripts.
-All scripts must be absolute path names.
-.El
-.Pp
-The following variables are used by the standard scripts that reside in
-.Pa /etc/periodic/monthly :
-.Bl -tag -offset 4n -width 2n
-.It Va monthly_accounting_enable
-.Pq Vt bool
-Set to
-.Dq Li YES
-if you want to do login accounting using the
-.Xr ac 8
-command.
-.It Va monthly_status_security_enable
-.Pq Vt bool
-Monthly counterpart of
-.Va daily_status_securiy_enable .
-.It Va monthly_status_security_inline
-.Pq Vt bool
-Monthly counterpart of
-.Va daily_status_securiy_inline .
-.It Va monthly_status_security_output
-.Pq Vt str
-Monthly counterpart of
-.Va daily_status_securiy_output .
-.It Va monthly_local
-.Pq Vt str
-Set to a list of extra scripts that should be run after all other
-monthly scripts.
-All scripts must be absolute path names.
.El
.Sh FILES
.Bl -tag -width ".Pa /etc/defaults/periodic.conf"
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 893c8a7..e85c7ad 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1443,6 +1443,13 @@ MLINKS+=vfs_getopt.9 vfs_copyopt.9 \
MLINKS+=vhold.9 vdrop.9 \
vhold.9 vdropl.9 \
vhold.9 vholdl.9
+MLINKS+=vmem.9 vmem_add.9 \
+ vmem.9 vmem_alloc.9 \
+ vmem.9 vmem_create.9 \
+ vmem.9 vmem_destroy.9 \
+ vmem.9 vmem_free.9 \
+ vmem.9 vmem_xalloc.9 \
+ vmem.9 vmem_xfree.9
MLINKS+=vm_map_lock.9 vm_map_lock_downgrade.9 \
vm_map_lock.9 vm_map_lock_read.9 \
vm_map_lock.9 vm_map_lock_upgrade.9 \
diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot
index 16dd348..79831dc 100644
--- a/share/misc/committers-ports.dot
+++ b/share/misc/committers-ports.dot
@@ -103,6 +103,7 @@ gerald [label="Gerald Pfeifer\ngerald@FreeBSD.org\n2002/04/03"]
gjb [label="Glen Barber\ngjb@FreeBSD.org\n2012/06/19"]
glarkin [label="Greg Larkin\nglarkin@FreeBSD.org\n2008/07/17"]
glewis [label="Greg Lewis\nglewis@FreeBSD.org\n2002/04/08"]
+gnn [label="George Neville-Neil\ngnn@FreeBSD.org\n2013/09/04"]
hq [label="Herve Quiroz\nhq@FreeBSD.org\n2004/08/05"]
ijliao [label="Ying-Chieh Liao\nijliao@FreeBSD.org\n2001/01/20"]
itetcu [label="Ion-Mihai Tetcu\nitetcu@FreeBSD.org\n2006/06/07"]
@@ -491,6 +492,8 @@ sem -> stas
shaun -> timur
shaun -> matthew
+skreuzer -> gnn
+
sobomax -> demon
sobomax -> glewis
sobomax -> lev
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index e1e117e..a273cf9 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -117,6 +117,7 @@ bapt [label="Baptiste Daroussin\nbapt@FreeBSD.org\n2011/12/23"]
benl [label="Ben Laurie\nbenl@FreeBSD.org\n2011/05/18"]
benno [label="Benno Rice\nbenno@FreeBSD.org\n2000/11/02"]
bms [label="Bruce M Simpson\nbms@FreeBSD.org\n2003/08/06"]
+br [label="Ruslan Bukin\nbr@FreeBSD.org\n2013/09/02"]
brian [label="Brian Somers\nbrian@FreeBSD.org\n1996/12/16"]
brooks [label="Brooks Davis\nbrooks@FreeBSD.org\n2001/06/21"]
brucec [label="Bruce Cran\nbrucec@FreeBSD.org\n2010/01/29"]
@@ -289,6 +290,7 @@ wkoszek [label="Wojciech A. Koszek\nwkoszek@FreeBSD.org\n2006/02/21"]
wollman [label="Garrett Wollman\nwollman@FreeBSD.org\n????/??/??"]
wsalamon [label="Wayne Salamon\nwsalamon@FreeBSD.org\n2005/06/25"]
yongari [label="Pyun YongHyeon\nyongari@FreeBSD.org\n2004/08/01"]
+zbb [label="Zbigniew Bodek\nzbb@FreeBSD.org\n2013/09/02"]
zec [label="Marko Zec\nzec@FreeBSD.org\n2008/06/22"]
zml [label="Zachary Loafman\nzml@FreeBSD.org\n2009/05/27"]
zont [label="Andrey Zonov\nzont@FreeBSD.org\n2012/08/21"]
@@ -348,10 +350,12 @@ bz -> anchie
bz -> jamie
bz -> syrinx
+cognet -> br
cognet -> jceel
cognet -> kevlo
cognet -> ian
cognet -> wkoszek
+cognet -> zbb
cperciva -> eadler
cperciva -> flz
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index f78a656..accda1c 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -51,6 +51,7 @@ LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a
LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a
LIBEDIT?= ${DESTDIR}${LIBDIR}/libedit.a
LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a
+LIBEXECINFO?= ${DESTDIR}${LIBDIR}/libexecinfo.a
LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a
LIBFL?= "don't use LIBFL, use LIBL"
LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a
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/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 },
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..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);
@@ -728,6 +725,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 +1047,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 +1134,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 +1235,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 +1857,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 +1865,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 +1884,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 +1907,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);
@@ -4599,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);
}
@@ -4830,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:
*
@@ -4839,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));
@@ -4852,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));
}
/*
@@ -4920,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));
}
/*
@@ -5081,8 +5100,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) {
@@ -5094,7 +5113,6 @@ retry:
rw_wlock(lock);
if (pvh_gen != pvh->pv_gen) {
PMAP_UNLOCK(pmap);
- rw_wunlock(lock);
goto retry;
}
}
@@ -5149,7 +5167,6 @@ small_mappings:
if (pvh_gen != pvh->pv_gen ||
md_gen != m->md.pv_gen) {
PMAP_UNLOCK(pmap);
- rw_wunlock(lock);
goto retry;
}
}
@@ -5936,7 +5953,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 +5967,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..7253fe2 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/pioctl.h>
#include <sys/proc.h>
-#include <sys/sf_buf.h>
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
@@ -220,9 +219,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 *);
@@ -697,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/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/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/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 */
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/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);
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)
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/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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/frame.h> /* For trapframe_t, used in <machine/machdep.h> */
+#include <machine/machdep.h>
+#include <machine/pmap.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#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
+*/
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 <sys/time.h> /* struct timeval */
+#include <sys/caprights.h> /* 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/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);
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
diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c
index 2e51030..6917fff 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,
@@ -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");
diff --git a/sys/cddl/compat/opensolaris/sys/file.h b/sys/cddl/compat/opensolaris/sys/file.h
index 0b8f875..5f83082 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 <sys/capability.h>
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);
}
@@ -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/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 <sys/vdev_impl.h>
#include <sys/zio.h>
+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?
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/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);
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 <security/audit/audit.h>
-#include <compat/freebsd32/freebsd32_misc.h>
#include <compat/freebsd32/freebsd32_proto.h>
#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/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/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 9480771..2920581 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2848,6 +2848,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/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/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
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
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 <jmg@FreeBSD.org>
+ * 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 <wmmintrin.h>
+
+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 <kib@FreeBSD.org>
- * 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 <machine/asmacros.h>
-
- .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 <kib@FreeBSD.org>
- * 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 <machine/asmacros.h>
-
-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 <sys/bus.h>
#include <sys/uio.h>
#include <crypto/aesni/aesni.h>
-#include "cryptodev_if.h"
+#include <cryptodev_if.h>
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 <djm@mindrot.org>
* Copyright (c) 2010 Konstantin Belousov <kib@FreeBSD.org>
* Copyright (c) 2010-2011 Pawel Jakub Dawidek <pawel@dawidek.net>
+ * Copyright 2012-2013 John-Mark Gurney <jmg@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,13 +29,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-
+
#include <sys/param.h>
#include <sys/libkern.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <crypto/aesni/aesni.h>
+
+#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/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/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 <sys/param.h>
+#if __FreeBSD_version >= 900000
+#include <sys/capability.h>
+#endif
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
@@ -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/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/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index 541624f..9a6ae72 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/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 <dev/cfi/cfi_reg.h>
#include <dev/cfi/cfi_var.h>
+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;
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;
}
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/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);
}
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/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/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);
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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/pmc.h>
+#include <sys/pmckern.h>
+#include <sys/systm.h>
+
+#include <machine/pmc_mdep.h>
+#include <machine/spr.h>
+#include <machine/cpu.h>
+
+#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..25a32fa 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.
*
@@ -36,677 +36,50 @@ __FBSDID("$FreeBSD$");
#include <machine/pmc_mdep.h>
#include <machine/spr.h>
+#include <machine/pte.h>
+#include <machine/sr.h>
#include <machine/cpu.h>
+#include <machine/vmparam.h> /* 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))
+#define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \
+ ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS)
-/* 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.
- */
-
-/*
- * 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]);
+struct powerpc_cpu **powerpc_pcpu;
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,8 +88,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_MAX_PMCS,
- ("[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);
@@ -735,65 +106,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 +133,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..a9b54f4
--- /dev/null
+++ b/sys/dev/hwpmc/hwpmc_powerpc.h
@@ -0,0 +1,59 @@
+/*-
+ * 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 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/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/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c
index 55b19c5..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;
@@ -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()
@@ -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);
}
@@ -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);
}
@@ -405,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;
@@ -475,8 +480,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);
@@ -497,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]);
@@ -673,6 +681,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);
@@ -709,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);
@@ -988,9 +998,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 +1085,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 +1192,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..019f2a7 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];
@@ -145,26 +154,31 @@ 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))
-
-#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))
+ 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);
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);
@@ -178,17 +192,21 @@ 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);
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 }
};
/*
@@ -245,12 +263,13 @@ 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);
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 +292,122 @@ 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);
+ 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;
- 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,
- &current_bar->pci_resource_id, 0, ~0, 1,
- RF_ACTIVE);
+ return (0);
+}
- if (current_bar->pci_resource == NULL) {
- device_printf(ntb->device,
- "unable to allocate pci resource\n");
- return (ENXIO);
+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_any(ntb->device, SYS_RES_MEMORY,
+ &bar->pci_resource_id, 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;
+ uint8_t bar_size_bits = 0;
+
+ 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);
+ 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(NTB_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);
}
- 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));
+
+ /* 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);
@@ -361,9 +443,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),
@@ -393,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 =
@@ -413,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,
@@ -463,7 +546,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);
@@ -481,7 +564,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));
@@ -501,7 +584,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
@@ -513,7 +596,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);
@@ -521,7 +604,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);
@@ -634,10 +717,15 @@ 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_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_reg_write(4, ntb->reg_ofs.lnk_cntl,
+ NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP);
+
return (0);
}
@@ -698,49 +786,63 @@ 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_read_8(SOC_PBAR2XLAT_OFFSET) == 0)
- ntb_write_8(SOC_PBAR2XLAT_OFFSET,
- SOC_PBAR2XLAT_USD_ADDR);
-
- if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0)
- ntb_write_8(SOC_PBAR4XLAT_OFFSET,
- SOC_PBAR4XLAT_USD_ADDR);
+ configure_soc_secondary_side_bars(ntb);
- if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC)
- ntb_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);
- } else {
- if (ntb_read_8(SOC_PBAR2XLAT_OFFSET) == 0)
- ntb_write_8(SOC_PBAR2XLAT_OFFSET,
- SOC_PBAR2XLAT_DSD_ADDR);
+ /* 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);
+ callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb);
- if (ntb_read_8(SOC_PBAR4XLAT_OFFSET) == 0)
- ntb_write_8(SOC_PBAR4XLAT_OFFSET,
- SOC_PBAR4XLAT_DSD_ADDR);
+ return (0);
+}
- if (ntb_read_8(SOC_MBAR23_OFFSET) == 0xC)
- ntb_write_8(SOC_MBAR23_OFFSET, SOC_MBAR23_DSD_ADDR);
+static void
+configure_soc_secondary_side_bars(struct ntb_softc *ntb)
+{
- if (ntb_read_8(SOC_MBAR45_OFFSET) == 0xC)
- ntb_write_8(SOC_MBAR45_OFFSET, SOC_MBAR45_DSD_ADDR);
+ 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);
}
+}
- /* Enable Bus Master and Memory Space on the secondary side */
- ntb_write_2(ntb->reg_ofs.spci_cmd,
- PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
- callout_reset(&ntb->heartbeat_timer, 0, ntb_handle_heartbeat, ntb);
+static void
+configure_xeon_secondary_side_bars(struct ntb_softc *ntb)
+{
- return (0);
+ 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 */
+/* SOC does not have link status interrupt, poll on that platform */
static void
ntb_handle_heartbeat(void *arg)
{
@@ -753,7 +855,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);
@@ -771,37 +873,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
@@ -819,7 +921,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);
@@ -833,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 */
@@ -852,15 +954,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)
@@ -883,7 +985,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
@@ -965,9 +1067,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);
}
@@ -988,9 +1090,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;
}
@@ -1091,7 +1193,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);
}
@@ -1114,7 +1216,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);
}
@@ -1137,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_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);
}
@@ -1160,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_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);
}
@@ -1233,10 +1341,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;
}
}
@@ -1256,11 +1364,16 @@ 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,
- ((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));
}
/**
@@ -1278,11 +1391,24 @@ 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)
+{
+
+ 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_ */
diff --git a/sys/dev/ntb/ntb_hw/ntb_regs.h b/sys/dev/ntb/ntb_hw/ntb_regs.h
index 34ad779..bd55a59 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,13 +114,15 @@
#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)
#define SOC_CNTL_LINK_DOWN (1 << 16)
-#define NTB_PPD_OFFSET 0x00D4
+#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
#define SOC_PPD_INIT_LINK 0x0008
@@ -134,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_ */
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/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..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
@@ -1776,6 +1777,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
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),
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index f757394..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;
@@ -1531,7 +1534,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
@@ -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;
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;
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index 33f6faf..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;
@@ -1239,6 +1232,8 @@ 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));
@@ -1608,7 +1603,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;
@@ -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));
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index f18c0fc..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. */
@@ -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_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();
+ }
}
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/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/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/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,
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)
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/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 <machine/specialreg.h>
#include <machine/pcpu.h>
-
-
#include <xen/xen-os.h>
#include <xen/evtchn.h>
#include <xen/xen_intr.h>
#include <xen/hypervisor.h>
#include <xen/interface/vcpu.h>
+/*---------------------------- 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);
-
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 <sys/vmmeter.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
-#include <sys/sf_buf.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
@@ -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/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/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/kern_descrip.c b/sys/kern/kern_descrip.c
index d0de6b9..9e9010f 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);
+ 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) {
@@ -670,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;
@@ -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) {
@@ -726,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) {
@@ -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,14 +2323,16 @@ 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);
- if (error != 0)
- return (error);
- if ((needrights & CAP_FCNTL) != 0) {
- error = cap_fcntl_check(fdp, fd, needfcntl);
+ haverights = *cap_rights(fdp, fd);
+ 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;
@@ -2338,7 +2353,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 +2374,23 @@ 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);
+ if (needrightsp != NULL)
+ needrights = *needrightsp;
+ else
+ cap_rights_init(&needrights);
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 +2403,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 +2440,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 +2476,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 +2498,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,9 +2522,11 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t need,
return (EBADF);
#ifdef CAPABILITIES
- error = cap_check(cap_rights(fdp, fd), need);
- 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)
@@ -2519,26 +2540,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 +2575,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 +2584,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 +2658,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 +3208,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 +3282,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 +3328,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 +3355,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 +3372,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 +3469,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_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);
/*
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_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.
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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifdef _KERNEL
+#include <sys/types.h>
+#include <sys/capability.h>
+#include <sys/systm.h>
+
+#include <machine/stdarg.h>
+#else /* !_KERNEL */
+#include <sys/types.h>
+#include <sys/capability.h>
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#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/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);
}
diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c
index 224042e..7a82017 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..d4d6293 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,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;
@@ -1373,7 +1387,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 +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);
@@ -1445,7 +1463,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.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/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/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/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_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_mqueue.c b/sys/kern/uipc_mqueue.c
index 62c54d3..fe7e886 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,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;
@@ -2269,7 +2281,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_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/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 72663a2..8229390 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) {
@@ -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);
@@ -267,12 +267,14 @@ 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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, fd,
+ cap_rights_init(&rights, CAP_BIND), &fp, NULL);
+ if (error != 0)
return (error);
so = fp->f_data;
#ifdef KTRACE
@@ -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
@@ -370,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);
@@ -379,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);
}
@@ -395,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);
@@ -416,20 +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_ACCEPT, &headfp, &fflag);
- if (error)
+ error = getsock_cap(fdp, s, cap_rights_init(&rights, CAP_ACCEPT),
+ &headfp, &fflag);
+ if (error != 0)
return (error);
head = headfp->f_data;
if ((head->so_options & SO_ACCEPTCONN) == 0) {
@@ -442,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)) {
@@ -457,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;
}
@@ -516,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.
@@ -543,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);
/*
@@ -585,6 +588,7 @@ sys_accept4(td, uap)
struct thread *td;
struct accept4_args *uap;
{
+
if (uap->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
return (EINVAL);
@@ -629,13 +633,14 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa)
{
struct socket *so;
struct file *fp;
- int error;
- int interrupted = 0;
+ cap_rights_t rights;
+ int error, 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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, fd,
+ cap_rights_init(&rights, CAP_CONNECT), &fp, NULL);
+ if (error != 0)
return (error);
so = fp->f_data;
if (so->so_state & SS_ISCONNECTING) {
@@ -648,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;
@@ -665,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;
@@ -740,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,
@@ -804,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]);
}
@@ -832,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;
}
@@ -852,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) {
@@ -872,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);
}
@@ -890,21 +894,21 @@ 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);
- 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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, s, &rights, &fp, NULL);
+ if (error != 0)
return (error);
so = (struct socket *)fp->f_data;
@@ -916,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
@@ -944,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;
@@ -983,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;
@@ -995,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
@@ -1012,7 +1014,6 @@ osend(td, uap)
{
struct msghdr msg;
struct iovec aiov;
- int error;
msg.msg_name = 0;
msg.msg_namelen = 0;
@@ -1022,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
@@ -1040,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;
@@ -1067,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
@@ -1091,30 +1091,31 @@ 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;
struct socket *so;
struct sockaddr *fromsa = NULL;
+ cap_rights_t rights;
#ifdef KTRACE
struct uio *ktruio = NULL;
#endif
+ ssize_t len;
+ int error, i;
if (controlp != NULL)
*controlp = NULL;
AUDIT_ARG_FD(s);
- error = getsock_cap(td->td_proc->p_fd, s, CAP_RECV, &fp, NULL);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, s,
+ cap_rights_init(&rights, CAP_RECV), &fp, NULL);
+ 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);
}
@@ -1142,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;
@@ -1155,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) {
@@ -1173,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);
@@ -1232,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;
@@ -1253,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)
@@ -1284,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;
@@ -1298,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
@@ -1326,7 +1326,6 @@ orecv(td, uap)
{
struct msghdr msg;
struct iovec aiov;
- int error;
msg.msg_name = 0;
msg.msg_namelen = 0;
@@ -1336,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));
}
/*
@@ -1359,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;
@@ -1389,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
@@ -1420,11 +1418,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);
@@ -1460,10 +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);
@@ -1487,7 +1487,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);
@@ -1509,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);
}
@@ -1539,10 +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;
@@ -1566,7 +1568,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);
@@ -1595,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) {
@@ -1621,19 +1624,21 @@ 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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, fd,
+ cap_rights_init(&rights, CAP_GETSOCKNAME), &fp, NULL);
+ 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;
@@ -1646,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;
}
@@ -1692,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) {
@@ -1718,12 +1723,14 @@ 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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, fd,
+ cap_rights_init(&rights, CAP_GETPEERNAME), &fp, NULL);
+ if (error != 0)
return (error);
so = fp->f_data;
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
@@ -1734,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;
@@ -1746,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;
}
@@ -1798,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;
@@ -1830,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
@@ -1907,6 +1914,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)
@@ -1916,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;
}
@@ -1937,18 +1945,18 @@ 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);
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);
}
@@ -1983,10 +1991,10 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
struct sf_buf *sf;
struct vm_page *pg;
struct vattr va;
- off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0;
- int error, hdrlen = 0, mnw = 0;
- int bsize;
struct sendfile_sync *sfs = NULL;
+ cap_rights_t rights;
+ off_t off, xfsize, fsbytes = 0, sbytes = 0, rem = 0;
+ int bsize, error, hdrlen = 0, mnw = 0;
vn_lock(vp, LK_SHARED | LK_RETRY);
if (vp->v_type == VREG) {
@@ -2030,8 +2038,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) {
@@ -2058,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
@@ -2173,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;
}
@@ -2265,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);
/*
@@ -2393,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;
}
@@ -2460,21 +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_PEELOFF, &head, &fflag);
- if (error)
+ error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF),
+ &head, &fflag);
+ 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
@@ -2483,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;
@@ -2513,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);
@@ -2523,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);
/*
@@ -2558,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;
@@ -2566,27 +2575,28 @@ 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;
}
- rights = CAP_SEND;
- if (uap->tolen) {
+ cap_rights_init(&rights, CAP_SEND);
+ if (uap->tolen != 0) {
error = getsockaddr(&to, uap->to, uap->tolen);
- if (error) {
+ if (error != 0) {
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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
+ if (error != 0)
goto sctp_bad;
#ifdef KTRACE
if (to && (KTRPOINT(td, KTR_STRUCT)))
@@ -2603,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 */
@@ -2616,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;
@@ -2641,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);
@@ -2669,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;
@@ -2678,26 +2684,28 @@ 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;
}
- rights = CAP_SEND;
- if (uap->tolen) {
+ cap_rights_init(&rights, CAP_SEND);
+ if (uap->tolen != 0) {
error = getsockaddr(&to, uap->to, uap->tolen);
- if (error) {
+ if (error != 0) {
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);
- if (error)
+ error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
+ if (error != 0)
goto sctp_bad1;
#ifdef COMPAT_FREEBSD32
@@ -2707,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)))
@@ -2721,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 */
@@ -2745,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;
@@ -2768,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);
@@ -2800,19 +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_RECV, &fp, NULL);
- if (error) {
+ error = getsock_cap(td->td_proc->p_fd, uap->sd,
+ cap_rights_init(&rights, CAP_RECV), &fp, NULL);
+ if (error != 0)
return (error);
- }
#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32))
error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
@@ -2820,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;
@@ -2830,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;
}
@@ -2879,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;
@@ -2893,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;
@@ -2904,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))
@@ -2918,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);
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..7f9f881 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;
@@ -2047,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);
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]);
}
/*
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_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/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 2877ad2..4b82df8 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));
@@ -367,11 +367,13 @@ 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);
- if (error)
+ error = getvnode(td->td_proc->p_fd, fd,
+ cap_rights_init(&rights, CAP_FSTATFS), &fp);
+ if (error != 0)
return (error);
vp = fp->f_vnode;
vn_lock(vp, LK_SHARED | LK_RETRY);
@@ -389,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
/*
@@ -404,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));
@@ -523,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);
}
@@ -568,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)));
@@ -596,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)));
@@ -667,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)));
@@ -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);
@@ -746,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);
}
@@ -787,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);
@@ -866,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);
@@ -904,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));
}
/*
@@ -937,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);
}
@@ -954,42 +962,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);
}
/*
@@ -1048,15 +1053,17 @@ 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_needed = CAP_LOOKUP;
+ cap_rights_t rights;
+ int cmode, error, indx;
+
+ indx = -1;
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.
@@ -1074,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
@@ -1082,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_needed, td);
+ &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
@@ -1131,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:
@@ -1255,9 +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);
@@ -1280,12 +1287,12 @@ 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();
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;
@@ -1333,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 {
@@ -1398,14 +1405,15 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
{
struct mount *mp;
struct vattr vattr;
- int error;
struct nameidata nd;
+ cap_rights_t rights;
+ int error;
AUDIT_ARG_MODE(mode);
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) {
@@ -1430,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);
@@ -1514,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);
}
@@ -1541,6 +1549,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 +1568,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)
@@ -1638,8 +1647,9 @@ 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) {
syspath = path1;
@@ -1652,7 +1662,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) {
@@ -1678,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);
@@ -1706,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)) {
@@ -1797,14 +1807,15 @@ 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();
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;
@@ -1839,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);
@@ -1880,10 +1891,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;
@@ -1949,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;
@@ -1964,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)
@@ -2026,6 +2039,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 +2056,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;
@@ -2109,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)));
}
/*
@@ -2138,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)));
}
/*
@@ -2244,6 +2257,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,12 +2265,12 @@ 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);
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);
@@ -2265,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
@@ -2317,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;
@@ -2355,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)));
}
/*
@@ -2384,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)));
}
/*
@@ -2508,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);
@@ -2523,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);
}
@@ -2556,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)
@@ -2572,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);
}
@@ -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);
@@ -2722,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);
@@ -2817,14 +2833,14 @@ 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;
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 +2862,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);
@@ -2870,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);
@@ -2949,12 +2966,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 +3034,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);
@@ -3073,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);
@@ -3155,12 +3174,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);
@@ -3197,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);
@@ -3238,12 +3258,16 @@ 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)
+ error = getutimes(tptr, tptrseg, ts);
+ if (error != 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,13 +3414,17 @@ 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)
+ 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))) {
@@ -3472,15 +3500,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 +3532,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 +3562,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;
}
@@ -3554,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);
@@ -3630,14 +3661,15 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg,
struct mount *mp;
struct vnode *vp;
struct vattr vattr;
- int error;
struct nameidata nd;
+ cap_rights_t rights;
+ int error;
AUDIT_ARG_MODE(mode);
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);
@@ -3669,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);
@@ -3678,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);
@@ -3715,13 +3747,14 @@ kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg)
{
struct mount *mp;
struct vnode *vp;
- int error;
struct nameidata nd;
+ cap_rights_t rights;
+ int error;
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;
@@ -3746,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) {
@@ -3806,6 +3839,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 +3848,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);
@@ -3840,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);
@@ -3898,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);
@@ -3952,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));
@@ -3967,6 +4003,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 +4012,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);
@@ -4005,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;
}
@@ -4013,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;
@@ -4049,6 +4089,7 @@ sys_getdents(td, uap)
} */ *uap;
{
struct getdirentries_args ap;
+
ap.fd = uap->fd;
ap.buf = uap->buf;
ap.count = uap->count;
@@ -4099,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);
@@ -4114,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)
@@ -4138,12 +4179,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);
@@ -4188,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;
@@ -4201,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);
}
@@ -4224,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;
@@ -4237,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);
}
@@ -4272,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);
@@ -4280,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);
@@ -4289,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);
}
@@ -4306,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,
@@ -4323,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;
}
@@ -4361,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);
}
@@ -4375,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);
@@ -4410,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)));
}
@@ -4427,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
/*
@@ -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/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.
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"
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)
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/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/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);
}
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 <sys/user.h>
#include <sys/mbuf.h>
+#ifndef __mips_n64
#include <sys/sf_buf.h>
+#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.
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 <bsd.kmod.mk>
+
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/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/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 <bsd.kmod.mk>
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) },
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;
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 23f1be7..3a03def 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();
@@ -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);
}
@@ -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;
+ u_long 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);
}
@@ -759,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);
}
}
@@ -803,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
@@ -1439,7 +1433,7 @@ non_fatal:
static void
expire_upcalls(void *arg)
{
- int i;
+ u_long i;
CURVNET_SET((struct vnet *) arg);
@@ -1451,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;
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 <netinet/sctp_os.h>
/* 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_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_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 <netinet/ip_options.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2/sha2.h>
+
#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 <netinet/sctp_sha1.h>
-#else
-#include <crypto/sha1.h>
/* 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 <crypto/sha2/sha2.h>
-#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_output.c b/sys/netinet/sctp_output.c
index 50e1ed9..3d76b7e 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)
@@ -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/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 {
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++;
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++) {
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",
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/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/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:
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/_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
diff --git a/sys/powerpc/include/frame.h b/sys/powerpc/include/frame.h
index 196cb6f..d2100a1 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 {
@@ -102,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
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];
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;
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_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)
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 <sys/caprights.h>
#include <sys/ipc.h>
#include <sys/socket.h>
#include <sys/ucred.h>
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 <sys/cdefs.h>
#include <sys/param.h>
+#include <sys/caprights.h>
#include <sys/file.h>
#include <sys/fcntl.h>
+#ifndef _KERNEL
+#include <stdbool.h>
+#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 <sys/systm.h>
@@ -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 <stdbool.h>
-
/*
* 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 <sys/caprights.h>
#include <sys/queue.h>
#include <sys/event.h>
#include <sys/lock.h>
@@ -108,10 +109,6 @@ struct filedesc_to_leader {
#ifdef _KERNEL
-#include <sys/systm.h> /* 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 <sys/caprights.h>
+
/*
* 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/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) \
diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h
index e0b70ff..e03bc40 100644
--- a/sys/sys/mouse.h
+++ b/sys/sys/mouse.h
@@ -107,6 +107,9 @@ typedef struct synapticshw {
int capMultiFinger;
int capPalmDetect;
int capPassthrough;
+ int capMiddle;
+ int nExtendedButtons;
+ int nExtendedQueries;
} synapticshw_t;
/* iftype */
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 <sys/caprights.h>
#include <sys/filedesc.h>
#include <sys/queue.h>
#include <sys/uio.h>
@@ -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/param.h b/sys/sys/param.h
index 2ba9201..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 1000051 /* Master, propagated to newvers */
+#define __FreeBSD_version 1000053 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
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/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 <machine/sf_buf.h>
+#include <sys/systm.h>
#include <sys/counter.h>
struct mbuf; /* for sf_buf_mext() */
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) */
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
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);
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 <sys/socket.h>
#endif
+#include <sys/caprights.h>
/*
* 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;
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);
+ }
}
/*
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);
diff --git a/tools/regression/bin/sh/builtins/return8.0 b/tools/regression/bin/sh/builtins/return8.0
new file mode 100644
index 0000000..f00e859
--- /dev/null
+++ b/tools/regression/bin/sh/builtins/return8.0
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+if [ "$1" = nested ]; then
+ return 17
+fi
+
+f() {
+ set -- nested
+ . "$0"
+ return $(($? ^ 1))
+}
+f
+exit $(($? ^ 16))
diff --git a/tools/regression/lib/libc/stdio/test-fmemopen.t b/tools/regression/lib/libc/stdio/test-fmemopen.t
index 8bdfd03..bd5157b 100644
--- a/tools/regression/lib/libc/stdio/test-fmemopen.t
+++ b/tools/regression/lib/libc/stdio/test-fmemopen.t
@@ -7,4 +7,9 @@ executable=`basename $0 .t`
make $executable 2>&1 > /dev/null
-exec ./$executable
+echo 1..1
+if ./$executable; then
+ echo ok 1 - $executable successful
+else
+ echo not ok 1 - $executable failed
+fi
diff --git a/tools/regression/lib/libc/stdio/test-fopen.c b/tools/regression/lib/libc/stdio/test-fopen.c
new file mode 100644
index 0000000..8605717
--- /dev/null
+++ b/tools/regression/lib/libc/stdio/test-fopen.c
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2013 Jilles Tjoelker
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * O_ACCMODE is currently defined incorrectly. This is what it should be.
+ * Various code depends on the incorrect value.
+ */
+#define CORRECT_O_ACCMODE (O_ACCMODE | O_EXEC)
+
+static int testnum = 1;
+
+static void
+runtest(const char *fname, const char *mode)
+{
+ FILE *fp;
+ int fd, flags, wantedflags;
+
+ fp = fopen(fname, mode);
+ if (fp == NULL) {
+ printf("not ok %d - fopen(\"%s\", \"%s\") failed\n",
+ testnum++, fname, mode);
+ printf("not ok %d - FD_CLOEXEC # SKIP\n",
+ testnum++);
+ return;
+ }
+ fd = fileno(fp);
+ if (fd < 0)
+ printf("not ok %d - fileno() failed\n", testnum++);
+ else
+ printf("ok %d - fopen(\"%s\", \"%s\") and fileno() succeeded\n",
+ testnum++, fname, mode);
+ if (fcntl(fd, F_GETFD) == (strchr(mode, 'e') != NULL ? FD_CLOEXEC : 0))
+ printf("ok %d - FD_CLOEXEC flag correct\n", testnum++);
+ else
+ printf("not ok %d - FD_CLOEXEC flag incorrect\n", testnum++);
+ flags = fcntl(fd, F_GETFL);
+ if (strchr(mode, '+'))
+ wantedflags = O_RDWR | (*mode == 'a' ? O_APPEND : 0);
+ else if (*mode == 'r')
+ wantedflags = O_RDONLY;
+ else if (*mode == 'w')
+ wantedflags = O_WRONLY;
+ else if (*mode == 'a')
+ wantedflags = O_WRONLY | O_APPEND;
+ else
+ wantedflags = -1;
+ if (wantedflags == -1)
+ printf("not ok %d - unrecognized mode\n", testnum++);
+ else if ((flags & (CORRECT_O_ACCMODE | O_APPEND)) == wantedflags)
+ printf("ok %d - correct access mode\n", testnum++);
+ else
+ printf("not ok %d - incorrect access mode\n", testnum++);
+ fclose(fp);
+}
+
+/*
+ * Test program for fopen().
+ */
+int
+main(int argc, char *argv[])
+{
+ printf("1..45\n");
+ runtest("/dev/null", "r");
+ runtest("/dev/null", "r+");
+ runtest("/dev/null", "w");
+ runtest("/dev/null", "w+");
+ runtest("/dev/null", "a");
+ runtest("/dev/null", "a+");
+ runtest("/dev/null", "re");
+ runtest("/dev/null", "r+e");
+ runtest("/dev/null", "we");
+ runtest("/dev/null", "w+e");
+ runtest("/dev/null", "ae");
+ runtest("/dev/null", "a+e");
+ runtest("/dev/null", "re+");
+ runtest("/dev/null", "we+");
+ runtest("/dev/null", "ae+");
+
+ return 0;
+}
+
+/* vim:ts=8:cin:sw=8
+ * */
diff --git a/tools/regression/lib/libc/stdio/test-fopen.t b/tools/regression/lib/libc/stdio/test-fopen.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/lib/libc/stdio/test-fopen.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/lib/libc/stdio/test-mkostemp.t b/tools/regression/lib/libc/stdio/test-mkostemp.t
new file mode 100644
index 0000000..8bdfd03
--- /dev/null
+++ b/tools/regression/lib/libc/stdio/test-mkostemp.t
@@ -0,0 +1,10 @@
+#!/bin/sh
+# $FreeBSD$
+
+cd `dirname $0`
+
+executable=`basename $0 .t`
+
+make $executable 2>&1 > /dev/null
+
+exec ./$executable
diff --git a/tools/regression/lib/libc/stdio/test-open_memstream.t b/tools/regression/lib/libc/stdio/test-open_memstream.t
index 8bdfd03..bd5157b 100644
--- a/tools/regression/lib/libc/stdio/test-open_memstream.t
+++ b/tools/regression/lib/libc/stdio/test-open_memstream.t
@@ -7,4 +7,9 @@ executable=`basename $0 .t`
make $executable 2>&1 > /dev/null
-exec ./$executable
+echo 1..1
+if ./$executable; then
+ echo ok 1 - $executable successful
+else
+ echo not ok 1 - $executable failed
+fi
diff --git a/tools/regression/lib/libc/stdio/test-open_wmemstream.t b/tools/regression/lib/libc/stdio/test-open_wmemstream.t
index 8bdfd03..bd5157b 100644
--- a/tools/regression/lib/libc/stdio/test-open_wmemstream.t
+++ b/tools/regression/lib/libc/stdio/test-open_wmemstream.t
@@ -7,4 +7,9 @@ executable=`basename $0 .t`
make $executable 2>&1 > /dev/null
-exec ./$executable
+echo 1..1
+if ./$executable; then
+ echo ok 1 - $executable successful
+else
+ echo not ok 1 - $executable failed
+fi
diff --git a/tools/tools/bus_autoconf/bus_load_file.c b/tools/tools/bus_autoconf/bus_load_file.c
index 527e5bc..8d82ac3 100644
--- a/tools/tools/bus_autoconf/bus_load_file.c
+++ b/tools/tools/bus_autoconf/bus_load_file.c
@@ -39,7 +39,7 @@ void
load_file(const char *fname, uint8_t **pptr, uint32_t *plen)
{
uint8_t *ptr;
- uint32_t len;
+ ssize_t len;
off_t off;
int f;
diff --git a/usr.bin/bmake/Makefile b/usr.bin/bmake/Makefile
index f7c403c..4129552 100644
--- a/usr.bin/bmake/Makefile
+++ b/usr.bin/bmake/Makefile
@@ -14,10 +14,10 @@ CFLAGS+= -I${.CURDIR}
CLEANDIRS+= FreeBSD
CLEANFILES+= bootstrap
-# $Id: Makefile,v 1.17 2013/07/30 19:13:53 sjg Exp $
+# $Id: Makefile,v 1.20 2013/09/04 15:42:03 sjg Exp $
# Base version on src date
-MAKE_VERSION= 20130810
+MAKE_VERSION= 20130904
PROG?= ${.CURDIR:T}
diff --git a/usr.bin/bmake/unit-tests/Makefile b/usr.bin/bmake/unit-tests/Makefile
index 4cbf6a2..be4cd2f 100644
--- a/usr.bin/bmake/unit-tests/Makefile
+++ b/usr.bin/bmake/unit-tests/Makefile
@@ -5,9 +5,9 @@
SRCTOP?= ${.CURDIR:H:H:H}
-# $Id: Makefile.in,v 1.43 2013/07/16 21:14:30 sjg Exp $
+# $Id: Makefile.in,v 1.44 2013/08/28 22:09:29 sjg Exp $
#
-# $NetBSD: Makefile,v 1.37 2013/07/16 19:59:28 sjg Exp $
+# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $
#
# Unit tests for make(1)
# The main targets are:
@@ -52,6 +52,7 @@ SUBFILES= \
phony-end \
posix \
qequals \
+ sunshcmd \
sysv \
ternary \
unexport \
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 06be0c0..0de183c 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -103,6 +103,7 @@ void ktrcsw_old(struct ktr_csw_old *);
void ktruser_malloc(unsigned char *);
void ktruser_rtld(int, unsigned char *);
void ktruser(int, unsigned char *);
+void ktrcaprights(cap_rights_t *);
void ktrsockaddr(struct sockaddr *);
void ktrstat(struct stat *);
void ktrstruct(char *, size_t);
@@ -379,21 +380,21 @@ limitfd(int fd)
cap_rights_t rights;
unsigned long cmd;
- rights = CAP_FSTAT;
+ cap_rights_init(&rights, CAP_FSTAT);
cmd = -1;
switch (fd) {
case STDIN_FILENO:
- rights |= CAP_READ;
+ cap_rights_set(&rights, CAP_READ);
break;
case STDOUT_FILENO:
- rights |= CAP_IOCTL | CAP_WRITE;
+ cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE);
cmd = TIOCGETA; /* required by isatty(3) in printf(3) */
break;
case STDERR_FILENO:
- rights |= CAP_WRITE;
+ cap_rights_set(&rights, CAP_WRITE);
if (!suppressdata) {
- rights |= CAP_IOCTL;
+ cap_rights_set(&rights, CAP_IOCTL);
cmd = TIOCGWINSZ;
}
break;
@@ -401,7 +402,7 @@ limitfd(int fd)
abort();
}
- if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)
+ if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS)
err(1, "unable to limit rights for descriptor %d", fd);
if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
err(1, "unable to limit ioctls for descriptor %d", fd);
@@ -1120,35 +1121,6 @@ ktrsyscall(struct ktr_syscall *ktr, u_int flags)
ip++;
narg--;
break;
- case SYS_cap_new:
- case SYS_cap_rights_limit:
- print_number(ip, narg, c);
- putchar(',');
- arg = *ip;
- ip++;
- narg--;
- /*
- * Hack: the second argument is a
- * cap_rights_t, which 64 bits wide, so on
- * 32-bit systems, it is split between two
- * registers.
- *
- * Since sizeof() is not evaluated by the
- * preprocessor, we can't use an #ifdef,
- * but the compiler will probably optimize
- * the code out anyway.
- */
- if (sizeof(cap_rights_t) > sizeof(register_t)) {
-#if _BYTE_ORDER == _LITTLE_ENDIAN
- arg = ((intmax_t)*ip << 32) + arg;
-#else
- arg = (arg << 32) + *ip;
-#endif
- ip++;
- narg--;
- }
- capname(arg);
- break;
case SYS_cap_fcntls_limit:
print_number(ip, narg, c);
putchar(',');
@@ -1536,6 +1508,15 @@ ktruser(int len, unsigned char *p)
}
void
+ktrcaprights(cap_rights_t *rightsp)
+{
+
+ printf("cap_rights_t ");
+ capname(rightsp);
+ printf("\n");
+}
+
+void
ktrsockaddr(struct sockaddr *sa)
{
/*
@@ -1712,6 +1693,7 @@ ktrstruct(char *buf, size_t buflen)
char *name, *data;
size_t namelen, datalen;
int i;
+ cap_rights_t rights;
struct stat sb;
struct sockaddr_storage ss;
@@ -1731,7 +1713,12 @@ ktrstruct(char *buf, size_t buflen)
for (i = 0; i < (int)namelen; ++i)
if (!isalpha(name[i]))
goto invalid;
- if (strcmp(name, "stat") == 0) {
+ if (strcmp(name, "caprights") == 0) {
+ if (datalen != sizeof(cap_rights_t))
+ goto invalid;
+ memcpy(&rights, data, datalen);
+ ktrcaprights(&rights);
+ } else if (strcmp(name, "stat") == 0) {
if (datalen != sizeof(struct stat))
goto invalid;
memcpy(&sb, data, datalen);
@@ -1758,16 +1745,16 @@ ktrcapfail(struct ktr_cap_fail *ktr)
case CAPFAIL_NOTCAPABLE:
/* operation on fd with insufficient capabilities */
printf("operation requires ");
- capname((intmax_t)ktr->cap_needed);
+ capname(&ktr->cap_needed);
printf(", process holds ");
- capname((intmax_t)ktr->cap_held);
+ capname(&ktr->cap_held);
break;
case CAPFAIL_INCREASE:
/* requested more capabilities than fd already has */
printf("attempt to increase capabilities from ");
- capname((intmax_t)ktr->cap_held);
+ capname(&ktr->cap_held);
printf(" to ");
- capname((intmax_t)ktr->cap_needed);
+ capname(&ktr->cap_needed);
break;
case CAPFAIL_SYSCALL:
/* called restricted syscall */
@@ -1779,9 +1766,9 @@ ktrcapfail(struct ktr_cap_fail *ktr)
break;
default:
printf("unknown capability failure: ");
- capname((intmax_t)ktr->cap_needed);
+ capname(&ktr->cap_needed);
printf(" ");
- capname((intmax_t)ktr->cap_held);
+ capname(&ktr->cap_held);
break;
}
printf("\n");
diff --git a/usr.bin/kdump/mksubr b/usr.bin/kdump/mksubr
index b10af94..676e9e2 100644
--- a/usr.bin/kdump/mksubr
+++ b/usr.bin/kdump/mksubr
@@ -385,7 +385,6 @@ _EOF_
auto_or_type "accessmodename" "[A-Z]_OK[[:space:]]+0?x?[0-9A-Fa-f]+" "sys/unistd.h"
auto_switch_type "acltypename" "ACL_TYPE_[A-Z4_]+[[:space:]]+0x[0-9]+" "sys/acl.h"
-auto_or_type "capname" "CAP_[A-Z]+[[:space:]]+0x[01248]{16}ULL" "sys/capability.h"
auto_or_type "capfcntlname" "CAP_FCNTL_[A-Z]+[[:space:]]+\(1" "sys/capability.h"
auto_switch_type "extattrctlname" "EXTATTR_NAMESPACE_[A-Z]+[[:space:]]+0x[0-9]+" "sys/extattr.h"
auto_switch_type "fadvisebehavname" "POSIX_FADV_[A-Z]+[[:space:]]+[0-9]+" "sys/fcntl.h"
@@ -609,3 +608,26 @@ cat <<_EOF_
}
}
}
+
+_EOF_
+egrep '#define[[:space:]]+CAP_[A-Z_]+[[:space:]]+CAPRIGHT\([0-9],[[:space:]]+0x[0-9]{16}ULL\)' \
+ $include_dir/sys/capability.h | \
+ sed -E 's/[ ]+/ /g' | \
+ awk -F '[ \(,\)]' '
+ BEGIN {
+ printf "void\n"
+ printf "capname(const cap_rights_t *rightsp)\n"
+ printf "{\n"
+ printf "\tint comma = 0;\n\n"
+ printf "\tprintf(\"<\");\n"
+ }
+ {
+ printf "\tif ((rightsp->cr_rights[%s] & %s) == %s) {\n", $4, $2, $2
+ printf "\t\tif (comma) printf(\",\"); else comma = 1;\n"
+ printf "\t\tprintf(\"%s\");\n", $2
+ printf "\t}\n"
+ }
+ END {
+ printf "\tprintf(\">\");\n"
+ printf "}\n"
+ }'
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c
index c6224e7..eca12ad 100644
--- a/usr.bin/patch/pch.c
+++ b/usr.bin/patch/pch.c
@@ -1516,15 +1516,12 @@ posix_name(const struct file_name *names, bool assume_exists)
return path ? savestr(path) : NULL;
}
-/*
- * Choose the name of the file to be patched based the "best" one
- * available.
- */
static char *
-best_name(const struct file_name *names, bool assume_exists)
+compare_names(const struct file_name *names, bool assume_exists, int phase)
{
size_t min_components, min_baselen, min_len, tmp;
char *best = NULL;
+ char *path;
int i;
/*
@@ -1536,47 +1533,43 @@ best_name(const struct file_name *names, bool assume_exists)
*/
min_components = min_baselen = min_len = SIZE_MAX;
for (i = INDEX_FILE; i >= OLD_FILE; i--) {
- if (names[i].path == NULL ||
- (!names[i].exists && !assume_exists))
+ path = names[i].path;
+ if (path == NULL ||
+ (phase == 1 && !names[i].exists && !assume_exists) ||
+ (phase == 2 && checked_in(path) == NULL))
continue;
- if ((tmp = num_components(names[i].path)) > min_components)
+ if ((tmp = num_components(path)) > min_components)
continue;
if (tmp < min_components) {
min_components = tmp;
- best = names[i].path;
+ best = path;
}
- if ((tmp = strlen(basename(names[i].path))) > min_baselen)
+ if ((tmp = strlen(basename(path))) > min_baselen)
continue;
if (tmp < min_baselen) {
min_baselen = tmp;
- best = names[i].path;
+ best = path;
}
- if ((tmp = strlen(names[i].path)) > min_len)
+ if ((tmp = strlen(path)) > min_len)
continue;
min_len = tmp;
- best = names[i].path;
+ best = path;
}
+ return best;
+}
+
+/*
+ * Choose the name of the file to be patched based the "best" one
+ * available.
+ */
+static char *
+best_name(const struct file_name *names, bool assume_exists)
+{
+ char *best;
+
+ best = compare_names(names, assume_exists, 1);
if (best == NULL) {
- /*
- * No files found, look for something we can checkout from
- * RCS/SCCS dirs. Logic is identical to that above...
- */
- min_components = min_baselen = min_len = SIZE_MAX;
- for (i = INDEX_FILE; i >= OLD_FILE; i--) {
- if (names[i].path == NULL ||
- checked_in(names[i].path) == NULL)
- continue;
- if ((tmp = num_components(names[i].path)) > min_components)
- continue;
- min_components = tmp;
- if ((tmp = strlen(basename(names[i].path))) > min_baselen)
- continue;
- min_baselen = tmp;
- if ((tmp = strlen(names[i].path)) > min_len)
- continue;
- min_len = tmp;
- best = names[i].path;
- }
+ best = compare_names(names, assume_exists, 2);
/*
* Still no match? Check to see if the diff could be creating
* a new file.
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c
index 28a3cb0..c19918b 100644
--- a/usr.bin/patch/util.c
+++ b/usr.bin/patch/util.c
@@ -412,7 +412,7 @@ checked_in(char *file)
void
version(void)
{
- fprintf(stderr, "patch 2.0-12u8 FreeBSD\n");
+ fprintf(stderr, "patch 2.0-12u9 FreeBSD\n");
my_exit(EXIT_SUCCESS);
}
diff --git a/usr.bin/procstat/procstat_files.c b/usr.bin/procstat/procstat_files.c
index 72600de..d65c1ae 100644
--- a/usr.bin/procstat/procstat_files.c
+++ b/usr.bin/procstat/procstat_files.c
@@ -133,7 +133,7 @@ print_address(struct sockaddr_storage *ss)
}
static struct cap_desc {
- cap_rights_t cd_right;
+ uint64_t cd_right;
const char *cd_desc;
} cap_desc[] = {
/* General file I/O. */
@@ -244,14 +244,14 @@ static const u_int cap_desc_count = sizeof(cap_desc) /
sizeof(cap_desc[0]);
static u_int
-width_capability(cap_rights_t rights)
+width_capability(cap_rights_t *rightsp)
{
u_int count, i, width;
count = 0;
width = 0;
for (i = 0; i < cap_desc_count; i++) {
- if ((cap_desc[i].cd_right & ~rights) == 0) {
+ if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) {
width += strlen(cap_desc[i].cd_desc);
if (count)
width++;
@@ -262,20 +262,20 @@ width_capability(cap_rights_t rights)
}
static void
-print_capability(cap_rights_t rights, u_int capwidth)
+print_capability(cap_rights_t *rightsp, u_int capwidth)
{
u_int count, i, width;
count = 0;
width = 0;
- for (i = width_capability(rights); i < capwidth; i++) {
- if (rights || i != 0)
+ for (i = width_capability(rightsp); i < capwidth; i++) {
+ if (i != 0)
printf(" ");
else
printf("-");
}
for (i = 0; i < cap_desc_count; i++) {
- if ((cap_desc[i].cd_right & ~rights) == 0) {
+ if (cap_rights_is_set(rightsp, cap_desc[i].cd_right)) {
printf("%s%s", count ? "," : "", cap_desc[i].cd_desc);
width += strlen(cap_desc[i].cd_desc);
if (count)
@@ -306,7 +306,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp)
head = procstat_getfiles(procstat, kipp, 0);
if (head != NULL && Cflag) {
STAILQ_FOREACH(fst, head, next) {
- width = width_capability(fst->fs_cap_rights);
+ width = width_capability(&fst->fs_cap_rights);
if (width > capwidth)
capwidth = width;
}
@@ -460,7 +460,7 @@ procstat_files(struct procstat *procstat, struct kinfo_proc *kipp)
printf("%7c ", '-');
}
if (Cflag) {
- print_capability(fst->fs_cap_rights, capwidth);
+ print_capability(&fst->fs_cap_rights, capwidth);
printf(" ");
}
switch (fst->fs_type) {
diff --git a/usr.bin/rwho/rwho.c b/usr.bin/rwho/rwho.c
index bcb5adb..8c985f0 100644
--- a/usr.bin/rwho/rwho.c
+++ b/usr.bin/rwho/rwho.c
@@ -93,6 +93,7 @@ main(int argc, char *argv[])
struct whod *w;
struct whoent *we;
struct myutmp *mp;
+ cap_rights_t rights;
int f, n, i;
int d_first;
int dfd;
@@ -124,7 +125,8 @@ main(int argc, char *argv[])
err(1, "opendir(%s)", _PATH_RWHODIR);
dfd = dirfd(dirp);
mp = myutmp;
- if (cap_rights_limit(dfd, CAP_READ | CAP_LOOKUP) < 0 && errno != ENOSYS)
+ cap_rights_init(&rights, CAP_READ, CAP_LOOKUP);
+ if (cap_rights_limit(dfd, &rights) < 0 && errno != ENOSYS)
err(1, "cap_rights_limit failed: %s", _PATH_RWHODIR);
/*
* Cache files required for time(3) and localtime(3) before entering
@@ -135,13 +137,14 @@ main(int argc, char *argv[])
if (cap_enter() < 0 && errno != ENOSYS)
err(1, "cap_enter");
(void) time(&now);
+ cap_rights_init(&rights, CAP_READ);
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0)
continue;
f = openat(dfd, dp->d_name, O_RDONLY);
if (f < 0)
continue;
- if (cap_rights_limit(f, CAP_READ) < 0 && errno != ENOSYS)
+ if (cap_rights_limit(f, &rights) < 0 && errno != ENOSYS)
err(1, "cap_rights_limit failed: %s", dp->d_name);
cc = read(f, (char *)&wd, sizeof(struct whod));
if (cc < WHDRSIZE) {
diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c
index d34b0c0..8e7f40f 100644
--- a/usr.bin/uniq/uniq.c
+++ b/usr.bin/uniq/uniq.c
@@ -145,20 +145,19 @@ main (int argc, char *argv[])
ofp = stdout;
if (argc > 0 && strcmp(argv[0], "-") != 0)
ifp = file(ifn = argv[0], "r");
- if (cap_rights_limit(fileno(ifp), CAP_FSTAT | CAP_READ) < 0 &&
- errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_FSTAT, CAP_READ);
+ if (cap_rights_limit(fileno(ifp), &rights) < 0 && errno != ENOSYS)
err(1, "unable to limit rights for %s", ifn);
- }
- rights = CAP_FSTAT | CAP_WRITE;
+ cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
if (argc > 1)
ofp = file(argv[1], "w");
else
- rights |= CAP_IOCTL;
- if (cap_rights_limit(fileno(ofp), rights) < 0 && errno != ENOSYS) {
+ cap_rights_set(&rights, CAP_IOCTL);
+ if (cap_rights_limit(fileno(ofp), &rights) < 0 && errno != ENOSYS) {
err(1, "unable to limit rights for %s",
argc > 1 ? argv[1] : "stdout");
}
- if ((rights & CAP_IOCTL) != 0) {
+ if (cap_rights_is_set(&rights, CAP_IOCTL)) {
unsigned long cmd;
cmd = TIOCGETA; /* required by isatty(3) in printf(3) */
diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c
index c712692..aeb008e 100644
--- a/usr.sbin/bhyve/ioapic.c
+++ b/usr.sbin/bhyve/ioapic.c
@@ -101,13 +101,13 @@ ioapic_set_pinstate(struct vmctx *ctx, int pin, bool newstate)
* XXX
* We only deal with:
* - edge triggered interrupts
- * - physical destination mode
* - fixed delivery mode
+ * Level-triggered sources will work so long as there is
+ * no sharing.
*/
low = ioapic->redtbl[pin];
high = ioapic->redtbl[pin] >> 32;
if ((low & IOART_INTMASK) == IOART_INTMCLR &&
- (low & IOART_TRGRMOD) == IOART_TRGREDG &&
(low & IOART_DESTMOD) == IOART_DESTPHY &&
(low & IOART_DELMOD) == IOART_DELFIXED) {
vector = low & IOART_INTVEC;
diff --git a/usr.sbin/periodic/periodic.sh b/usr.sbin/periodic/periodic.sh
index 9b13a96..c27aeee 100644
--- a/usr.sbin/periodic/periodic.sh
+++ b/usr.sbin/periodic/periodic.sh
@@ -21,7 +21,7 @@ output_pipe()
case "$output" in
/*) pipe="cat >>$output";;
"") pipe=cat;;
- *) pipe="mail -E -s '$host ${1##*/} run output' $output";;
+ *) pipe="mail -E -s '$host ${2}${2:+ }${1##*/} run output' $output";;
esac
eval $pipe
}
@@ -53,12 +53,13 @@ if [ $1 != "LOCKED" ]; then
case $? in
0) ;;
73) #EX_CANTCREATE
- echo "can't create ${lockfile}" | output_pipe $arg
+ echo "can't create ${lockfile}" | \
+ output_pipe $arg "$PERIODIC"
ret=1
;;
75) #EX_TEMPFAIL
echo "$host ${arg##*/} prior run still in progress" | \
- output_pipe $arg
+ output_pipe $arg "$PERIODIC"
ret=1
;;
*)
@@ -76,6 +77,7 @@ shift
arg=$1
tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`
+context="$PERIODIC"
export PERIODIC="$arg${PERIODIC:+ }${PERIODIC}"
# Execute each executable file in the directory list. If the x bit is not
@@ -136,6 +138,6 @@ esac
echo ""
echo "-- End of $arg output --"
fi
-} | output_pipe ${arg}
+} | output_pipe $arg "$context"
rm -f $tmp_output
diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c
index b857356..5413cdf 100644
--- a/usr.sbin/rtadvd/if.c
+++ b/usr.sbin/rtadvd/if.c
@@ -394,8 +394,8 @@ update_ifinfo_nd_flags(struct ifinfo *ifi)
error = ioctl(s, SIOCGIFINFO_IN6, (caddr_t)&nd);
if (error) {
close(s);
- syslog(LOG_ERR,
- "<%s> ioctl() failed.", __func__);
+ if (errno != EPFNOSUPPORT)
+ syslog(LOG_ERR, "<%s> ioctl() failed.", __func__);
return (1);
}
ifi->ifi_nd_flags = nd.ndi.flags;
diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c
index 25b8692..87a4166 100644
--- a/usr.sbin/rwhod/rwhod.c
+++ b/usr.sbin/rwhod/rwhod.c
@@ -274,21 +274,17 @@ main(int argc, char *argv[])
exit(1);
if (!quiet_mode) {
pid_child_receiver = pdfork(&fdp, 0);
- if (pid_child_receiver == -1) {
- if (errno != ENOSYS) {
- syslog(LOG_ERR, "pdfork: %m");
- exit(1);
- } else {
- pid_child_receiver = fork();
- fdp = -1;
- }
- }
if (pid_child_receiver == 0) {
receiver_process();
} else if (pid_child_receiver > 0) {
sender_process();
} else if (pid_child_receiver == -1) {
- syslog(LOG_ERR, "pdfork: %m");
+ if (errno == ENOSYS) {
+ syslog(LOG_ERR,
+ "The pdfork(2) system call is not available; recompile the kernel with options PROCDESC");
+ } else {
+ syslog(LOG_ERR, "pdfork: %m");
+ }
exit(1);
}
} else {
@@ -354,6 +350,7 @@ receiver_process(void)
{
struct sockaddr_in from;
struct stat st;
+ cap_rights_t rights;
char path[64];
int dirfd;
struct whod wd;
@@ -367,8 +364,9 @@ receiver_process(void)
syslog(LOG_WARNING, "%s: %m", _PATH_RWHODIR);
exit(1);
}
- if (cap_rights_limit(dirfd, CAP_CREATE | CAP_WRITE | CAP_FTRUNCATE |
- CAP_SEEK | CAP_LOOKUP | CAP_FSTAT) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_CREATE, CAP_FSTAT, CAP_FTRUNCATE,
+ CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(dirfd, &rights) < 0 && errno != ENOSYS) {
syslog(LOG_WARNING, "cap_rights_limit: %m");
exit(1);
}
@@ -413,8 +411,8 @@ receiver_process(void)
syslog(LOG_WARNING, "%s: %m", path);
continue;
}
- if (cap_rights_limit(whod, CAP_WRITE | CAP_FTRUNCATE |
- CAP_FSTAT) < 0 && errno != ENOSYS) {
+ cap_rights_init(&rights, CAP_FSTAT, CAP_FTRUNCATE, CAP_WRITE);
+ if (cap_rights_limit(whod, &rights) < 0 && errno != ENOSYS) {
syslog(LOG_WARNING, "cap_rights_limit: %m");
exit(1);
}
diff --git a/usr.sbin/watch/watch.c b/usr.sbin/watch/watch.c
index e69534d..eecf0d3 100644
--- a/usr.sbin/watch/watch.c
+++ b/usr.sbin/watch/watch.c
@@ -110,7 +110,6 @@ set_tty(void)
{
struct termios ntty;
- tcgetattr(std_in, &otty);
ntty = otty;
ntty.c_lflag &= ~ICANON; /* disable canonical operation */
ntty.c_lflag &= ~ECHO;
@@ -324,6 +323,8 @@ main(int ac, char *av[])
usage();
}
+ tcgetattr(std_in, &otty);
+
if (modfind("snp") == -1)
if (kldload("snp") == -1 || modfind("snp") == -1)
warn("snp module not available");
OpenPOWER on IntegriCloud