summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-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
217 files changed, 5777 insertions, 3150 deletions
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);
OpenPOWER on IntegriCloud