aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-09-11 18:41:00 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-09-11 18:41:00 +0000
commit3af64f03119a159ac15eb75b92d346705b490385 (patch)
treeccf01a63517d6acf2fcf883b298f5a384b814df9 /sys
parentda2d1e9d2582eece6aad948897489ca0b5d64d73 (diff)
parentde35521a3bbfa50aa7c6dc6852a78099254da094 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/efirt_machdep.c3
-rw-r--r--sys/amd64/amd64/efirt_support.S116
-rw-r--r--sys/amd64/amd64/genassym.c20
-rw-r--r--sys/amd64/amd64/pmap.c10
-rw-r--r--sys/amd64/amd64/support.S43
-rw-r--r--sys/amd64/amd64/trap.c2
-rw-r--r--sys/amd64/include/efi.h27
-rw-r--r--sys/amd64/include/proc.h2
-rw-r--r--sys/arm/arm/gic.c3
-rw-r--r--sys/arm/arm/gic_acpi.c3
-rw-r--r--sys/arm/arm/physmem.c13
-rw-r--r--sys/arm/ti/omap4/omap4_prcm_clks.c27
-rw-r--r--sys/arm64/arm64/efirt_machdep.c7
-rw-r--r--sys/arm64/arm64/machdep.c8
-rw-r--r--sys/arm64/include/efi.h14
-rw-r--r--sys/cam/ctl/ctl.c22
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c20
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c20
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h9
-rw-r--r--sys/cddl/dev/dtrace/riscv/dtrace_subr.c56
-rw-r--r--sys/cddl/dev/fbt/fbt.c2
-rw-r--r--sys/cddl/dev/fbt/riscv/fbt_isa.c102
-rw-r--r--sys/conf/files.amd641
-rw-r--r--sys/conf/kern.mk2
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/contrib/rdma/krping/krping.c2
-rw-r--r--sys/crypto/ccp/ccp.c2
-rw-r--r--sys/dev/efidev/efirt.c192
-rw-r--r--sys/dev/efidev/efirtc.c3
-rw-r--r--sys/dev/extres/regulator/regulator.c11
-rw-r--r--sys/dev/intel/spi.c6
-rw-r--r--sys/dev/ixgbe/if_ixv.c30
-rw-r--r--sys/dev/ixgbe/ix_txrx.c3
-rw-r--r--sys/dev/mlx5/driver.h3
-rw-r--r--sys/dev/mlx5/mlx5_core/mlx5_main.c15
-rw-r--r--sys/dev/mlx5/mlx5_en/en.h5
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c19
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_main.c11
-rw-r--r--sys/dev/mlx5/mlx5_en/mlx5_en_tx.c6
-rw-r--r--sys/dev/mmc/mmc.c8
-rw-r--r--sys/dev/pci/pci_user.c14
-rw-r--r--sys/dev/random/randomdev.c10
-rw-r--r--sys/dev/sdhci/sdhci.c3
-rw-r--r--sys/dev/sound/midi/midi.c4
-rw-r--r--sys/dev/sound/pci/csamidi.c290
-rw-r--r--sys/dev/usb/input/wmt.c2
-rw-r--r--sys/kern/kern_clock.c93
-rw-r--r--sys/kern/kern_clocksource.c6
-rw-r--r--sys/kern/kern_thread.c2
-rw-r--r--sys/kern/subr_blist.c14
-rw-r--r--sys/kern/subr_rtc.c5
-rw-r--r--sys/mips/conf/MALTA64EL1
-rw-r--r--sys/modules/dtb/omap4/Makefile4
-rw-r--r--sys/modules/efirt/Makefile7
-rw-r--r--sys/modules/sound/driver/csa/Makefile4
-rw-r--r--sys/net/iflib.c96
-rw-r--r--sys/net/route.h6
-rw-r--r--sys/netinet/in_kdtrace.c6
-rw-r--r--sys/netinet/in_pcb.c74
-rw-r--r--sys/netinet/in_pcb.h11
-rw-r--r--sys/netinet/ip_fastfwd.c26
-rw-r--r--sys/netinet/tcp_hpts.c4
-rw-r--r--sys/netinet6/frag6.c4
-rw-r--r--sys/netinet6/in6_pcb.c21
-rw-r--r--sys/netinet6/ip6_output.c10
-rw-r--r--sys/ofed/drivers/infiniband/core/ib_cm.c5
-rw-r--r--sys/ofed/drivers/infiniband/core/ib_cma.c89
-rw-r--r--sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c28
-rw-r--r--sys/ofed/drivers/infiniband/core/ib_uverbs_marshall.c2
-rw-r--r--sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c159
-rw-r--r--sys/ofed/include/rdma/ib_addr.h10
-rw-r--r--sys/ofed/include/rdma/ib_cm.h14
-rw-r--r--sys/powerpc/include/pcb.h6
-rw-r--r--sys/powerpc/include/pcpu.h1
-rw-r--r--sys/riscv/conf/GENERIC9
-rw-r--r--sys/riscv/include/asm.h10
-rw-r--r--sys/riscv/include/riscv_opcode.h116
-rw-r--r--sys/riscv/include/riscvreg.h27
-rw-r--r--sys/riscv/riscv/copyinout.S16
-rw-r--r--sys/riscv/riscv/exception.S9
-rw-r--r--sys/riscv/riscv/locore.S5
-rw-r--r--sys/riscv/riscv/machdep.c15
-rw-r--r--sys/riscv/riscv/support.S28
-rw-r--r--sys/riscv/riscv/vm_machdep.c3
-rw-r--r--sys/security/audit/audit_bsm_db.c91
-rw-r--r--sys/sys/efi.h3
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/systm.h10
-rw-r--r--sys/sys/vmmeter.h7
-rw-r--r--sys/ufs/ffs/ffs_alloc.c4
-rw-r--r--sys/vm/vm_domainset.c26
-rw-r--r--sys/vm/vm_domainset.h7
-rw-r--r--sys/vm/vm_fault.c11
-rw-r--r--sys/vm/vm_glue.c8
-rw-r--r--sys/vm/vm_page.c78
-rw-r--r--sys/vm/vm_page.h16
-rw-r--r--sys/vm/vm_pageout.h2
-rw-r--r--sys/vm/vm_phys.c25
-rw-r--r--sys/x86/x86/intr_machdep.c2
99 files changed, 1723 insertions, 688 deletions
diff --git a/sys/amd64/amd64/efirt_machdep.c b/sys/amd64/amd64/efirt_machdep.c
index da7783043a24..80ffa66f5ec4 100644
--- a/sys/amd64/amd64/efirt_machdep.c
+++ b/sys/amd64/amd64/efirt_machdep.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <machine/vmparam.h>
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <vm/vm_extern.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
@@ -266,6 +267,7 @@ efi_arch_enter(void)
curpmap = PCPU_GET(curpmap);
PMAP_LOCK_ASSERT(curpmap, MA_OWNED);
+ curthread->td_md.md_efirt_dis_pf = vm_fault_disable_pagefaults();
/*
* IPI TLB shootdown handler invltlb_pcid_handler() reloads
@@ -300,6 +302,7 @@ efi_arch_leave(void)
curpmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid : 0));
if (!pmap_pcid_enabled)
invltlb();
+ vm_fault_enable_pagefaults(curthread->td_md.md_efirt_dis_pf);
}
/* XXX debug stuff */
diff --git a/sys/amd64/amd64/efirt_support.S b/sys/amd64/amd64/efirt_support.S
new file mode 100644
index 000000000000..cd578eddcfb1
--- /dev/null
+++ b/sys/amd64/amd64/efirt_support.S
@@ -0,0 +1,116 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * 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$
+ */
+
+#include <machine/asmacros.h>
+
+#include "assym.inc"
+
+ .text
+ENTRY(efi_rt_arch_call)
+ pushq %rbp
+ movq %rsp, %rbp
+
+ movq %rbx, EC_RBX(%rdi)
+ movq %rsp, EC_RSP(%rdi)
+ movq %rbp, EC_RBP(%rdi)
+ movq %r12, EC_R12(%rdi)
+ movq %r13, EC_R13(%rdi)
+ movq %r14, EC_R14(%rdi)
+ movq %r15, EC_R15(%rdi)
+ movq PCPU(CURTHREAD), %rax
+ movq %rdi, TD_MD+MD_EFIRT_TMP(%rax)
+ movq PCPU(CURPCB), %rsi
+
+ movl EC_ARGCNT(%rdi), %ecx
+ movl %ecx, %ebx
+ movl $4, %eax
+ cmpl %eax, %ecx
+ cmovbl %eax, %ecx
+ shll $3, %ecx
+ subq %rcx, %rsp
+
+ cmpl $0, %ebx
+ jz 1f
+ movq EC_ARG1(%rdi), %rcx
+ decl %ebx
+ jz 1f
+ movq EC_ARG2(%rdi), %rdx
+ decl %ebx
+ jz 1f
+ movq EC_ARG3(%rdi), %r8
+ decl %ebx
+ jz 1f
+ movq EC_ARG4(%rdi), %r9
+ decl %ebx
+ jz 1f
+ movq EC_ARG5(%rdi), %rax
+ movq %rax, 4*8(%rsp)
+ decl %ebx
+ jz 1f
+ movq $efi_rt_panic_str, %rdi
+ call panic
+1: movq EC_FPTR(%rdi), %rax
+ movq $efi_rt_fault, PCB_ONFAULT(%rsi)
+ callq *%rax
+
+ movq PCPU(CURTHREAD), %rbx
+ movq TD_MD+MD_EFIRT_TMP(%rbx), %rdi
+ movq %rax, EC_EFI_STATUS(%rdi)
+ movq PCPU(CURPCB), %rsi
+ xorl %eax, %eax
+ movq %rax, PCB_ONFAULT(%rsi)
+
+efi_rt_arch_call_tail:
+ movq EC_R15(%rdi), %r15
+ movq EC_R14(%rdi), %r14
+ movq EC_R13(%rdi), %r13
+ movq EC_R12(%rdi), %r12
+ movq EC_RBP(%rdi), %rbp
+ movq EC_RSP(%rdi), %rsp
+ movq EC_RBX(%rdi), %rbx
+
+ popq %rbp
+ ret
+END(efi_rt_arch_call)
+
+ENTRY(efi_rt_fault)
+ xorl %eax, %eax
+ movq PCPU(CURPCB), %rsi
+ movq %rax, PCB_ONFAULT(%rsi)
+ movl $EFAULT, %eax
+ movq PCPU(CURTHREAD), %rbx
+ movq TD_MD+MD_EFIRT_TMP(%rbx), %rdi
+ jmp efi_rt_arch_call_tail
+END(efi_rt_fault)
+
+efi_rt_panic_str: .asciz "efi_rt_arch_call: too many args"
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index d61b5c7bb6df..4d069388ee93 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <machine/sigframe.h>
#include <machine/proc.h>
#include <machine/segments.h>
+#include <machine/efi.h>
ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
@@ -77,12 +78,15 @@ ASSYM(P_MD, offsetof(struct proc, p_md));
ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt));
ASSYM(MD_LDT_SD, offsetof(struct mdproc, md_ldt_sd));
+ASSYM(MD_EFIRT_TMP, offsetof(struct mdthread, md_efirt_tmp));
+
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_PFLAGS, offsetof(struct thread, td_pflags));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
+ASSYM(TD_MD, offsetof(struct thread, td_md));
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
@@ -249,3 +253,19 @@ ASSYM(__FreeBSD_version, __FreeBSD_version);
#ifdef HWPMC_HOOKS
ASSYM(PMC_FN_USER_CALLCHAIN, PMC_FN_USER_CALLCHAIN);
#endif
+
+ASSYM(EC_EFI_STATUS, offsetof(struct efirt_callinfo, ec_efi_status));
+ASSYM(EC_FPTR, offsetof(struct efirt_callinfo, ec_fptr));
+ASSYM(EC_ARGCNT, offsetof(struct efirt_callinfo, ec_argcnt));
+ASSYM(EC_ARG1, offsetof(struct efirt_callinfo, ec_arg1));
+ASSYM(EC_ARG2, offsetof(struct efirt_callinfo, ec_arg2));
+ASSYM(EC_ARG3, offsetof(struct efirt_callinfo, ec_arg3));
+ASSYM(EC_ARG4, offsetof(struct efirt_callinfo, ec_arg4));
+ASSYM(EC_ARG5, offsetof(struct efirt_callinfo, ec_arg5));
+ASSYM(EC_RBX, offsetof(struct efirt_callinfo, ec_rbx));
+ASSYM(EC_RSP, offsetof(struct efirt_callinfo, ec_rsp));
+ASSYM(EC_RBP, offsetof(struct efirt_callinfo, ec_rbp));
+ASSYM(EC_R12, offsetof(struct efirt_callinfo, ec_r12));
+ASSYM(EC_R13, offsetof(struct efirt_callinfo, ec_r13));
+ASSYM(EC_R14, offsetof(struct efirt_callinfo, ec_r14));
+ASSYM(EC_R15, offsetof(struct efirt_callinfo, ec_r15));
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index cbd76aa48585..8cb09df626be 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -7582,9 +7582,13 @@ pmap_activate_boot(pmap_t pmap)
CPU_SET(cpuid, &pmap->pm_active);
#endif
PCPU_SET(curpmap, pmap);
- kcr3 = pmap->pm_cr3;
- if (pmap_pcid_enabled)
- kcr3 |= pmap->pm_pcids[cpuid].pm_pcid | CR3_PCID_SAVE;
+ if (pti) {
+ kcr3 = pmap->pm_cr3;
+ if (pmap_pcid_enabled)
+ kcr3 |= pmap->pm_pcids[cpuid].pm_pcid | CR3_PCID_SAVE;
+ } else {
+ kcr3 = PMAP_NO_CR3;
+ }
PCPU_SET(kcr3, kcr3);
PCPU_SET(ucr3, PMAP_NO_CR3);
}
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index e010c4eef64c..714f100a9749 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -312,9 +312,10 @@ ENTRY(copyout_smap)
movsq
movb %dl,%cl
andb $7,%cl
+ je 1f
rep
movsb
- clac
+1: clac
done_copyout:
xorl %eax,%eax
@@ -361,6 +362,7 @@ ENTRY(copyin_nosmap)
movsq
movb %al,%cl
andb $7,%cl /* copy remaining bytes */
+ je done_copyin
rep
movsb
@@ -393,10 +395,10 @@ ENTRY(copyin_smap)
movsq
movb %al,%cl
andb $7,%cl /* copy remaining bytes */
- je done_copyin
+ je 1f
rep
movsb
- clac
+1: clac
done_copyin:
xorl %eax,%eax
@@ -912,6 +914,8 @@ ENTRY(copyinstr_smap)
subq %rsi,%rax
jbe cpystrflt
+ stac
+
/* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */
cmpq %rdx,%rax
jae 1f
@@ -922,31 +926,19 @@ ENTRY(copyinstr_smap)
2:
decq %rdx
- jz copyinstr_toolong
+ jz copyinstr_toolong_smap
- stac
lodsb
stosb
- clac
orb %al,%al
jnz 2b
+ clac
+
copyinstr_succ:
/* Success -- 0 byte reached */
decq %rdx
xorl %eax,%eax
- jmp cpystrflt_x
-copyinstr_toolong:
- /* rdx is zero - return ENAMETOOLONG or EFAULT */
- movq $VM_MAXUSER_ADDRESS,%rax
- cmpq %rax,%rsi
- jae cpystrflt
- movq $ENAMETOOLONG,%rax
- jmp cpystrflt_x
-
- /* Fault entry clears PSL.AC */
-cpystrflt:
- movq $EFAULT,%rax
cpystrflt_x:
/* set *lencopied and return %eax */
@@ -960,6 +952,21 @@ cpystrflt_x:
1:
POP_FRAME_POINTER
ret
+ /* Fault entry clears PSL.AC */
+cpystrflt:
+ movq $EFAULT,%rax
+ jmp cpystrflt_x
+
+copyinstr_toolong_smap:
+ clac
+copyinstr_toolong:
+ /* rdx is zero - return ENAMETOOLONG or EFAULT */
+ movq $VM_MAXUSER_ADDRESS,%rax
+ cmpq %rax,%rsi
+ jae cpystrflt
+ movq $ENAMETOOLONG,%rax
+ jmp cpystrflt_x
+
END(copyinstr_smap)
/*
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 019decb837ac..4d03da234f19 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -806,7 +806,7 @@ trap_pfault(struct trapframe *frame, int usermode)
* If nx protection of the usermode portion of kernel page
* tables caused trap, panic.
*/
- if (PCPU_GET(curpmap)->pm_ucr3 != PMAP_NO_CR3 && usermode &&
+ if (usermode && PCPU_GET(curpmap)->pm_ucr3 != PMAP_NO_CR3 &&
pg_nx != 0 && (frame->tf_err & (PGEX_P | PGEX_W |
PGEX_U | PGEX_I)) == (PGEX_P | PGEX_U | PGEX_I) &&
(curpcb->pcb_saved_ucr3 & ~CR3_PCID_MASK)==
diff --git a/sys/amd64/include/efi.h b/sys/amd64/include/efi.h
index eaea8d03276c..082223792ac0 100644
--- a/sys/amd64/include/efi.h
+++ b/sys/amd64/include/efi.h
@@ -48,9 +48,30 @@
#ifdef _KERNEL
#include <isa/rtc.h>
-#define EFI_TIME_LOCK() mtx_lock(&atrtc_time_lock);
-#define EFI_TIME_UNLOCK() mtx_unlock(&atrtc_time_lock);
-#define EFI_TIME_OWNED() mtx_assert(&atrtc_time_lock, MA_OWNED);
+#define EFI_TIME_LOCK() mtx_lock(&atrtc_time_lock)
+#define EFI_TIME_UNLOCK() mtx_unlock(&atrtc_time_lock)
+#define EFI_TIME_OWNED() mtx_assert(&atrtc_time_lock, MA_OWNED)
+
+#define EFI_RT_HANDLE_FAULTS_DEFAULT 1
#endif
+struct efirt_callinfo {
+ const char *ec_name;
+ register_t ec_efi_status;
+ register_t ec_fptr;
+ register_t ec_argcnt;
+ register_t ec_arg1;
+ register_t ec_arg2;
+ register_t ec_arg3;
+ register_t ec_arg4;
+ register_t ec_arg5;
+ register_t ec_rbx;
+ register_t ec_rsp;
+ register_t ec_rbp;
+ register_t ec_r12;
+ register_t ec_r13;
+ register_t ec_r14;
+ register_t ec_r15;
+};
+
#endif /* __AMD64_INCLUDE_EFI_H_ */
diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h
index f52c71208e64..54f5b416a7d4 100644
--- a/sys/amd64/include/proc.h
+++ b/sys/amd64/include/proc.h
@@ -62,6 +62,8 @@ struct mdthread {
register_t md_saved_flags; /* (k) */
register_t md_spurflt_addr; /* (k) Spurious page fault address. */
struct pmap_invl_gen md_invl_gen;
+ register_t md_efirt_tmp; /* (k) */
+ int md_efirt_dis_pf; /* (k) */
};
struct mdproc {
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 0b6d90be053e..9ff0ec110b54 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -497,8 +497,7 @@ arm_gic_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
switch(which) {
case GIC_IVAR_HW_REV:
- KASSERT(GICD_IIDR_VAR(sc->gic_iidr) < 3 &&
- GICD_IIDR_VAR(sc->gic_iidr) != 0,
+ KASSERT(GICD_IIDR_VAR(sc->gic_iidr) < 3,
("arm_gic_read_ivar: Unknown IIDR revision %u (%.08x)",
GICD_IIDR_VAR(sc->gic_iidr), sc->gic_iidr));
*result = GICD_IIDR_VAR(sc->gic_iidr);
diff --git a/sys/arm/arm/gic_acpi.c b/sys/arm/arm/gic_acpi.c
index 2ca65fcaf80c..40928b2b2b19 100644
--- a/sys/arm/arm/gic_acpi.c
+++ b/sys/arm/arm/gic_acpi.c
@@ -34,6 +34,7 @@
* SUCH DAMAGE.
*/
+#include "opt_acpi.h"
#include "opt_platform.h"
#include <sys/cdefs.h>
@@ -217,7 +218,7 @@ gic_acpi_attach(device_t dev)
if (err != 0)
return (err);
- xref = 0;
+ xref = ACPI_INTR_XREF;
/*
* Now, when everything is initialized, it's right time to
diff --git a/sys/arm/arm/physmem.c b/sys/arm/arm/physmem.c
index 66c74c9cd731..8a97f9883451 100644
--- a/sys/arm/arm/physmem.c
+++ b/sys/arm/arm/physmem.c
@@ -48,8 +48,8 @@ __FBSDID("$FreeBSD$");
* that can be allocated, or both, depending on the exclusion flags associated
* with the region.
*/
-#define MAX_HWCNT 10
-#define MAX_EXCNT 10
+#define MAX_HWCNT 16
+#define MAX_EXCNT 16
#if defined(__arm__)
#define MAX_PHYS_ADDR 0xFFFFFFFFull
@@ -359,7 +359,8 @@ arm_physmem_hardware_region(uint64_t pa, uint64_t sz)
/*
* Add an exclusion region.
*/
-void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
+void
+arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
{
vm_offset_t adj;
@@ -371,8 +372,10 @@ void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
pa = trunc_page(pa);
sz = round_page(sz + adj);
- if (excnt < nitems(exregions))
- excnt = insert_region(exregions, excnt, pa, sz, exflags);
+ if (excnt >= nitems(exregions))
+ panic("failed to exclude region %#jx-%#jx", (uintmax_t)pa,
+ (uintmax_t)(pa + sz));
+ excnt = insert_region(exregions, excnt, pa, sz, exflags);
}
size_t
diff --git a/sys/arm/ti/omap4/omap4_prcm_clks.c b/sys/arm/ti/omap4/omap4_prcm_clks.c
index ecf698a0208e..1ed3a0f6c4d2 100644
--- a/sys/arm/ti/omap4/omap4_prcm_clks.c
+++ b/sys/arm/ti/omap4/omap4_prcm_clks.c
@@ -176,6 +176,7 @@ struct omap4_prcm_softc {
struct resource *sc_res;
int sc_rid;
int sc_instance;
+ int attach_done;
};
static int omap4_clk_generic_activate(struct ti_clock_dev *clkdev);
@@ -1446,10 +1447,8 @@ static int
omap4_prcm_attach(device_t dev)
{
struct omap4_prcm_softc *sc;
- unsigned int freq;
const struct ofw_compat_data *ocd;
-
sc = device_get_softc(dev);
ocd = ofw_bus_search_compatible(dev, compat_data);
sc->sc_instance = (int)ocd->ocd_data;
@@ -1463,6 +1462,22 @@ omap4_prcm_attach(device_t dev)
ti_cpu_reset = omap4_prcm_reset;
+ return (0);
+}
+
+static void
+omap4_prcm_new_pass(device_t dev)
+{
+ struct omap4_prcm_softc *sc = device_get_softc(dev);
+ unsigned int freq;
+
+ if (sc->attach_done ||
+ bus_current_pass < (BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY)) {
+ bus_generic_new_pass(dev);
+ return;
+ }
+ sc->attach_done = 1;
+
/*
* In order to determine ARM frequency we need both RPM and CM1
* instances up and running. So wait until all CRM devices are
@@ -1473,12 +1488,16 @@ omap4_prcm_attach(device_t dev)
arm_tmr_change_frequency(freq / 2);
}
- return (0);
+ return;
}
static device_method_t omap4_prcm_methods[] = {
DEVMETHOD(device_probe, omap4_prcm_probe),
DEVMETHOD(device_attach, omap4_prcm_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_new_pass, omap4_prcm_new_pass),
+
{0, 0},
};
@@ -1491,5 +1510,5 @@ static driver_t omap4_prcm_driver = {
static devclass_t omap4_prcm_devclass;
EARLY_DRIVER_MODULE(omap4_prcm, simplebus, omap4_prcm_driver,
- omap4_prcm_devclass, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY);
+ omap4_prcm_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
MODULE_VERSION(omap4_prcm, 1);
diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c
index 44e3a04ac372..cf092ff0dab7 100644
--- a/sys/arm64/arm64/efirt_machdep.c
+++ b/sys/arm64/arm64/efirt_machdep.c
@@ -268,3 +268,10 @@ efi_arch_leave(void)
"isb \n"
: : "r"(td->td_proc->p_md.md_l0addr));
}
+
+int
+efi_rt_arch_call(struct efirt_callinfo *ec)
+{
+
+ panic("not implemented");
+}
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index f1ba40cfa9ae..dc243c958a63 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -982,6 +982,7 @@ cache_setup(void)
void
initarm(struct arm64_bootparams *abp)
{
+ struct efi_fb *efifb;
struct efi_map_header *efihdr;
struct pcpu *pcpup;
char *env;
@@ -1031,6 +1032,13 @@ initarm(struct arm64_bootparams *abp)
EXFLAG_NODUMP | EXFLAG_NOALLOC);
#endif
+ /* Exclude the EFI framebuffer from our view of physical memory. */
+ efifb = (struct efi_fb *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_EFI_FB);
+ if (efifb != NULL)
+ arm_physmem_exclude_region(efifb->fb_addr, efifb->fb_size,
+ EXFLAG_NOALLOC);
+
/* Set the pcpu data, this is needed by pmap_bootstrap */
pcpup = &__pcpu[0];
pcpu_init(pcpup, 0, sizeof(struct pcpu));
diff --git a/sys/arm64/include/efi.h b/sys/arm64/include/efi.h
index 6673adccb34f..a8fddfad8d0f 100644
--- a/sys/arm64/include/efi.h
+++ b/sys/arm64/include/efi.h
@@ -39,6 +39,20 @@
#define EFI_TIME_LOCK()
#define EFI_TIME_UNLOCK()
#define EFI_TIME_OWNED()
+
+#define EFI_RT_HANDLE_FAULTS_DEFAULT 0
#endif
+struct efirt_callinfo {
+ const char *ec_name;
+ register_t ec_efi_status;
+ register_t ec_fptr;
+ register_t ec_argcnt;
+ register_t ec_arg1;
+ register_t ec_arg2;
+ register_t ec_arg3;
+ register_t ec_arg4;
+ register_t ec_arg5;
+};
+
#endif /* __ARM64_INCLUDE_EFI_H_ */
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 94bc97bc033d..2606327d3851 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -2943,8 +2943,17 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
if (lun_req->args != NULL) {
- lun_req->args_nvl = nvlist_unpack(lun_req->args,
+ packed = malloc(lun_req->args_len, M_CTL, M_WAITOK);
+ if (copyin(lun_req->args, packed, lun_req->args_len) != 0) {
+ free(packed, M_CTL);
+ lun_req->status = CTL_LUN_ERROR;
+ snprintf(lun_req->error_str, sizeof(lun_req->error_str),
+ "Cannot copyin args.");
+ break;
+ }
+ lun_req->args_nvl = nvlist_unpack(packed,
lun_req->args_len, 0);
+ free(packed, M_CTL);
if (lun_req->args_nvl == NULL) {
lun_req->status = CTL_LUN_ERROR;
@@ -3211,8 +3220,17 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
}
if (req->args != NULL) {
- req->args_nvl = nvlist_unpack(req->args,
+ packed = malloc(req->args_len, M_CTL, M_WAITOK);
+ if (copyin(req->args, packed, req->args_len) != 0) {
+ free(packed, M_CTL);
+ req->status = CTL_LUN_ERROR;
+ snprintf(req->error_str, sizeof(req->error_str),
+ "Cannot copyin args.");
+ break;
+ }
+ req->args_nvl = nvlist_unpack(packed,
req->args_len, 0);
+ free(packed, M_CTL);
if (req->args_nvl == NULL) {
req->status = CTL_LUN_ERROR;
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 2d3766a8e73b..d5be20c2a215 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -1434,7 +1434,7 @@ cfiscsi_offline(void *arg)
struct cfiscsi_softc *softc;
struct cfiscsi_target *ct;
struct cfiscsi_session *cs;
- int online;
+ int error, online;
ct = (struct cfiscsi_target *)arg;
softc = ct->ct_softc;
@@ -1447,17 +1447,23 @@ cfiscsi_offline(void *arg)
ct->ct_online = 0;
online = --softc->online;
- TAILQ_FOREACH(cs, &softc->sessions, cs_next) {
- if (cs->cs_target == ct)
- cfiscsi_session_terminate(cs);
- }
do {
TAILQ_FOREACH(cs, &softc->sessions, cs_next) {
if (cs->cs_target == ct)
+ cfiscsi_session_terminate(cs);
+ }
+ TAILQ_FOREACH(cs, &softc->sessions, cs_next) {
+ if (cs->cs_target == ct)
break;
}
- if (cs != NULL)
- cv_wait(&softc->sessions_cv, &softc->lock);
+ if (cs != NULL) {
+ error = cv_wait_sig(&softc->sessions_cv, &softc->lock);
+ if (error != 0) {
+ CFISCSI_SESSION_DEBUG(cs,
+ "cv_wait failed with error %d\n", error);
+ break;
+ }
+ }
} while (cs != NULL && ct->ct_online == 0);
mtx_unlock(&softc->lock);
if (online > 0)
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
index b825a4c92e9c..2bc065e12509 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -661,6 +661,12 @@ typedef struct arc_stats {
* Number of bytes consumed by bonus buffers.
*/
kstat_named_t arcstat_bonus_size;
+#if defined(__FreeBSD__) && defined(COMPAT_FREEBSD11)
+ /*
+ * Sum of the previous three counters, provided for compatibility.
+ */
+ kstat_named_t arcstat_other_size;
+#endif
/*
* Total number of bytes consumed by ARC buffers residing in the
* arc_anon state. This includes *all* buffers in the arc_anon
@@ -875,6 +881,9 @@ static arc_stats_t arc_stats = {
{ "dbuf_size", KSTAT_DATA_UINT64 },
{ "dnode_size", KSTAT_DATA_UINT64 },
{ "bonus_size", KSTAT_DATA_UINT64 },
+#if defined(__FreeBSD__) && defined(COMPAT_FREEBSD11)
+ { "other_size", KSTAT_DATA_UINT64 },
+#endif
{ "anon_size", KSTAT_DATA_UINT64 },
{ "anon_evictable_data", KSTAT_DATA_UINT64 },
{ "anon_evictable_metadata", KSTAT_DATA_UINT64 },
@@ -4438,6 +4447,12 @@ arc_adjust(void)
}
/*
+ * Re-sum ARC stats after the first round of evictions.
+ */
+ asize = aggsum_value(&arc_size);
+ ameta = aggsum_value(&arc_meta_used);
+
+ /*
* Adjust MFU size
*
* Now that we've tried to evict enough from the MRU to get its
@@ -6825,6 +6840,11 @@ arc_kstat_update(kstat_t *ksp, int rw)
ARCSTAT(arcstat_bonus_size) = aggsum_value(&astat_bonus_size);
ARCSTAT(arcstat_dnode_size) = aggsum_value(&astat_dnode_size);
ARCSTAT(arcstat_dbuf_size) = aggsum_value(&astat_dbuf_size);
+#if defined(__FreeBSD__) && defined(COMPAT_FREEBSD11)
+ ARCSTAT(arcstat_other_size) = aggsum_value(&astat_bonus_size) +
+ aggsum_value(&astat_dnode_size) +
+ aggsum_value(&astat_dbuf_size);
+#endif
ARCSTAT(arcstat_l2_hdr_size) = aggsum_value(&astat_l2_hdr_size);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index ef252a32caeb..efbf36e86339 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -2496,12 +2496,11 @@ extern void dtrace_helpers_destroy(proc_t *);
#elif defined(__riscv)
-#define SD_RA_SP_MASK 0x01fff07f
-#define SD_RA_SP 0x00113023
-
#define DTRACE_INVOP_SD 1
-#define DTRACE_INVOP_RET 2
-#define DTRACE_INVOP_NOP 3
+#define DTRACE_INVOP_C_SDSP 2
+#define DTRACE_INVOP_RET 3
+#define DTRACE_INVOP_C_RET 4
+#define DTRACE_INVOP_NOP 5
#endif
diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
index 3957a1b93665..68d98db30c83 100644
--- a/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/riscv/dtrace_subr.c
@@ -19,7 +19,7 @@
*
* CDDL HEADER END
*
- * Portions Copyright 2016 Ruslan Bukin <br@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br@bsdpad.com>
*
* $FreeBSD$
*
@@ -42,8 +42,8 @@ __FBSDID("$FreeBSD$");
#include <sys/dtrace_impl.h>
#include <sys/dtrace_bsd.h>
#include <machine/vmparam.h>
+#include <machine/encoding.h>
#include <machine/riscvreg.h>
-#include <machine/riscv_opcode.h>
#include <machine/clock.h>
#include <machine/frame.h>
#include <machine/trap.h>
@@ -77,7 +77,6 @@ dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax)
return (0);
}
-
void
dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
{
@@ -238,29 +237,58 @@ dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
}
static int
+match_opcode(uint32_t insn, int match, int mask)
+{
+
+ if (((insn ^ match) & mask) == 0)
+ return (1);
+
+ return (0);
+}
+
+static int
dtrace_invop_start(struct trapframe *frame)
{
- int data, invop, reg, update_sp;
- register_t arg1, arg2;
register_t *sp;
+ uint32_t uimm;
uint32_t imm;
- InstFmt i;
- int offs;
- int tmp;
+ int invop;
invop = dtrace_invop(frame->tf_sepc, frame, frame->tf_sepc);
- if (invop == RISCV_INSN_RET) {
+ if (match_opcode(invop, (MATCH_SD | RS2_RA | RS1_SP),
+ (MASK_SD | RS2_MASK | RS1_MASK))) {
+ /* Non-compressed store of ra to sp */
+ imm = (invop >> 7) & 0x1f;
+ imm |= ((invop >> 25) & 0x7f) << 5;
+ sp = (register_t *)((uint8_t *)frame->tf_sp + imm);
+ *sp = frame->tf_ra;
+ frame->tf_sepc += INSN_SIZE;
+ return (0);
+ }
+
+ if (match_opcode(invop, (MATCH_JALR | (X_RA << RS1_SHIFT)),
+ (MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) {
+ /* Non-compressed ret */
frame->tf_sepc = frame->tf_ra;
return (0);
}
- if ((invop & SD_RA_SP_MASK) == SD_RA_SP) {
- i.word = invop;
- imm = i.SType.imm0_4 | (i.SType.imm5_11 << 5);
- sp = (register_t *)((uint8_t *)frame->tf_sp + imm);
+ if (match_opcode(invop, (MATCH_C_SDSP | RS2_C_RA),
+ (MASK_C_SDSP | RS2_C_MASK))) {
+ /* 'C'-compressed store of ra to sp */
+ uimm = ((invop >> 10) & 0x7) << 3;
+ uimm |= ((invop >> 7) & 0x7) << 6;
+ sp = (register_t *)((uint8_t *)frame->tf_sp + uimm);
*sp = frame->tf_ra;
- frame->tf_sepc += INSN_SIZE;
+ frame->tf_sepc += INSN_C_SIZE;
+ return (0);
+ }
+
+ if (match_opcode(invop, (MATCH_C_JR | (X_RA << RD_SHIFT)),
+ (MASK_C_JR | RD_MASK))) {
+ /* 'C'-compressed ret */
+ frame->tf_sepc = frame->tf_ra;
return (0);
}
diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c
index 590967ade7b3..775100c0a68b 100644
--- a/sys/cddl/dev/fbt/fbt.c
+++ b/sys/cddl/dev/fbt/fbt.c
@@ -212,7 +212,7 @@ fbt_destroy_one(fbt_probe_t *fbt)
ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
for (hash = fbt_probetab[ndx], hashprev = NULL; hash != NULL;
- hash = hash->fbtp_hashnext, hashprev = hash) {
+ hashprev = hash, hash = hash->fbtp_hashnext) {
if (hash == fbt) {
if ((next = fbt->fbtp_tracenext) != NULL)
next->fbtp_hashnext = hash->fbtp_hashnext;
diff --git a/sys/cddl/dev/fbt/riscv/fbt_isa.c b/sys/cddl/dev/fbt/riscv/fbt_isa.c
index 519784bbfcdf..4c29cee46b53 100644
--- a/sys/cddl/dev/fbt/riscv/fbt_isa.c
+++ b/sys/cddl/dev/fbt/riscv/fbt_isa.c
@@ -21,7 +21,7 @@
* Portions Copyright 2006-2008 John Birrell jb@freebsd.org
* Portions Copyright 2013 Justin Hibbits jhibbits@freebsd.org
* Portions Copyright 2013 Howard Su howardsu@freebsd.org
- * Portions Copyright 2016 Ruslan Bukin <br@bsdpad.com>
+ * Portions Copyright 2016-2018 Ruslan Bukin <br@bsdpad.com>
*
* $FreeBSD$
*/
@@ -37,10 +37,12 @@
#include <sys/dtrace.h>
#include <machine/riscvreg.h>
+#include <machine/encoding.h>
#include "fbt.h"
-#define FBT_PATCHVAL (RISCV_INSN_BREAK)
+#define FBT_C_PATCHVAL MATCH_C_EBREAK
+#define FBT_PATCHVAL MATCH_EBREAK
#define FBT_ENTRY "entry"
#define FBT_RETURN "return"
@@ -73,8 +75,62 @@ void
fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
{
- *fbt->fbtp_patchpoint = val;
- cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+ switch(fbt->fbtp_patchval) {
+ case FBT_C_PATCHVAL:
+ *(uint16_t *)fbt->fbtp_patchpoint = (uint16_t)val;
+ cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 2);
+ break;
+ case FBT_PATCHVAL:
+ *fbt->fbtp_patchpoint = val;
+ cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, 4);
+ break;
+ };
+}
+
+static int
+match_opcode(uint32_t insn, int match, int mask)
+{
+
+ if (((insn ^ match) & mask) == 0)
+ return (1);
+
+ return (0);
+}
+
+static int
+check_c_ret(uint32_t **instr)
+{
+ uint16_t *instr1;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ instr1 = (uint16_t *)(*instr) + i;
+ if (match_opcode(*instr1, (MATCH_C_JR | (X_RA << RD_SHIFT)),
+ (MASK_C_JR | RD_MASK))) {
+ *instr = (uint32_t *)instr1;
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+check_c_sdsp(uint32_t **instr)
+{
+ uint16_t *instr1;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ instr1 = (uint16_t *)(*instr) + i;
+ if (match_opcode(*instr1, (MATCH_C_SDSP | RS2_C_RA),
+ (MASK_C_SDSP | RS2_C_MASK))) {
+ *instr = (uint32_t *)instr1;
+ return (1);
+ }
+ }
+
+ return (0);
}
int
@@ -85,6 +141,8 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
uint32_t *instr, *limit;
const char *name;
char *modname;
+ int patchval;
+ int rval;
modname = opaque;
name = symval->name;
@@ -98,8 +156,20 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
/* Look for sd operation */
for (; instr < limit; instr++) {
- if ((*instr & SD_RA_SP_MASK) == SD_RA_SP)
+ /* Look for a non-compressed store of ra to sp */
+ if (match_opcode(*instr, (MATCH_SD | RS2_RA | RS1_SP),
+ (MASK_SD | RS2_MASK | RS1_MASK))) {
+ rval = DTRACE_INVOP_SD;
+ patchval = FBT_PATCHVAL;
break;
+ }
+
+ /* Look for a 'C'-compressed store of ra to sp. */
+ if (check_c_sdsp(&instr)) {
+ rval = DTRACE_INVOP_C_SDSP;
+ patchval = FBT_C_PATCHVAL;
+ break;
+ }
}
if (instr >= limit)
@@ -113,8 +183,8 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
fbt->fbtp_savedval = *instr;
- fbt->fbtp_patchval = FBT_PATCHVAL;
- fbt->fbtp_rval = DTRACE_INVOP_SD;
+ fbt->fbtp_patchval = patchval;
+ fbt->fbtp_rval = rval;
fbt->fbtp_symindx = symindx;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
@@ -125,8 +195,20 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
retfbt = NULL;
again:
for (; instr < limit; instr++) {
- if (*instr == RISCV_INSN_RET)
+ /* Look for non-compressed return */
+ if (match_opcode(*instr, (MATCH_JALR | (X_RA << RS1_SHIFT)),
+ (MASK_JALR | RD_MASK | RS1_MASK | IMM_MASK))) {
+ rval = DTRACE_INVOP_RET;
+ patchval = FBT_PATCHVAL;
break;
+ }
+
+ /* Look for 'C'-compressed return */
+ if (check_c_ret(&instr)) {
+ rval = DTRACE_INVOP_C_RET;
+ patchval = FBT_C_PATCHVAL;
+ break;
+ }
}
if (instr >= limit)
@@ -150,9 +232,9 @@ again:
fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt;
fbt->fbtp_symindx = symindx;
- fbt->fbtp_rval = DTRACE_INVOP_RET;
+ fbt->fbtp_rval = rval;
fbt->fbtp_savedval = *instr;
- fbt->fbtp_patchval = FBT_PATCHVAL;
+ fbt->fbtp_patchval = patchval;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 93bf50f9502f..0407dd30c7f1 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -134,6 +134,7 @@ amd64/amd64/db_disasm.c optional ddb
amd64/amd64/db_interface.c optional ddb
amd64/amd64/db_trace.c optional ddb
amd64/amd64/efirt_machdep.c optional efirt
+amd64/amd64/efirt_support.S optional efirt
amd64/amd64/elf_machdep.c standard
amd64/amd64/exception.S standard
amd64/amd64/fpu.c standard
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index bc4204dcd0d6..3cd293b3342f 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -132,7 +132,7 @@ INLINE_LIMIT?= 8000
.endif
.if ${MACHINE_CPUARCH} == "riscv"
-CFLAGS.gcc+= -mcmodel=medany -march=rv64imafd -mabi=lp64
+CFLAGS.gcc+= -mcmodel=medany -march=rv64imafdc -mabi=lp64
INLINE_LIMIT?= 8000
.endif
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 89d40f3ece64..9e83b6379f51 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -46,7 +46,7 @@
TYPE="FreeBSD"
REVISION="12.0"
-BRANCH="ALPHA3"
+BRANCH="ALPHA5"
if [ -n "${BRANCH_OVERRIDE}" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/contrib/rdma/krping/krping.c b/sys/contrib/rdma/krping/krping.c
index e97588382710..7b1038c27db7 100644
--- a/sys/contrib/rdma/krping/krping.c
+++ b/sys/contrib/rdma/krping/krping.c
@@ -2156,7 +2156,7 @@ int krping_doit(char *cmd)
goto out;
}
- cb->cm_id = rdma_create_id(&init_net, krping_cma_event_handler, cb, RDMA_PS_TCP, IB_QPT_RC);
+ cb->cm_id = rdma_create_id(TD_TO_VNET(curthread), krping_cma_event_handler, cb, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(cb->cm_id)) {
ret = PTR_ERR(cb->cm_id);
printk(KERN_ERR PFX "rdma_create_id error %d\n", ret);
diff --git a/sys/crypto/ccp/ccp.c b/sys/crypto/ccp/ccp.c
index f6235bc1610b..163fa748b2ef 100644
--- a/sys/crypto/ccp/ccp.c
+++ b/sys/crypto/ccp/ccp.c
@@ -734,8 +734,10 @@ DRIVER_MODULE(ccp, pci, ccp_driver, ccp_devclass, NULL, NULL);
MODULE_VERSION(ccp, 1);
MODULE_DEPEND(ccp, crypto, 1, 1, 1);
MODULE_DEPEND(ccp, random_device, 1, 1, 1);
+#if 0 /* There are enough known issues that we shouldn't load automatically */
MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, sizeof(ccp_ids[0]),
nitems(ccp_ids));
+#endif
static int
ccp_queue_reserve_space(struct ccp_queue *qp, unsigned n, int mflags)
diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c
index d48074d72d6c..5c1f7fd75d36 100644
--- a/sys/dev/efidev/efirt.c
+++ b/sys/dev/efidev/efirt.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2004 Marcel Moolenaar
* Copyright (c) 2001 Doug Rabson
- * Copyright (c) 2016 The FreeBSD Foundation
+ * Copyright (c) 2016, 2018 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Konstantin Belousov
@@ -293,22 +293,89 @@ efi_get_table(struct uuid *uuid, void **ptr)
return (ENOENT);
}
+static int efi_rt_handle_faults = EFI_RT_HANDLE_FAULTS_DEFAULT;
+SYSCTL_INT(_machdep, OID_AUTO, efi_rt_handle_faults, CTLFLAG_RWTUN,
+ &efi_rt_handle_faults, 0,
+ "Call EFI RT methods with fault handler wrapper around");
+
static int
-efi_get_time_locked(struct efi_tm *tm, struct efi_tmcap *tmcap)
+efi_rt_arch_call_nofault(struct efirt_callinfo *ec)
+{
+
+ switch (ec->ec_argcnt) {
+ case 0:
+ ec->ec_efi_status = ((register_t (*)(void))ec->ec_fptr)();
+ break;
+ case 1:
+ ec->ec_efi_status = ((register_t (*)(register_t))ec->ec_fptr)
+ (ec->ec_arg1);
+ break;
+ case 2:
+ ec->ec_efi_status = ((register_t (*)(register_t, register_t))
+ ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2);
+ break;
+ case 3:
+ ec->ec_efi_status = ((register_t (*)(register_t, register_t,
+ register_t))ec->ec_fptr)(ec->ec_arg1, ec->ec_arg2,
+ ec->ec_arg3);
+ break;
+ case 4:
+ ec->ec_efi_status = ((register_t (*)(register_t, register_t,
+ register_t, register_t))ec->ec_fptr)(ec->ec_arg1,
+ ec->ec_arg2, ec->ec_arg3, ec->ec_arg4);
+ break;
+ case 5:
+ ec->ec_efi_status = ((register_t (*)(register_t, register_t,
+ register_t, register_t, register_t))ec->ec_fptr)(
+ ec->ec_arg1, ec->ec_arg2, ec->ec_arg3, ec->ec_arg4,
+ ec->ec_arg5);
+ break;
+ default:
+ panic("efi_rt_arch_call: %d args", (int)ec->ec_argcnt);
+ }
+
+ return (0);
+}
+
+static int
+efi_call(struct efirt_callinfo *ecp)
{
- efi_status status;
int error;
- EFI_TIME_OWNED()
error = efi_enter();
if (error != 0)
return (error);
- status = efi_runtime->rt_gettime(tm, tmcap);
+ error = efi_rt_handle_faults ? efi_rt_arch_call(ecp) :
+ efi_rt_arch_call_nofault(ecp);
efi_leave();
- error = efi_status_to_errno(status);
+ if (error == 0)
+ error = efi_status_to_errno(ecp->ec_efi_status);
+ else if (bootverbose)
+ printf("EFI %s call faulted, error %d\n", ecp->ec_name, error);
return (error);
}
+#define EFI_RT_METHOD_PA(method) \
+ ((uintptr_t)((struct efi_rt *)efi_phys_to_kva((uintptr_t) \
+ efi_runtime))->method)
+
+static int
+efi_get_time_locked(struct efi_tm *tm, struct efi_tmcap *tmcap)
+{
+ struct efirt_callinfo ec;
+
+ EFI_TIME_OWNED();
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_name = "rt_gettime";
+ ec.ec_argcnt = 2;
+ ec.ec_arg1 = (uintptr_t)tm;
+ ec.ec_arg2 = (uintptr_t)tmcap;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_gettime);
+ return (efi_call(&ec));
+}
+
int
efi_get_time(struct efi_tm *tm)
{
@@ -317,7 +384,7 @@ efi_get_time(struct efi_tm *tm)
if (efi_runtime == NULL)
return (ENXIO);
- EFI_TIME_LOCK()
+ EFI_TIME_LOCK();
/*
* UEFI spec states that the Capabilities argument to GetTime is
* optional, but some UEFI implementations choke when passed a NULL
@@ -325,7 +392,7 @@ efi_get_time(struct efi_tm *tm)
* to workaround such implementations.
*/
error = efi_get_time_locked(tm, &dummy);
- EFI_TIME_UNLOCK()
+ EFI_TIME_UNLOCK();
return (error);
}
@@ -337,39 +404,44 @@ efi_get_time_capabilities(struct efi_tmcap *tmcap)
if (efi_runtime == NULL)
return (ENXIO);
- EFI_TIME_LOCK()
+ EFI_TIME_LOCK();
error = efi_get_time_locked(&dummy, tmcap);
- EFI_TIME_UNLOCK()
+ EFI_TIME_UNLOCK();
return (error);
}
int
efi_reset_system(void)
{
- int error;
+ struct efirt_callinfo ec;
- error = efi_enter();
- if (error != 0)
- return (error);
- efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL);
- efi_leave();
- return (EIO);
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_name = "rt_reset";
+ ec.ec_argcnt = 4;
+ ec.ec_arg1 = (uintptr_t)EFI_RESET_WARM;
+ ec.ec_arg2 = (uintptr_t)0;
+ ec.ec_arg3 = (uintptr_t)0;
+ ec.ec_arg4 = (uintptr_t)NULL;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_reset);
+ return (efi_call(&ec));
}
static int
efi_set_time_locked(struct efi_tm *tm)
{
- efi_status status;
- int error;
+ struct efirt_callinfo ec;
EFI_TIME_OWNED();
- error = efi_enter();
- if (error != 0)
- return (error);
- status = efi_runtime->rt_settime(tm);
- efi_leave();
- error = efi_status_to_errno(status);
- return (error);
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_name = "rt_settime";
+ ec.ec_argcnt = 1;
+ ec.ec_arg1 = (uintptr_t)tm;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_settime);
+ return (efi_call(&ec));
}
int
@@ -379,9 +451,9 @@ efi_set_time(struct efi_tm *tm)
if (efi_runtime == NULL)
return (ENXIO);
- EFI_TIME_LOCK()
+ EFI_TIME_LOCK();
error = efi_set_time_locked(tm);
- EFI_TIME_UNLOCK()
+ EFI_TIME_UNLOCK();
return (error);
}
@@ -389,47 +461,57 @@ int
efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib,
size_t *datasize, void *data)
{
- efi_status status;
- int error;
+ struct efirt_callinfo ec;
- error = efi_enter();
- if (error != 0)
- return (error);
- status = efi_runtime->rt_getvar(name, vendor, attrib, datasize, data);
- efi_leave();
- error = efi_status_to_errno(status);
- return (error);
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_argcnt = 5;
+ ec.ec_name = "rt_getvar";
+ ec.ec_arg1 = (uintptr_t)name;
+ ec.ec_arg2 = (uintptr_t)vendor;
+ ec.ec_arg3 = (uintptr_t)attrib;
+ ec.ec_arg4 = (uintptr_t)datasize;
+ ec.ec_arg5 = (uintptr_t)data;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_getvar);
+ return (efi_call(&ec));
}
int
efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor)
{
- efi_status status;
- int error;
+ struct efirt_callinfo ec;
- error = efi_enter();
- if (error != 0)
- return (error);
- status = efi_runtime->rt_scanvar(namesize, name, vendor);
- efi_leave();
- error = efi_status_to_errno(status);
- return (error);
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_argcnt = 3;
+ ec.ec_name = "rt_scanvar";
+ ec.ec_arg1 = (uintptr_t)namesize;
+ ec.ec_arg2 = (uintptr_t)name;
+ ec.ec_arg3 = (uintptr_t)vendor;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_scanvar);
+ return (efi_call(&ec));
}
int
efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib,
size_t datasize, void *data)
{
- efi_status status;
- int error;
+ struct efirt_callinfo ec;
- error = efi_enter();
- if (error != 0)
- return (error);
- status = efi_runtime->rt_setvar(name, vendor, attrib, datasize, data);
- efi_leave();
- error = efi_status_to_errno(status);
- return (error);
+ if (efi_runtime == NULL)
+ return (ENXIO);
+ bzero(&ec, sizeof(ec));
+ ec.ec_argcnt = 5;
+ ec.ec_name = "rt_setvar";
+ ec.ec_arg1 = (uintptr_t)name;
+ ec.ec_arg2 = (uintptr_t)vendor;
+ ec.ec_arg3 = (uintptr_t)attrib;
+ ec.ec_arg4 = (uintptr_t)datasize;
+ ec.ec_arg5 = (uintptr_t)data;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_setvar);
+ return (efi_call(&ec));
}
static int
diff --git a/sys/dev/efidev/efirtc.c b/sys/dev/efidev/efirtc.c
index b9e06bcc362e..e5a2ec262bf5 100644
--- a/sys/dev/efidev/efirtc.c
+++ b/sys/dev/efidev/efirtc.c
@@ -74,7 +74,8 @@ efirtc_probe(device_t dev)
*/
if ((error = efi_get_time(&tm)) != 0) {
if (bootverbose)
- device_printf(dev, "cannot read EFI realtime clock\n");
+ device_printf(dev, "cannot read EFI realtime clock, "
+ "error %d\n", error);
return (error);
}
device_set_desc(dev, "EFI Realtime Clock");
diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c
index ef6e5216d7c5..079612a46957 100644
--- a/sys/dev/extres/regulator/regulator.c
+++ b/sys/dev/extres/regulator/regulator.c
@@ -172,7 +172,7 @@ regulator_shutdown(void *dummy)
REG_TOPO_SLOCK();
TUNABLE_INT_FETCH("hw.regulator.disable_unused", &disable);
TAILQ_FOREACH(entry, &regnode_list, reglist_link) {
- if (entry->std_param.always_on == 0 && disable) {
+ if (!entry->std_param.always_on && disable) {
if (bootverbose)
printf("regulator: shutting down %s\n",
entry->name);
@@ -595,8 +595,9 @@ regnode_disable(struct regnode *regnode)
REGNODE_XLOCK(regnode);
/* Disable regulator for each node in chain, starting from consumer. */
- if ((regnode->enable_cnt == 1) &&
- ((regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0)) {
+ if (regnode->enable_cnt == 1 &&
+ (regnode->flags & REGULATOR_FLAGS_NOT_DISABLE) == 0 &&
+ !regnode->std_param.always_on) {
rv = REGNODE_ENABLE(regnode, false, &udelay);
if (rv != 0) {
REGNODE_UNLOCK(regnode);
@@ -1048,10 +1049,10 @@ regulator_parse_ofw_stdparam(device_t pdev, phandle_t node,
par->enable_delay = 0;
if (OF_hasprop(node, "regulator-boot-on"))
- par->boot_on = 1;
+ par->boot_on = true;
if (OF_hasprop(node, "regulator-always-on"))
- par->always_on = 1;
+ par->always_on = true;
if (OF_hasprop(node, "enable-active-high"))
par->enable_active_high = 1;
diff --git a/sys/dev/intel/spi.c b/sys/dev/intel/spi.c
index 9b229bb74123..e9b9bfc46fb0 100644
--- a/sys/dev/intel/spi.c
+++ b/sys/dev/intel/spi.c
@@ -480,7 +480,7 @@ error:
sc->sc_mem_rid, sc->sc_mem_res);
if (sc->sc_irq_res != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY,
+ bus_release_resource(dev, SYS_RES_IRQ,
sc->sc_irq_rid, sc->sc_irq_res);
return (ENXIO);
@@ -503,10 +503,10 @@ intelspi_detach(device_t dev)
sc->sc_mem_rid, sc->sc_mem_res);
if (sc->sc_irq_res != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY,
+ bus_release_resource(dev, SYS_RES_IRQ,
sc->sc_irq_rid, sc->sc_irq_res);
- return (0);
+ return (bus_generic_detach(dev));
}
static device_method_t intelspi_methods[] = {
diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index e1fb720511fb..a6a3465b60d7 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -1470,6 +1470,7 @@ ixv_initialize_receive_units(if_ctx_t ctx)
static void
ixv_setup_vlan_support(if_ctx_t ctx)
{
+ struct ifnet *ifp = iflib_get_ifp(ctx);
struct adapter *adapter = iflib_get_softc(ctx);
struct ixgbe_hw *hw = &adapter->hw;
u32 ctrl, vid, vfta, retry;
@@ -1483,19 +1484,28 @@ ixv_setup_vlan_support(if_ctx_t ctx)
if (adapter->num_vlans == 0)
return;
- /* Enable the queues */
- for (int i = 0; i < adapter->num_rx_queues; i++) {
- ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
- ctrl |= IXGBE_RXDCTL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl);
- /*
- * Let Rx path know that it needs to store VLAN tag
- * as part of extra mbuf info.
- */
- adapter->rx_queues[i].rxr.vtag_strip = TRUE;
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ /* Enable the queues */
+ for (int i = 0; i < adapter->num_rx_queues; i++) {
+ ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
+ ctrl |= IXGBE_RXDCTL_VME;
+ IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl);
+ /*
+ * Let Rx path know that it needs to store VLAN tag
+ * as part of extra mbuf info.
+ */
+ adapter->rx_queues[i].rxr.vtag_strip = TRUE;
+ }
}
/*
+ * If filtering VLAN tags is disabled,
+ * there is no need to fill VLAN Filter Table Array (VFTA).
+ */
+ if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0)
+ return;
+
+ /*
* A soft reset zero's out the VFTA, so
* we need to repopulate it now.
*/
diff --git a/sys/dev/ixgbe/ix_txrx.c b/sys/dev/ixgbe/ix_txrx.c
index 3fef6c5889d1..91c92c56a6df 100644
--- a/sys/dev/ixgbe/ix_txrx.c
+++ b/sys/dev/ixgbe/ix_txrx.c
@@ -430,7 +430,8 @@ ixgbe_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
rxd->wb.upper.status_error = 0;
eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
- if (staterr & IXGBE_RXD_STAT_VP) {
+
+ if ( (rxr->vtag_strip) && (staterr & IXGBE_RXD_STAT_VP) ) {
vtag = le16toh(rxd->wb.upper.vlan);
} else {
vtag = 0;
diff --git a/sys/dev/mlx5/driver.h b/sys/dev/mlx5/driver.h
index 82c96ae42278..15bcb3cc3ae4 100644
--- a/sys/dev/mlx5/driver.h
+++ b/sys/dev/mlx5/driver.h
@@ -682,6 +682,9 @@ struct mlx5_core_dev {
struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
u32 num_q_counter_allocated[MLX5_INTERFACE_NUMBER];
struct mlx5_dump_data *dump_data;
+
+ struct sysctl_ctx_list sysctl_ctx;
+ int msix_eqvec;
};
enum {
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_main.c b/sys/dev/mlx5/mlx5_core/mlx5_main.c
index d443433f67cf..df18c11121b3 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_main.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_main.c
@@ -61,10 +61,6 @@ static int prof_sel = MLX5_DEFAULT_PROF;
module_param_named(prof_sel, prof_sel, int, 0444);
MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
-static int mlx5_core_msix_eqvec;
-module_param_named(msix_eqvec, mlx5_core_msix_eqvec, int, 0644);
-MODULE_PARM_DESC(msix_eqvec, "Maximum number of MSIX event queue vectors");
-
#define NUMA_NO_NODE -1
static LIST_HEAD(intf_list);
@@ -243,7 +239,7 @@ static int mlx5_enable_msix(struct mlx5_core_dev *dev)
struct mlx5_priv *priv = &dev->priv;
struct mlx5_eq_table *table = &priv->eq_table;
int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
- int limit = mlx5_core_msix_eqvec;
+ int limit = dev->msix_eqvec;
int nvec = MLX5_EQ_VEC_COMP_BASE;
int i;
@@ -1206,6 +1202,7 @@ static int init_one(struct pci_dev *pdev,
{
struct mlx5_core_dev *dev;
struct mlx5_priv *priv;
+ device_t bsddev = pdev->dev.bsddev;
int err;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1221,6 +1218,12 @@ static int init_one(struct pci_dev *pdev,
dev->pdev = pdev;
dev->event = mlx5_core_event;
+ sysctl_ctx_init(&dev->sysctl_ctx);
+ SYSCTL_ADD_INT(&dev->sysctl_ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(bsddev)),
+ OID_AUTO, "msix_eqvec", CTLFLAG_RDTUN, &dev->msix_eqvec, 0,
+ "Maximum number of MSIX event queue vectors, if set");
+
INIT_LIST_HEAD(&priv->ctx_list);
spin_lock_init(&priv->ctx_lock);
mutex_init(&dev->pci_status_mutex);
@@ -1256,6 +1259,7 @@ clean_health:
close_pci:
mlx5_pci_close(dev, priv);
clean_dev:
+ sysctl_ctx_free(&dev->sysctl_ctx);
kfree(dev);
return err;
}
@@ -1276,6 +1280,7 @@ static void remove_one(struct pci_dev *pdev)
mlx5_health_cleanup(dev);
mlx5_pci_close(dev, priv);
pci_set_drvdata(pdev, NULL);
+ sysctl_ctx_free(&dev->sysctl_ctx);
kfree(dev);
}
diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
index f125313cd7b9..73f0268ca270 100644
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -123,7 +123,8 @@
#define MLX5E_MAX_TX_MBUF_SIZE 65536 /* bytes */
#define MLX5E_MAX_TX_MBUF_FRAGS \
((MLX5_SEND_WQE_MAX_WQEBBS * MLX5_SEND_WQEBB_NUM_DS) - \
- (MLX5E_MAX_TX_HEADER / MLX5_SEND_WQE_DS)) /* units */
+ (MLX5E_MAX_TX_HEADER / MLX5_SEND_WQE_DS) - \
+ 1 /* the maximum value of the DS counter is 0x3F and not 0x40 */) /* units */
#define MLX5E_MAX_TX_INLINE \
(MLX5E_MAX_TX_HEADER - sizeof(struct mlx5e_tx_wqe) + \
sizeof(((struct mlx5e_tx_wqe *)0)->eth.inline_hdr_start)) /* bytes */
@@ -453,6 +454,7 @@ struct mlx5e_params {
u32 rx_priority_flow_control __aligned(4);
u16 tx_max_inline;
u8 tx_min_inline_mode;
+ u8 channels_rsss;
};
#define MLX5E_PARAMS(m) \
@@ -461,6 +463,7 @@ struct mlx5e_params {
m(+1, u64 tx_queue_size, "tx_queue_size", "Default send queue size") \
m(+1, u64 rx_queue_size, "rx_queue_size", "Default receive queue size") \
m(+1, u64 channels, "channels", "Default number of channels") \
+ m(+1, u64 channels_rsss, "channels_rsss", "Default channels receive side scaling stride") \
m(+1, u64 coalesce_usecs_max, "coalesce_usecs_max", "Maximum usecs for joining packets") \
m(+1, u64 coalesce_pkts_max, "coalesce_pkts_max", "Maximum packets to join") \
m(+1, u64 rx_coalesce_usecs, "rx_coalesce_usecs", "Limit in usec for joining rx packets") \
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
index d85afb570872..85b1fe85617f 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_ethtool.c
@@ -493,6 +493,24 @@ mlx5e_ethtool_handler(SYSCTL_HANDLER_ARGS)
mlx5e_open_locked(priv->ifp);
break;
+ case MLX5_PARAM_OFFSET(channels_rsss):
+ /* network interface must be down */
+ if (was_opened)
+ mlx5e_close_locked(priv->ifp);
+
+ /* import number of channels */
+ if (priv->params_ethtool.channels_rsss < 1)
+ priv->params_ethtool.channels_rsss = 1;
+ else if (priv->params_ethtool.channels_rsss > 128)
+ priv->params_ethtool.channels_rsss = 128;
+
+ priv->params.channels_rsss = priv->params_ethtool.channels_rsss;
+
+ /* restart network interface, if any */
+ if (was_opened)
+ mlx5e_open_locked(priv->ifp);
+ break;
+
case MLX5_PARAM_OFFSET(channels):
/* network interface must be down */
if (was_opened)
@@ -1041,6 +1059,7 @@ mlx5e_create_ethtool(struct mlx5e_priv *priv)
priv->params_ethtool.tx_queue_size = 1 << priv->params.log_sq_size;
priv->params_ethtool.rx_queue_size = 1 << priv->params.log_rq_size;
priv->params_ethtool.channels = priv->params.num_channels;
+ priv->params_ethtool.channels_rsss = priv->params.channels_rsss;
priv->params_ethtool.coalesce_pkts_max = MLX5E_FLD_MAX(cqc, cq_max_count);
priv->params_ethtool.coalesce_usecs_max = MLX5E_FLD_MAX(cqc, cq_period);
priv->params_ethtool.rx_coalesce_mode = priv->params.rx_cq_moderation_mode;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
index 08a0e98fa0fb..916ebe72c46c 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -2204,14 +2204,16 @@ mlx5e_open_rqt(struct mlx5e_priv *priv)
MLX5_SET(rqtc, rqtc, rqt_max_size, sz);
for (i = 0; i < sz; i++) {
- int ix;
+ int ix = i;
#ifdef RSS
- ix = rss_get_indirection_to_bucket(i);
-#else
- ix = i;
+ ix = rss_get_indirection_to_bucket(ix);
#endif
/* ensure we don't overflow */
ix %= priv->params.num_channels;
+
+ /* apply receive side scaling stride, if any */
+ ix -= ix % (int)priv->params.channels_rsss;
+
MLX5_SET(rqtc, rqtc, rq_num[i], priv->channel[ix]->rq.rqn);
}
@@ -3083,6 +3085,7 @@ mlx5e_build_ifp_priv(struct mlx5_core_dev *mdev,
priv->mdev = mdev;
priv->params.num_channels = num_comp_vectors;
+ priv->params.channels_rsss = 1;
priv->order_base_2_num_channels = order_base_2(num_comp_vectors);
priv->queue_mapping_channel_mask =
roundup_pow_of_two(num_comp_vectors) - 1;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
index 71dca59e795a..40d8157c6771 100644
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
@@ -528,13 +528,11 @@ mlx5e_xmit_locked(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
/* Process the queue */
while ((next = drbr_peek(ifp, sq->br)) != NULL) {
if (mlx5e_sq_xmit(sq, &next) != 0) {
- if (next == NULL) {
- drbr_advance(ifp, sq->br);
- } else {
+ if (next != NULL) {
drbr_putback(ifp, sq->br, next);
atomic_store_rel_int(&sq->queue_state, MLX5E_SQ_FULL);
+ break;
}
- break;
}
drbr_advance(ifp, sq->br);
}
diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c
index d07a914a00cc..cf5cacbf0fe6 100644
--- a/sys/dev/mmc/mmc.c
+++ b/sys/dev/mmc/mmc.c
@@ -1591,6 +1591,7 @@ mmc_discover_cards(struct mmc_softc *sc)
int err, host_caps, i, newcard;
uint32_t resp, sec_count, status;
uint16_t rca = 2;
+ int16_t rev;
uint8_t card_type;
host_caps = mmcbr_get_caps(sc->dev);
@@ -1779,6 +1780,7 @@ mmc_discover_cards(struct mmc_softc *sc)
goto free_ivar;
}
+ rev = -1;
/* Only MMC >= 4.x devices support EXT_CSD. */
if (ivar->csd.spec_vers >= 4) {
err = mmc_send_ext_csd(sc->dev, sc->dev,
@@ -1789,6 +1791,7 @@ mmc_discover_cards(struct mmc_softc *sc)
goto free_ivar;
}
ext_csd = ivar->raw_ext_csd;
+ rev = ext_csd[EXT_CSD_REV];
/* Handle extended capacity from EXT_CSD */
sec_count = le32dec(&ext_csd[EXT_CSD_SEC_CNT]);
if (sec_count != 0) {
@@ -1859,7 +1862,7 @@ mmc_discover_cards(struct mmc_softc *sc)
* units of 10 ms), defaulting to 500 ms.
*/
ivar->cmd6_time = 500 * 1000;
- if (ext_csd[EXT_CSD_REV] >= 6)
+ if (rev >= 6)
ivar->cmd6_time = 10 *
ext_csd[EXT_CSD_GEN_CMD6_TIME];
/* Handle HC erase sector size. */
@@ -1880,8 +1883,7 @@ mmc_discover_cards(struct mmc_softc *sc)
}
}
- mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid,
- ext_csd[EXT_CSD_REV] >= 5);
+ mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid, rev >= 5);
child_common:
for (quirk = &mmc_quirks[0]; quirk->mid != 0x0; quirk++) {
diff --git a/sys/dev/pci/pci_user.c b/sys/dev/pci/pci_user.c
index 4053e193b012..4e40a8167362 100644
--- a/sys/dev/pci/pci_user.c
+++ b/sys/dev/pci/pci_user.c
@@ -446,6 +446,14 @@ pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches,
}
}
+/*
+ * Like PVE_NEXT but takes an explicit length since 'pve' is a user
+ * pointer that cannot be dereferenced.
+ */
+#define PVE_NEXT_LEN(pve, datalen) \
+ ((struct pci_vpd_element *)((char *)(pve) + \
+ sizeof(struct pci_vpd_element) + (datalen)))
+
static int
pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
{
@@ -494,7 +502,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
strlen(vpd->vpd_ident));
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
vpd_element.pve_flags = 0;
for (i = 0; i < vpd->vpd_rocnt; i++) {
vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0];
@@ -507,7 +515,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
vpd->vpd_ros[i].len);
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
}
vpd_element.pve_flags = PVE_FLAG_RW;
for (i = 0; i < vpd->vpd_wcnt; i++) {
@@ -521,7 +529,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
vpd->vpd_w[i].len);
if (error)
return (error);
- vpd_user = PVE_NEXT(vpd_user);
+ vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen);
}
KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len,
("length mismatch"));
diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c
index c7bb97c3a0fe..94bd2f1a4147 100644
--- a/sys/dev/random/randomdev.c
+++ b/sys/dev/random/randomdev.c
@@ -156,6 +156,10 @@ READ_RANDOM_UIO(struct uio *uio, bool nonblock)
error = tsleep(&random_alg_context, PCATCH, "randseed", hz/10);
if (error == ERESTART || error == EINTR)
break;
+ /* Squash tsleep timeout condition */
+ if (error == EWOULDBLOCK)
+ error = 0;
+ KASSERT(error == 0, ("unexpected tsleep error %d", error));
}
if (error == 0) {
read_rate_increment((uio->uio_resid + sizeof(uint32_t))/sizeof(uint32_t));
@@ -184,9 +188,13 @@ READ_RANDOM_UIO(struct uio *uio, bool nonblock)
* uninterruptible syscalls.
*/
if (error == 0 && uio->uio_resid != 0 &&
- total_read % sigchk_period == 0)
+ total_read % sigchk_period == 0) {
error = tsleep_sbt(&random_alg_context, PCATCH,
"randrd", SBT_1NS, 0, C_HARDCLOCK);
+ /* Squash tsleep timeout condition */
+ if (error == EWOULDBLOCK)
+ error = 0;
+ }
}
if (error == ERESTART || error == EINTR)
error = 0;
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
index 2a3ce12ea63d..f117fb49c88d 100644
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -1575,11 +1575,10 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, struct mmc_data *data)
#ifdef MMCCAM
slot->ccb->mmcio.stop.opcode == MMC_STOP_TRANSMISSION &&
#else
- slot->req->stop &&
+ slot->req->stop != NULL &&
#endif
!(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)))
mode |= SDHCI_TRNS_ACMD12;
-
}
if (data->flags & MMC_DATA_READ)
mode |= SDHCI_TRNS_READ;
diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c
index 325106200320..7ccc9da533de 100644
--- a/sys/dev/sound/midi/midi.c
+++ b/sys/dev/sound/midi/midi.c
@@ -1467,18 +1467,14 @@ midi_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
retval = midi_load();
-#if 0
if (retval == 0)
retval = seq_modevent(mod, type, data);
-#endif
break;
case MOD_UNLOAD:
retval = midi_unload();
-#if 0
if (retval == 0)
retval = seq_modevent(mod, type, data);
-#endif
break;
default:
diff --git a/sys/dev/sound/pci/csamidi.c b/sys/dev/sound/pci/csamidi.c
new file mode 100644
index 000000000000..21543e736e9f
--- /dev/null
+++ b/sys/dev/sound/pci/csamidi.c
@@ -0,0 +1,290 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+
+ * Copyright (c) 2015-2018 Tai-hwa Liang <avatar@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.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+#include <sys/kobj.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_snd.h"
+#endif
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/sound/chip.h>
+#include <dev/sound/pcm/sound.h>
+
+#include <dev/sound/midi/midi.h>
+#include <dev/sound/midi/mpu401.h>
+
+#include <dev/sound/pci/csareg.h>
+#include <dev/sound/pci/csavar.h>
+
+#include "mpufoi_if.h"
+
+SND_DECLARE_FILE("$FreeBSD$");
+
+/* pulled from mpu401.c */
+#define MPU_DATAPORT 0
+#define MPU_CMDPORT 1
+#define MPU_STATPORT 1
+#define MPU_RESET 0xff
+#define MPU_UART 0x3f
+#define MPU_ACK 0xfe
+#define MPU_STATMASK 0xc0
+#define MPU_OUTPUTBUSY 0x40
+#define MPU_INPUTBUSY 0x80
+
+/* device private data */
+struct csa_midi_softc {
+ /* hardware resources */
+ int io_rid; /* io rid */
+ struct resource *io; /* io */
+
+ struct mtx mtx;
+ device_t dev;
+ struct mpu401 *mpu;
+ mpu401_intr_t *mpu_intr;
+ int mflags; /* MIDI flags */
+};
+
+static struct kobj_class csamidi_mpu_class;
+static devclass_t midicsa_devclass;
+
+static u_int32_t
+csamidi_readio(struct csa_midi_softc *scp, u_long offset)
+{
+ if (offset < BA0_AC97_RESET)
+ return bus_space_read_4(rman_get_bustag(scp->io), rman_get_bushandle(scp->io), offset) & 0xffffffff;
+ else
+ return (0);
+}
+
+static void
+csamidi_writeio(struct csa_midi_softc *scp, u_long offset, u_int32_t data)
+{
+ if (offset < BA0_AC97_RESET)
+ bus_space_write_4(rman_get_bustag(scp->io), rman_get_bushandle(scp->io), offset, data);
+}
+
+static void
+csamidi_midi_intr(void *arg)
+{
+ struct csa_midi_softc *scp = (struct csa_midi_softc *)arg;
+
+ if (scp->mpu_intr)
+ (scp->mpu_intr)(scp->mpu);
+}
+
+static unsigned char
+csamidi_mread(struct mpu401 *arg __unused, void *cookie, int reg)
+{
+ struct csa_midi_softc *scp = cookie;
+ unsigned int rc;
+ unsigned int uart_stat;
+
+ rc = 0;
+ /* hacks to convert hardware status to MPU compatible ones */
+ switch (reg) {
+ case MPU_STATPORT:
+ uart_stat = csamidi_readio(scp, BA0_MIDSR);
+ if (uart_stat & MIDSR_TBF)
+ rc |= MPU_OUTPUTBUSY; /* Tx buffer full */
+ if (uart_stat & MIDSR_RBE)
+ rc |= MPU_INPUTBUSY;
+ break;
+ case MPU_DATAPORT:
+ rc = csamidi_readio(scp, BA0_MIDRP);
+ break;
+ default:
+ printf("csamidi_mread: unknown register %d\n", reg);
+ break;
+ }
+ return (rc);
+}
+
+static void
+csamidi_mwrite(struct mpu401 *arg __unused, void *cookie, int reg, unsigned char b)
+{
+ struct csa_midi_softc *scp = cookie;
+ unsigned int val;
+
+ switch (reg) {
+ case MPU_CMDPORT:
+ switch (b)
+ {
+ case MPU_RESET:
+ /* preserve current operation mode */
+ val = csamidi_readio(scp, BA0_MIDCR);
+ /* reset the MIDI port */
+ csamidi_writeio(scp, BA0_MIDCR, MIDCR_MRST);
+ csamidi_writeio(scp, BA0_MIDCR, MIDCR_MLB);
+ csamidi_writeio(scp, BA0_MIDCR, 0x00);
+ /* restore previous operation mode */
+ csamidi_writeio(scp, BA0_MIDCR, val);
+ break;
+ case MPU_UART:
+ /* switch to UART mode, no-op */
+ default:
+ break;
+ }
+ break;
+ case MPU_DATAPORT:
+ /* put the MIDI databyte in the write port */
+ csamidi_writeio(scp, BA0_MIDWP, b);
+ break;
+ default:
+ printf("csamidi_mwrite: unknown register %d\n", reg);
+ break;
+ }
+}
+
+static int
+csamidi_muninit(struct mpu401 *arg __unused, void *cookie)
+{
+ struct csa_midi_softc *scp = cookie;
+
+ mtx_lock(&scp->mtx);
+ scp->mpu_intr = NULL;
+ mtx_unlock(&scp->mtx);
+
+ return (0);
+}
+
+static int
+midicsa_probe(device_t dev)
+{
+ struct sndcard_func *func;
+
+ /* The parent device has already been probed. */
+
+ func = device_get_ivars(dev);
+ if (func == NULL || func->func != SCF_MIDI)
+ return (ENXIO);
+
+ device_set_desc(dev, "CS461x MIDI");
+ return (0);
+}
+
+static int
+midicsa_attach(device_t dev)
+{
+ struct csa_midi_softc *scp;
+ struct sndcard_func *func;
+ int rc = ENXIO;
+
+ scp = device_get_softc(dev);
+ func = device_get_ivars(dev);
+
+ bzero(scp, sizeof(struct csa_midi_softc));
+ scp->dev = dev;
+
+ /* allocate the required resources */
+ scp->io_rid = PCIR_BAR(0);
+ scp->io = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &scp->io_rid, RF_ACTIVE);
+ if (scp->io == NULL)
+ goto err0;
+
+ /* init the fake MPU401 interface. */
+ scp->mpu = mpu401_init(&csamidi_mpu_class, scp, csamidi_midi_intr,
+ &scp->mpu_intr);
+ if (scp->mpu == NULL) {
+ rc = ENOMEM;
+ goto err1;
+ }
+
+ mtx_init(&scp->mtx, device_get_nameunit(dev), "csamidi softc",
+ MTX_DEF);
+
+ /* reset the MIDI port */
+ csamidi_writeio(scp, BA0_MIDCR, MIDCR_MRST);
+ /* MIDI transmit enable, no interrupt */
+ csamidi_writeio(scp, BA0_MIDCR, MIDCR_TXE | MIDCR_RXE);
+ csamidi_writeio(scp, BA0_HICR, HICR_IEV | HICR_CHGM);
+
+ return (0);
+err1:
+ bus_release_resource(dev, SYS_RES_MEMORY, scp->io_rid, scp->io);
+ scp->io = NULL;
+err0:
+ return (rc);
+}
+
+static int
+midicsa_detach(device_t dev)
+{
+ struct csa_midi_softc *scp;
+ int rc = 0;
+
+ scp = device_get_softc(dev);
+ rc = mpu401_uninit(scp->mpu);
+ if (rc)
+ return (rc);
+ if (scp->io != NULL) {
+ bus_release_resource(dev, SYS_RES_MEMORY, scp->io_rid,
+ scp->io);
+ scp->io = NULL;
+ }
+ mtx_destroy(&scp->mtx);
+ return (rc);
+}
+
+static kobj_method_t csamidi_mpu_methods[] = {
+ KOBJMETHOD(mpufoi_read, csamidi_mread),
+ KOBJMETHOD(mpufoi_write, csamidi_mwrite),
+ KOBJMETHOD(mpufoi_uninit, csamidi_muninit),
+ KOBJMETHOD_END
+};
+
+static DEFINE_CLASS(csamidi_mpu, csamidi_mpu_methods, 0);
+
+static device_method_t midicsa_methods[] = {
+ DEVMETHOD(device_probe, midicsa_probe),
+ DEVMETHOD(device_attach, midicsa_attach),
+ DEVMETHOD(device_detach, midicsa_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t midicsa_driver = {
+ "midi",
+ midicsa_methods,
+ sizeof(struct csa_midi_softc),
+};
+DRIVER_MODULE(snd_csa_midi, csa, midicsa_driver, midicsa_devclass, 0, 0);
+MODULE_DEPEND(snd_csa_midi, snd_csa, 1, 1, 1);
+MODULE_DEPEND(snd_csa_midi, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+MODULE_VERSION(snd_csa_midi, 1);
diff --git a/sys/dev/usb/input/wmt.c b/sys/dev/usb/input/wmt.c
index 226023a57bfd..c5b774244ece 100644
--- a/sys/dev/usb/input/wmt.c
+++ b/sys/dev/usb/input/wmt.c
@@ -521,7 +521,7 @@ tr_ignore:
case USB_ST_SETUP:
tr_setup:
- usbd_xfer_set_frame_len(xfer, 0, sc->isize);
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
usbd_transfer_submit(xfer);
break;
default:
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index f3c68c408bb7..d8a3796f91de 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -421,81 +421,8 @@ initclocks(void *dummy)
#endif
}
-/*
- * Each time the real-time timer fires, this function is called on all CPUs.
- * Note that hardclock() calls hardclock_cpu() for the boot CPU, so only
- * the other CPUs in the system need to call this function.
- */
void
-hardclock_cpu(int usermode)
-{
- struct pstats *pstats;
- struct thread *td = curthread;
- struct proc *p = td->td_proc;
- int flags;
-
- /*
- * Run current process's virtual and profile time, as needed.
- */
- pstats = p->p_stats;
- flags = 0;
- if (usermode &&
- timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
- PROC_ITIMLOCK(p);
- if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0)
- flags |= TDF_ALRMPEND | TDF_ASTPENDING;
- PROC_ITIMUNLOCK(p);
- }
- if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
- PROC_ITIMLOCK(p);
- if (itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0)
- flags |= TDF_PROFPEND | TDF_ASTPENDING;
- PROC_ITIMUNLOCK(p);
- }
- thread_lock(td);
- td->td_flags |= flags;
- thread_unlock(td);
-
-#ifdef HWPMC_HOOKS
- if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid)))
- PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL);
- if (td->td_intr_frame != NULL)
- PMC_SOFT_CALL_TF( , , clock, hard, td->td_intr_frame);
-#endif
- callout_process(sbinuptime());
- if (__predict_false(DPCPU_GET(epoch_cb_count)))
- GROUPTASK_ENQUEUE(DPCPU_PTR(epoch_cb_task));
-}
-
-/*
- * The real-time timer, interrupting hz times per second.
- */
-void
-hardclock(int usermode, uintfptr_t pc)
-{
-
- atomic_add_int(&ticks, 1);
- hardclock_cpu(usermode);
- tc_ticktock(1);
- cpu_tick_calibration();
- /*
- * If no separate statistics clock is available, run it from here.
- *
- * XXX: this only works for UP
- */
- if (stathz == 0) {
- profclock(usermode, pc);
- statclock(usermode);
- }
-#ifdef DEVICE_POLLING
- hardclock_device_poll(); /* this is very short and quick */
-#endif /* DEVICE_POLLING */
- if (watchdog_enabled > 0 && --watchdog_ticks <= 0)
- watchdog_fire();
-}
-
-void
-hardclock_cnt(int cnt, int usermode)
+hardclock(int cnt, int usermode)
{
struct pstats *pstats;
struct thread *td = curthread;
@@ -696,14 +623,7 @@ stopprofclock(struct proc *p)
* This should be called by all active processors.
*/
void
-statclock(int usermode)
-{
-
- statclock_cnt(1, usermode);
-}
-
-void
-statclock_cnt(int cnt, int usermode)
+statclock(int cnt, int usermode)
{
struct rusage *ru;
struct vmspace *vm;
@@ -776,14 +696,7 @@ statclock_cnt(int cnt, int usermode)
}
void
-profclock(int usermode, uintfptr_t pc)
-{
-
- profclock_cnt(1, usermode, pc);
-}
-
-void
-profclock_cnt(int cnt, int usermode, uintfptr_t pc)
+profclock(int cnt, int usermode, uintfptr_t pc)
{
struct thread *td;
#ifdef GPROF
diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c
index ed7b67f62cf6..dfc9081ba9f6 100644
--- a/sys/kern/kern_clocksource.c
+++ b/sys/kern/kern_clocksource.c
@@ -183,7 +183,7 @@ handleevents(sbintime_t now, int fake)
hct = DPCPU_PTR(hardclocktime);
*hct = state->nexthard - tick_sbt;
if (fake < 2) {
- hardclock_cnt(runs, usermode);
+ hardclock(runs, usermode);
done = 1;
}
}
@@ -193,7 +193,7 @@ handleevents(sbintime_t now, int fake)
runs++;
}
if (runs && fake < 2) {
- statclock_cnt(runs, usermode);
+ statclock(runs, usermode);
done = 1;
}
if (profiling) {
@@ -203,7 +203,7 @@ handleevents(sbintime_t now, int fake)
runs++;
}
if (runs && !fake) {
- profclock_cnt(runs, usermode, TRAPF_PC(frame));
+ profclock(runs, usermode, TRAPF_PC(frame));
done = 1;
}
} else
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 79b34dc76499..b60c2d5b40ef 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -83,7 +83,7 @@ _Static_assert(offsetof(struct thread, td_pflags) == 0x104,
"struct thread KBI td_pflags");
_Static_assert(offsetof(struct thread, td_frame) == 0x470,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x518,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x528,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0xb0,
"struct proc KBI p_flag");
diff --git a/sys/kern/subr_blist.c b/sys/kern/subr_blist.c
index d77d12997a57..db7df6932633 100644
--- a/sys/kern/subr_blist.c
+++ b/sys/kern/subr_blist.c
@@ -224,17 +224,19 @@ blist_create(daddr_t blocks, int flags)
u_daddr_t nodes, radix, skip;
int digit;
+ if (blocks == 0)
+ panic("invalid block count");
+
/*
- * Calculate the radix and node count used for scanning. Find the last
- * block that is followed by a terminator.
+ * Calculate the radix and node count used for scanning.
*/
last_block = blocks - 1;
radix = BLIST_BMAP_RADIX;
while (radix < blocks) {
if (((last_block / radix + 1) & BLIST_META_MASK) != 0)
/*
- * A terminator will be added. Update last_block to the
- * position just before that terminator.
+ * We must widen the blist to avoid partially
+ * filled nodes.
*/
last_block |= radix - 1;
radix *= BLIST_META_RADIX;
@@ -244,7 +246,9 @@ blist_create(daddr_t blocks, int flags)
* Count the meta-nodes in the expanded tree, including the final
* terminator, from the bottom level up to the root.
*/
- nodes = (last_block >= blocks) ? 2 : 1;
+ nodes = 1;
+ if (radix - blocks >= BLIST_BMAP_RADIX)
+ nodes++;
last_block /= BLIST_BMAP_RADIX;
while (last_block > 0) {
nodes += last_block + 1;
diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c
index 82c276f210a2..1c3a9804694c 100644
--- a/sys/kern/subr_rtc.c
+++ b/sys/kern/subr_rtc.c
@@ -138,6 +138,7 @@ settime_task_func(void *arg, int pending)
{
struct timespec ts;
struct rtc_instance *rtc;
+ int error;
rtc = arg;
if (!(rtc->flags & CLOCKF_SETTIME_NO_TS)) {
@@ -150,7 +151,9 @@ settime_task_func(void *arg, int pending)
ts.tv_sec = 0;
ts.tv_nsec = 0;
}
- CLOCK_SETTIME(rtc->clockdev, &ts);
+ error = CLOCK_SETTIME(rtc->clockdev, &ts);
+ if (error != 0 && bootverbose)
+ device_printf(rtc->clockdev, "CLOCK_SETTIME error %d\n", error);
}
static void
diff --git a/sys/mips/conf/MALTA64EL b/sys/mips/conf/MALTA64EL
index 5b87b6e171f4..34df1da7146c 100644
--- a/sys/mips/conf/MALTA64EL
+++ b/sys/mips/conf/MALTA64EL
@@ -9,5 +9,4 @@ include "std.MALTA"
machine mips mips64el
makeoptions ARCH_FLAGS="-march=mips64 -mabi=64"
-makeoptions MODULES_OVERRIDE=""
makeoptions KERNLOADADDR=0xffffffff80100000
diff --git a/sys/modules/dtb/omap4/Makefile b/sys/modules/dtb/omap4/Makefile
index a6eb8e20de7a..8e6ea876bbe7 100644
--- a/sys/modules/dtb/omap4/Makefile
+++ b/sys/modules/dtb/omap4/Makefile
@@ -5,4 +5,8 @@ DTS= \
pandaboard.dts \
pandaboard-es.dts
+LINKS= \
+ ${DTBDIR}/pandaboard.dtb ${DTBDIR}/omap4-panda.dtb \
+ ${DTBDIR}/pandaboard-es.dtb ${DTBDIR}/omap4-panda-es.dtb
+
.include <bsd.dtb.mk>
diff --git a/sys/modules/efirt/Makefile b/sys/modules/efirt/Makefile
index 2613150db489..2e53336cf22d 100644
--- a/sys/modules/efirt/Makefile
+++ b/sys/modules/efirt/Makefile
@@ -8,4 +8,11 @@ SRCS= efirt.c efirt_machdep.c efidev.c
SRCS+= efirtc.c
SRCS+= device_if.h bus_if.h clock_if.h
+.if ${MACHINE_CPUARCH} == "amd64"
+SRCS+= efirt_support.S
+efirt_support.o: efirt_support.S assym.inc
+ ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
+ ${.IMPSRC} -o ${.TARGET}
+.endif
+
.include <bsd.kmod.mk>
diff --git a/sys/modules/sound/driver/csa/Makefile b/sys/modules/sound/driver/csa/Makefile
index af02ef4f4e0d..b1a3f1fb9df4 100644
--- a/sys/modules/sound/driver/csa/Makefile
+++ b/sys/modules/sound/driver/csa/Makefile
@@ -3,7 +3,7 @@
.PATH: ${SRCTOP}/sys/dev/sound/pci
KMOD= snd_csa
-SRCS= device_if.h bus_if.h pci_if.h
-SRCS+= csa.c csapcm.c
+SRCS= device_if.h bus_if.h mpufoi_if.h pci_if.h
+SRCS+= csa.c csamidi.c csapcm.c
.include <bsd.kmod.mk>
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index faee06d02a83..65bf07a0b2c1 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -641,7 +641,6 @@ SYSCTL_INT(_net_iflib, OID_AUTO, fl_refills_large, CTLFLAG_RD,
static int iflib_txq_drain_flushing;
static int iflib_txq_drain_oactive;
static int iflib_txq_drain_notready;
-static int iflib_txq_drain_encapfail;
SYSCTL_INT(_net_iflib, OID_AUTO, txq_drain_flushing, CTLFLAG_RD,
&iflib_txq_drain_flushing, 0, "# drain flushes");
@@ -649,8 +648,6 @@ SYSCTL_INT(_net_iflib, OID_AUTO, txq_drain_oactive, CTLFLAG_RD,
&iflib_txq_drain_oactive, 0, "# drain oactives");
SYSCTL_INT(_net_iflib, OID_AUTO, txq_drain_notready, CTLFLAG_RD,
&iflib_txq_drain_notready, 0, "# drain notready");
-SYSCTL_INT(_net_iflib, OID_AUTO, txq_drain_encapfail, CTLFLAG_RD,
- &iflib_txq_drain_encapfail, 0, "# drain encap fails");
static int iflib_encap_load_mbuf_fail;
@@ -670,21 +667,14 @@ SYSCTL_INT(_net_iflib, OID_AUTO, encap_txd_encap_fail, CTLFLAG_RD,
static int iflib_task_fn_rxs;
static int iflib_rx_intr_enables;
static int iflib_fast_intrs;
-static int iflib_intr_link;
-static int iflib_intr_msix;
static int iflib_rx_unavail;
static int iflib_rx_ctx_inactive;
-static int iflib_rx_zero_len;
static int iflib_rx_if_input;
static int iflib_rx_mbuf_null;
static int iflib_rxd_flush;
static int iflib_verbose_debug;
-SYSCTL_INT(_net_iflib, OID_AUTO, intr_link, CTLFLAG_RD,
- &iflib_intr_link, 0, "# intr link calls");
-SYSCTL_INT(_net_iflib, OID_AUTO, intr_msix, CTLFLAG_RD,
- &iflib_intr_msix, 0, "# intr msix calls");
SYSCTL_INT(_net_iflib, OID_AUTO, task_fn_rx, CTLFLAG_RD,
&iflib_task_fn_rxs, 0, "# task_fn_rx calls");
SYSCTL_INT(_net_iflib, OID_AUTO, rx_intr_enables, CTLFLAG_RD,
@@ -695,8 +685,6 @@ SYSCTL_INT(_net_iflib, OID_AUTO, rx_unavail, CTLFLAG_RD,
&iflib_rx_unavail, 0, "# times rxeof called with no available data");
SYSCTL_INT(_net_iflib, OID_AUTO, rx_ctx_inactive, CTLFLAG_RD,
&iflib_rx_ctx_inactive, 0, "# times rxeof called with inactive context");
-SYSCTL_INT(_net_iflib, OID_AUTO, rx_zero_len, CTLFLAG_RD,
- &iflib_rx_zero_len, 0, "# times rxeof saw zero len mbuf");
SYSCTL_INT(_net_iflib, OID_AUTO, rx_if_input, CTLFLAG_RD,
&iflib_rx_if_input, 0, "# times rxeof called if_input");
SYSCTL_INT(_net_iflib, OID_AUTO, rx_mbuf_null, CTLFLAG_RD,
@@ -713,12 +701,12 @@ iflib_debug_reset(void)
iflib_tx_seen = iflib_tx_sent = iflib_tx_encap = iflib_rx_allocs =
iflib_fl_refills = iflib_fl_refills_large = iflib_tx_frees =
iflib_txq_drain_flushing = iflib_txq_drain_oactive =
- iflib_txq_drain_notready = iflib_txq_drain_encapfail =
+ iflib_txq_drain_notready =
iflib_encap_load_mbuf_fail = iflib_encap_pad_mbuf_fail =
iflib_encap_txq_avail_fail = iflib_encap_txd_encap_fail =
iflib_task_fn_rxs = iflib_rx_intr_enables = iflib_fast_intrs =
- iflib_intr_link = iflib_intr_msix = iflib_rx_unavail =
- iflib_rx_ctx_inactive = iflib_rx_zero_len = iflib_rx_if_input =
+ iflib_rx_unavail =
+ iflib_rx_ctx_inactive = iflib_rx_if_input =
iflib_rx_mbuf_null = iflib_rxd_flush = 0;
}
@@ -839,6 +827,9 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo
if_ctx_t ctx = rxq->ifr_ctx;
iflib_fl_t fl = &rxq->ifr_fl[0];
uint32_t refill_pidx, nic_i;
+#if IFLIB_DEBUG_COUNTERS
+ int rf_count = 0;
+#endif
if (nm_i == head && __predict_true(!init))
return 0;
@@ -851,7 +842,12 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo
*/
head = nm_prev(head, lim);
nic_i = UINT_MAX;
+ DBG_COUNTER_INC(fl_refills);
while (nm_i != head) {
+#if IFLIB_DEBUG_COUNTERS
+ if (++rf_count == 9)
+ DBG_COUNTER_INC(fl_refills_large);
+#endif
for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) {
struct netmap_slot *slot = &ring->slot[nm_i];
void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[tmp_pidx]);
@@ -898,8 +894,10 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo
if (map)
bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if (__predict_true(nic_i != UINT_MAX))
+ if (__predict_true(nic_i != UINT_MAX)) {
ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i);
+ DBG_COUNTER_INC(rxd_flush);
+ }
return (0);
}
@@ -998,6 +996,7 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
/* Fill the slot in the NIC ring. */
ctx->isc_txd_encap(ctx->ifc_softc, &pi);
+ DBG_COUNTER_INC(tx_encap);
/* prefetch for next round */
__builtin_prefetch(&ring->slot[nm_i + 1]);
@@ -1524,8 +1523,10 @@ iflib_fast_intr_rxtx(void *arg)
cidx = rxq->ifr_fl[0].ifl_cidx;
if (iflib_rxd_avail(ctx, rxq, cidx, 1))
GROUPTASK_ENQUEUE(gtask);
- else
+ else {
IFDI_RX_QUEUE_INTR_ENABLE(ctx, rxq->ifr_id);
+ DBG_COUNTER_INC(rx_intr_enables);
+ }
return (FILTER_HANDLED);
}
@@ -2887,6 +2888,7 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp)
return (ENOMEM);
} else {
m_freem(*mp);
+ DBG_COUNTER_INC(tx_frees);
*mp = m;
}
}
@@ -2994,6 +2996,7 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp)
pi->ipi_ip_hlen = sizeof(struct ip6_hdr);
if (__predict_false(m->m_len < pi->ipi_ehdrlen + sizeof(struct ip6_hdr))) {
+ txq->ift_pullups++;
if (__predict_false((m = m_pullup(m, pi->ipi_ehdrlen + sizeof(struct ip6_hdr))) == NULL))
return (ENOMEM);
}
@@ -3041,34 +3044,6 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp)
return (0);
}
-static __noinline struct mbuf *
-collapse_pkthdr(struct mbuf *m0)
-{
- struct mbuf *m, *m_next, *tmp;
-
- m = m0;
- m_next = m->m_next;
- while (m_next != NULL && m_next->m_len == 0) {
- m = m_next;
- m->m_next = NULL;
- m_free(m);
- m_next = m_next->m_next;
- }
- m = m0;
- m->m_next = m_next;
- if (m_next == NULL)
- return (m);
- if ((m_next->m_flags & M_EXT) == 0) {
- m = m_defrag(m, M_NOWAIT);
- } else {
- tmp = m_next->m_next;
- memcpy(m_next, m, MPKTHSIZE);
- m = m_next;
- m->m_next = tmp;
- }
- return (m);
-}
-
/*
* If dodgy hardware rejects the scatter gather chain we've handed it
* we'll need to remove the mbuf chain from ifsg_m[] before we can add the
@@ -3117,8 +3092,7 @@ iflib_busdma_load_mbuf_sg(iflib_txq_t txq, bus_dma_tag_t tag, bus_dmamap_t map,
/*
* Please don't ever do this
*/
- if (__predict_false(m->m_len == 0))
- *m0 = collapse_pkthdr(m);
+ MPASS(__predict_true(m->m_len > 0));
ctx = txq->ift_ctx;
sctx = ctx->ifc_sctx;
@@ -3259,6 +3233,7 @@ iflib_ether_pad(device_t dev, struct mbuf **m_head, uint16_t min_frame_size)
m_freem(*m_head);
device_printf(dev, "cannot pad short frame, m_dup() failed");
DBG_COUNTER_INC(encap_pad_mbuf_fail);
+ DBG_COUNTER_INC(tx_frees);
return ENOMEM;
}
m_freem(*m_head);
@@ -3274,6 +3249,7 @@ iflib_ether_pad(device_t dev, struct mbuf **m_head, uint16_t min_frame_size)
m_freem(*m_head);
device_printf(dev, "cannot pad short frame\n");
DBG_COUNTER_INC(encap_pad_mbuf_fail);
+ DBG_COUNTER_INC(tx_frees);
return (ENOBUFS);
}
@@ -3337,8 +3313,10 @@ iflib_encap(iflib_txq_t txq, struct mbuf **m_headp)
if ((sctx->isc_flags & IFLIB_NEED_ETHER_PAD) &&
__predict_false(m_head->m_pkthdr.len < scctx->isc_min_frame_size)) {
err = iflib_ether_pad(ctx->ifc_dev, m_headp, scctx->isc_min_frame_size);
- if (err)
+ if (err) {
+ DBG_COUNTER_INC(encap_txd_encap_fail);
return err;
+ }
}
m_head = *m_headp;
@@ -3352,8 +3330,10 @@ iflib_encap(iflib_txq_t txq, struct mbuf **m_headp)
/* deliberate bitwise OR to make one condition */
if (__predict_true((pi.ipi_csum_flags | pi.ipi_vtag))) {
- if (__predict_false((err = iflib_parse_header(txq, &pi, m_headp)) != 0))
+ if (__predict_false((err = iflib_parse_header(txq, &pi, m_headp)) != 0)) {
+ DBG_COUNTER_INC(encap_txd_encap_fail);
return (err);
+ }
m_head = *m_headp;
}
@@ -3370,12 +3350,13 @@ defrag:
if (m_head == NULL)
remap++;
}
- if (remap == 1)
+ if (remap == 1) {
+ txq->ift_mbuf_defrag++;
m_head = m_defrag(*m_headp, M_NOWAIT);
+ }
remap++;
if (__predict_false(m_head == NULL))
goto defrag_failed;
- txq->ift_mbuf_defrag++;
*m_headp = m_head;
goto retry;
break;
@@ -3391,6 +3372,7 @@ defrag:
}
txq->ift_map_failed++;
DBG_COUNTER_INC(encap_load_mbuf_fail);
+ DBG_COUNTER_INC(encap_txd_encap_fail);
return (err);
}
@@ -3404,6 +3386,7 @@ defrag:
if (map != NULL)
bus_dmamap_unload(desc_tag, map);
DBG_COUNTER_INC(encap_txq_avail_fail);
+ DBG_COUNTER_INC(encap_txd_encap_fail);
if ((txq->ift_task.gt_task.ta_flags & TASK_ENQUEUED) == 0)
GROUPTASK_ENQUEUE(&txq->ift_task);
return (ENOBUFS);
@@ -3466,9 +3449,12 @@ defrag:
goto defrag;
}
}
- DBG_COUNTER_INC(encap_txd_encap_fail);
goto defrag_failed;
}
+ /*
+ * err can't possibly be non-zero here, so we don't neet to test it
+ * to see if we need to DBG_COUNTER_INC(encap_txd_encap_fail).
+ */
return (err);
defrag_failed:
@@ -3477,6 +3463,7 @@ defrag_failed:
m_freem(*m_headp);
DBG_COUNTER_INC(tx_frees);
*m_headp = NULL;
+ DBG_COUNTER_INC(encap_txd_encap_fail);
return (ENOMEM);
}
@@ -3676,12 +3663,10 @@ iflib_txq_drain(struct ifmp_ring *r, uint32_t cidx, uint32_t pidx)
in_use_prev = txq->ift_in_use;
err = iflib_encap(txq, mp);
if (__predict_false(err)) {
- DBG_COUNTER_INC(txq_drain_encapfail);
/* no room - bail out */
if (err == ENOBUFS)
break;
consumed++;
- DBG_COUNTER_INC(txq_drain_encapfail);
/* we can't send this packet - skip it */
continue;
}
@@ -3741,6 +3726,7 @@ iflib_txq_drain_free(struct ifmp_ring *r, uint32_t cidx, uint32_t pidx)
if (__predict_false(*mp == (struct mbuf *)txq))
continue;
m_freem(*mp);
+ DBG_COUNTER_INC(tx_frees);
}
MPASS(ifmp_ring_is_stalled(r) == 0);
return (avail);
@@ -3987,6 +3973,7 @@ iflib_if_transmit(if_t ifp, struct mbuf *m)
next = m->m_nextpkt;
m->m_nextpkt = NULL;
m_freem(m);
+ DBG_COUNTER_INC(tx_frees);
m = next;
}
return (ENOBUFS);
@@ -4029,6 +4016,7 @@ iflib_if_transmit(if_t ifp, struct mbuf *m)
#endif
ifmp_ring_check_drainage(txq->ift_br, TX_BATCH_SIZE);
m_freem(m);
+ DBG_COUNTER_INC(tx_frees);
}
return (err);
diff --git a/sys/net/route.h b/sys/net/route.h
index 28f1db01ef88..15ec1b3e9a38 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -410,10 +410,8 @@ struct rt_addrinfo {
} while (0)
#define RO_RTFREE(_ro) do { \
- if ((_ro)->ro_rt) { \
- RT_LOCK((_ro)->ro_rt); \
- RTFREE_LOCKED((_ro)->ro_rt); \
- } \
+ if ((_ro)->ro_rt) \
+ RTFREE((_ro)->ro_rt); \
} while (0)
#define RO_INVALIDATE_CACHE(ro) do { \
diff --git a/sys/netinet/in_kdtrace.c b/sys/netinet/in_kdtrace.c
index e56cbc4d97cf..fedff49cfdc2 100644
--- a/sys/netinet/in_kdtrace.c
+++ b/sys/netinet/in_kdtrace.c
@@ -31,12 +31,16 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_sctp.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sdt.h>
SDT_PROVIDER_DEFINE(ip);
+#ifdef SCTP
SDT_PROVIDER_DEFINE(sctp);
+#endif
SDT_PROVIDER_DEFINE(tcp);
SDT_PROVIDER_DEFINE(udp);
SDT_PROVIDER_DEFINE(udplite);
@@ -57,6 +61,7 @@ SDT_PROBE_DEFINE6_XLATE(ip, , , send,
"struct ip *", "ipv4info_t *",
"struct ip6_hdr *", "ipv6info_t *");
+#ifdef SCTP
SDT_PROBE_DEFINE5_XLATE(sctp, , , receive,
"void *", "pktinfo_t *",
"struct sctp_tcb *", "csinfo_t *",
@@ -78,6 +83,7 @@ SDT_PROBE_DEFINE6_XLATE(sctp, , , state__change,
"struct sctp_tcb *", "sctpsinfo_t *",
"void *", "void *",
"int", "sctplsinfo_t *");
+#endif
SDT_PROBE_DEFINE5_XLATE(tcp, , , accept__established,
"void *", "pktinfo_t *",
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 98838fa041a1..671a9c7c7faf 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -235,16 +235,26 @@ in_pcblbgroup_alloc(struct inpcblbgrouphead *hdr, u_char vflag,
grp->il_lport = port;
grp->il_dependladdr = *addr;
grp->il_inpsiz = size;
- LIST_INSERT_HEAD(hdr, grp, il_list);
+ CK_LIST_INSERT_HEAD(hdr, grp, il_list);
return (grp);
}
static void
+in_pcblbgroup_free_deferred(epoch_context_t ctx)
+{
+ struct inpcblbgroup *grp;
+
+ grp = __containerof(ctx, struct inpcblbgroup, il_epoch_ctx);
+ free(grp, M_PCB);
+}
+
+static void
in_pcblbgroup_free(struct inpcblbgroup *grp)
{
- LIST_REMOVE(grp, il_list);
- free(grp, M_TEMP);
+ CK_LIST_REMOVE(grp, il_list);
+ epoch_call(net_epoch_preempt, &grp->il_epoch_ctx,
+ in_pcblbgroup_free_deferred);
}
static struct inpcblbgroup *
@@ -301,13 +311,14 @@ in_pcblbgroup_reorder(struct inpcblbgrouphead *hdr, struct inpcblbgroup **grpp,
static int
in_pcbinslbgrouphash(struct inpcb *inp)
{
+ const static struct timeval interval = { 60, 0 };
+ static struct timeval lastprint;
struct inpcbinfo *pcbinfo;
struct inpcblbgrouphead *hdr;
struct inpcblbgroup *grp;
uint16_t hashmask, lport;
uint32_t group_index;
struct ucred *cred;
- static int limit_logged = 0;
pcbinfo = inp->inp_pcbinfo;
@@ -346,7 +357,7 @@ in_pcbinslbgrouphash(struct inpcb *inp)
hdr = &pcbinfo->ipi_lbgrouphashbase[
INP_PCBLBGROUP_PORTHASH(inp->inp_lport,
pcbinfo->ipi_lbgrouphashmask)];
- LIST_FOREACH(grp, hdr, il_list) {
+ CK_LIST_FOREACH(grp, hdr, il_list) {
if (grp->il_vflag == inp->inp_vflag &&
grp->il_lport == inp->inp_lport &&
memcmp(&grp->il_dependladdr,
@@ -364,11 +375,9 @@ in_pcbinslbgrouphash(struct inpcb *inp)
return (ENOBUFS);
} else if (grp->il_inpcnt == grp->il_inpsiz) {
if (grp->il_inpsiz >= INPCBLBGROUP_SIZMAX) {
- if (!limit_logged) {
- limit_logged = 1;
+ if (ratecheck(&lastprint, &interval))
printf("lb group port %d, limit reached\n",
ntohs(grp->il_lport));
- }
return (0);
}
@@ -410,7 +419,7 @@ in_pcbremlbgrouphash(struct inpcb *inp)
INP_PCBLBGROUP_PORTHASH(inp->inp_lport,
pcbinfo->ipi_lbgrouphashmask)];
- LIST_FOREACH(grp, hdr, il_list) {
+ CK_LIST_FOREACH(grp, hdr, il_list) {
for (i = 0; i < grp->il_inpcnt; ++i) {
if (grp->il_inp[i] != inp)
continue;
@@ -1950,18 +1959,18 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
static struct inpcb *
in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
- const struct in_addr *laddr, uint16_t lport, const struct in_addr *faddr,
- uint16_t fport, int lookupflags)
+ const struct in_addr *laddr, uint16_t lport, const struct in_addr *faddr,
+ uint16_t fport, int lookupflags)
{
- struct inpcb *local_wild = NULL;
+ struct inpcb *local_wild;
const struct inpcblbgrouphead *hdr;
struct inpcblbgroup *grp;
- struct inpcblbgroup *grp_local_wild;
+ uint32_t idx;
INP_HASH_LOCK_ASSERT(pcbinfo);
- hdr = &pcbinfo->ipi_lbgrouphashbase[
- INP_PCBLBGROUP_PORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)];
+ hdr = &pcbinfo->ipi_lbgrouphashbase[INP_PCBLBGROUP_PORTHASH(lport,
+ pcbinfo->ipi_lbgrouphashmask)];
/*
* Order of socket selection:
@@ -1972,35 +1981,24 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
* - Load balanced group does not contain jailed sockets
* - Load balanced group does not contain IPv4 mapped INET6 wild sockets
*/
- LIST_FOREACH(grp, hdr, il_list) {
+ local_wild = NULL;
+ CK_LIST_FOREACH(grp, hdr, il_list) {
#ifdef INET6
if (!(grp->il_vflag & INP_IPV4))
continue;
#endif
+ if (grp->il_lport != lport)
+ continue;
- if (grp->il_lport == lport) {
-
- uint32_t idx = 0;
- int pkt_hash = INP_PCBLBGROUP_PKTHASH(faddr->s_addr,
- lport, fport);
-
- idx = pkt_hash % grp->il_inpcnt;
-
- if (grp->il_laddr.s_addr == laddr->s_addr) {
- return (grp->il_inp[idx]);
- } else {
- if (grp->il_laddr.s_addr == INADDR_ANY &&
- (lookupflags & INPLOOKUP_WILDCARD)) {
- local_wild = grp->il_inp[idx];
- grp_local_wild = grp;
- }
- }
- }
+ idx = INP_PCBLBGROUP_PKTHASH(faddr->s_addr, lport, fport) %
+ grp->il_inpcnt;
+ if (grp->il_laddr.s_addr == laddr->s_addr)
+ return (grp->il_inp[idx]);
+ if (grp->il_laddr.s_addr == INADDR_ANY &&
+ (lookupflags & INPLOOKUP_WILDCARD) != 0)
+ local_wild = grp->il_inp[idx];
}
- if (local_wild != NULL) {
- return (local_wild);
- }
- return (NULL);
+ return (local_wild);
}
#ifdef PCBGROUP
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 31009099e6f7..86c9705cb905 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -70,6 +70,7 @@
*/
CK_LIST_HEAD(inpcbhead, inpcb);
CK_LIST_HEAD(inpcbporthead, inpcbport);
+CK_LIST_HEAD(inpcblbgrouphead, inpcblbgroup);
typedef uint64_t inp_gen_t;
/*
@@ -320,7 +321,7 @@ struct inpcb {
CK_LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */
struct inpcbport *inp_phd; /* (i/h) head of this list */
inp_gen_t inp_gencnt; /* (c) generation count */
- struct llentry *inp_lle; /* cached L2 information */
+ void *spare_ptr; /* Spare pointer. */
rt_gen_t inp_rt_cookie; /* generation for route entry */
union { /* cached L3 information */
struct route inp_route;
@@ -566,7 +567,8 @@ struct inpcbgroup {
* is dynamically resized as processes bind/unbind to that specific group.
*/
struct inpcblbgroup {
- LIST_ENTRY(inpcblbgroup) il_list;
+ CK_LIST_ENTRY(inpcblbgroup) il_list;
+ struct epoch_context il_epoch_ctx;
uint16_t il_lport; /* (c) */
u_char il_vflag; /* (c) */
u_char il_pad;
@@ -578,7 +580,6 @@ struct inpcblbgroup {
uint32_t il_inpcnt; /* cur count in il_inp[] (h) */
struct inpcb *il_inp[]; /* (h) */
};
-LIST_HEAD(inpcblbgrouphead, inpcblbgroup);
#define INP_LOCK_INIT(inp, d, t) \
rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK)
@@ -744,8 +745,8 @@ int inp_so_options(const struct inpcb *inp);
/*
* Flags for inp_flags2.
*/
-#define INP_LLE_VALID 0x00000001 /* cached lle is valid */
-#define INP_RT_VALID 0x00000002 /* cached rtentry is valid */
+#define INP_2UNUSED1 0x00000001
+#define INP_2UNUSED2 0x00000002
#define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */
#define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */
#define INP_FREED 0x00000010 /* inp itself is not valid */
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 47351bacb5b6..643a75e2294b 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -153,7 +153,7 @@ ip_tryforward(struct mbuf *m)
struct mbuf *m0 = NULL;
struct nhop4_basic nh;
struct sockaddr_in dst;
- struct in_addr odest, dest;
+ struct in_addr dest, odest, rtdest;
uint16_t ip_len, ip_off;
int error = 0;
struct m_tag *fwd_tag = NULL;
@@ -294,12 +294,31 @@ passin:
#endif
/*
+ * Next hop forced by pfil(9) hook?
+ */
+ if ((m->m_flags & M_IP_NEXTHOP) &&
+ ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) {
+ /*
+ * Now we will find route to forced destination.
+ */
+ dest.s_addr = ((struct sockaddr_in *)
+ (fwd_tag + 1))->sin_addr.s_addr;
+ m_tag_delete(m, fwd_tag);
+ m->m_flags &= ~M_IP_NEXTHOP;
+ }
+
+ /*
* Find route to destination.
*/
if (ip_findroute(&nh, dest, m) != 0)
return (NULL); /* icmp unreach already sent */
/*
+ * Avoid second route lookup by caching destination.
+ */
+ rtdest.s_addr = dest.s_addr;
+
+ /*
* Step 5: outgoing firewall packet processing
*/
if (!PFIL_HOOKED(&V_inet_pfil_hook))
@@ -321,6 +340,8 @@ passin:
*/
if (m->m_flags & M_IP_NEXTHOP)
fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ else
+ fwd_tag = NULL;
if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
/*
* Is it now for a local address on this host?
@@ -342,7 +363,8 @@ forwardlocal:
m_tag_delete(m, fwd_tag);
m->m_flags &= ~M_IP_NEXTHOP;
}
- if (ip_findroute(&nh, dest, m) != 0)
+ if (dest.s_addr != rtdest.s_addr &&
+ ip_findroute(&nh, dest, m) != 0)
return (NULL); /* icmp unreach already sent */
}
diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c
index 7c4ad009d73d..32047180f883 100644
--- a/sys/netinet/tcp_hpts.c
+++ b/sys/netinet/tcp_hpts.c
@@ -167,6 +167,8 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_TCPHPTS, "tcp_hpts", "TCP hpts");
#ifdef RSS
+#include <net/netisr.h>
+#include <net/rss_config.h>
static int tcp_bind_threads = 1;
#else
static int tcp_bind_threads = 0;
@@ -1076,7 +1078,7 @@ hpts_random_cpu(struct inpcb *inp){
static uint16_t
hpts_cpuid(struct inpcb *inp){
- uint16_t cpuid;
+ u_int cpuid;
/*
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 0f30801540a6..bbdbf448f7cb 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -218,7 +218,9 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
int offset = *offp, nxt, i, next;
int first_frag = 0;
int fragoff, frgpartlen; /* must be larger than u_int16_t */
- uint32_t hash, hashkey[sizeof(struct in6_addr) * 2 + 1], *hashkeyp;
+ uint32_t hashkey[(sizeof(struct in6_addr) * 2 +
+ sizeof(ip6f->ip6f_ident)) / sizeof(uint32_t)];
+ uint32_t hash, *hashkeyp;
struct ifnet *dstifp;
u_int8_t ecn, ecn0;
#ifdef RSS
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index b45d04bf1be5..a9c73798b18c 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -846,16 +846,10 @@ in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp)
* (by a redirect), time to try a default gateway again.
*/
void
-in6_losing(struct inpcb *in6p)
+in6_losing(struct inpcb *inp)
{
- if (in6p->inp_route6.ro_rt) {
- RTFREE(in6p->inp_route6.ro_rt);
- in6p->inp_route6.ro_rt = (struct rtentry *)NULL;
- }
- if (in6p->inp_route.ro_lle)
- LLE_FREE(in6p->inp_route.ro_lle); /* zeros ro_lle */
- return;
+ RO_INVALIDATE_CACHE(&inp->inp_route6);
}
/*
@@ -863,15 +857,10 @@ in6_losing(struct inpcb *in6p)
* and allocate a (hopefully) better one.
*/
struct inpcb *
-in6_rtchange(struct inpcb *inp, int errno)
+in6_rtchange(struct inpcb *inp, int errno __unused)
{
- if (inp->inp_route6.ro_rt) {
- RTFREE(inp->inp_route6.ro_rt);
- inp->inp_route6.ro_rt = (struct rtentry *)NULL;
- }
- if (inp->inp_route.ro_lle)
- LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
+ RO_INVALIDATE_CACHE(&inp->inp_route6);
return inp;
}
@@ -900,7 +889,7 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
* - Load balanced group does not contain jailed sockets.
* - Load balanced does not contain IPv4 mapped INET6 wild sockets.
*/
- LIST_FOREACH(grp, hdr, il_list) {
+ CK_LIST_FOREACH(grp, hdr, il_list) {
#ifdef INET
if (!(grp->il_vflag & INP_IPV6))
continue;
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 7ce29e2e1d83..9c24daf2f7a7 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -804,22 +804,16 @@ again:
error = netisr_queue(NETISR_IPV6, m);
goto done;
} else {
- RO_RTFREE(ro);
+ RO_INVALIDATE_CACHE(ro);
needfiblookup = 1; /* Redo the routing table lookup. */
- if (ro->ro_lle)
- LLE_FREE(ro->ro_lle); /* zeros ro_lle */
- ro->ro_lle = NULL;
}
}
/* See if fib was changed by packet filter. */
if (fibnum != M_GETFIB(m)) {
m->m_flags |= M_SKIP_FIREWALL;
fibnum = M_GETFIB(m);
- RO_RTFREE(ro);
+ RO_INVALIDATE_CACHE(ro);
needfiblookup = 1;
- if (ro->ro_lle)
- LLE_FREE(ro->ro_lle); /* zeros ro_lle */
- ro->ro_lle = NULL;
}
if (needfiblookup)
goto again;
diff --git a/sys/ofed/drivers/infiniband/core/ib_cm.c b/sys/ofed/drivers/infiniband/core/ib_cm.c
index d7fc30fec7d3..b903eeab4a3c 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cm.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cm.c
@@ -1453,6 +1453,7 @@ static void cm_format_req_event(struct cm_work *work,
param->retry_count = cm_req_get_retry_count(req_msg);
param->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg);
param->srq = cm_req_get_srq(req_msg);
+ param->ppath_sgid_index = cm_id_priv->av.ah_attr.grh.sgid_index;
work->cm_event.private_data = &req_msg->private_data;
}
@@ -3137,6 +3138,7 @@ out:
EXPORT_SYMBOL(ib_send_cm_sidr_req);
static void cm_format_sidr_req_event(struct cm_work *work,
+ const struct cm_id_private *rx_cm_id,
struct ib_cm_id *listen_id)
{
struct cm_sidr_req_msg *sidr_req_msg;
@@ -3150,6 +3152,7 @@ static void cm_format_sidr_req_event(struct cm_work *work,
param->service_id = sidr_req_msg->service_id;
param->bth_pkey = cm_get_bth_pkey(work);
param->port = work->port->port_num;
+ param->sgid_index = rx_cm_id->av.ah_attr.grh.sgid_index;
work->cm_event.private_data = &sidr_req_msg->private_data;
}
@@ -3203,7 +3206,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
cm_id_priv->id.service_id = sidr_req_msg->service_id;
cm_id_priv->id.service_mask = ~cpu_to_be64(0);
- cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
+ cm_format_sidr_req_event(work, cm_id_priv, &cur_cm_id_priv->id);
cm_process_work(cm_id_priv, work);
cm_deref_id(cur_cm_id_priv);
return 0;
diff --git a/sys/ofed/drivers/infiniband/core/ib_cma.c b/sys/ofed/drivers/infiniband/core/ib_cma.c
index 42e7b3ad811f..0e20a04b3464 100644
--- a/sys/ofed/drivers/infiniband/core/ib_cma.c
+++ b/sys/ofed/drivers/infiniband/core/ib_cma.c
@@ -733,6 +733,10 @@ struct rdma_cm_id *rdma_create_id(struct vnet *net,
{
struct rdma_id_private *id_priv;
+#ifdef VIMAGE
+ if (net == NULL)
+ return ERR_PTR(-EINVAL);
+#endif
id_priv = kzalloc(sizeof *id_priv, GFP_KERNEL);
if (!id_priv)
return ERR_PTR(-ENOMEM);
@@ -751,7 +755,7 @@ struct rdma_cm_id *rdma_create_id(struct vnet *net,
INIT_LIST_HEAD(&id_priv->listen_list);
INIT_LIST_HEAD(&id_priv->mc_list);
get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
- id_priv->id.route.addr.dev_addr.net = TD_TO_VNET(curthread);
+ id_priv->id.route.addr.dev_addr.net = net;
return &id_priv->id;
}
@@ -1263,10 +1267,10 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
const struct sockaddr_in *src_addr)
{
#ifdef INET
- struct sockaddr_in dst_tmp = *dst_addr;
+ struct sockaddr_in src_tmp = *src_addr;
__be32 daddr = dst_addr->sin_addr.s_addr,
saddr = src_addr->sin_addr.s_addr;
- struct net_device *src_dev;
+ struct net_device *dst_dev;
struct rtentry *rte;
bool ret;
@@ -1276,29 +1280,29 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
ipv4_is_loopback(saddr))
return false;
- src_dev = ip_dev_find(net_dev->if_vnet, saddr);
- if (src_dev != net_dev) {
- if (src_dev != NULL)
- dev_put(src_dev);
+ dst_dev = ip_dev_find(net_dev->if_vnet, daddr);
+ if (dst_dev != net_dev) {
+ if (dst_dev != NULL)
+ dev_put(dst_dev);
return false;
}
- dev_put(src_dev);
+ dev_put(dst_dev);
/*
* Make sure the socket address length field
* is set, else rtalloc1() will fail.
*/
- dst_tmp.sin_len = sizeof(dst_tmp);
+ src_tmp.sin_len = sizeof(src_tmp);
CURVNET_SET(net_dev->if_vnet);
- rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
- CURVNET_RESTORE();
+ rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
if (rte != NULL) {
ret = (rte->rt_ifp == net_dev);
RTFREE_LOCKED(rte);
} else {
ret = false;
}
+ CURVNET_RESTORE();
return ret;
#else
return false;
@@ -1310,31 +1314,42 @@ static bool validate_ipv6_net_dev(struct net_device *net_dev,
const struct sockaddr_in6 *src_addr)
{
#ifdef INET6
- struct sockaddr_in6 dst_tmp = *dst_addr;
- struct in6_addr in6_addr = src_addr->sin6_addr;
- struct net_device *src_dev;
+ struct sockaddr_in6 src_tmp = *src_addr;
+ struct in6_addr in6_addr = dst_addr->sin6_addr;
+ struct net_device *dst_dev;
struct rtentry *rte;
bool ret;
- src_dev = ip6_dev_find(net_dev->if_vnet, in6_addr);
- if (src_dev != net_dev)
+ dst_dev = ip6_dev_find(net_dev->if_vnet, in6_addr);
+ if (dst_dev != net_dev) {
+ if (dst_dev != NULL)
+ dev_put(dst_dev);
return false;
+ }
+
+ CURVNET_SET(net_dev->if_vnet);
/*
* Make sure the socket address length field
* is set, else rtalloc1() will fail.
*/
- dst_tmp.sin6_len = sizeof(dst_tmp);
+ src_tmp.sin6_len = sizeof(src_tmp);
- CURVNET_SET(net_dev->if_vnet);
- rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
- CURVNET_RESTORE();
+ /*
+ * Make sure the scope ID gets embedded, else rtalloc1() will
+ * resolve to the loopback interface.
+ */
+ src_tmp.sin6_scope_id = net_dev->if_index;
+ sa6_embedscope(&src_tmp, 0);
+
+ rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
if (rte != NULL) {
ret = (rte->rt_ifp == net_dev);
RTFREE_LOCKED(rte);
} else {
ret = false;
}
+ CURVNET_RESTORE();
return ret;
#else
return false;
@@ -1364,6 +1379,26 @@ static bool validate_net_dev(struct net_device *net_dev,
}
}
+static struct net_device *
+roce_get_net_dev_by_cm_event(struct ib_device *device, u8 port_num,
+ const struct ib_cm_event *ib_event)
+{
+ struct ib_gid_attr sgid_attr;
+ union ib_gid sgid;
+ int err = -EINVAL;
+
+ if (ib_event->event == IB_CM_REQ_RECEIVED) {
+ err = ib_get_cached_gid(device, port_num,
+ ib_event->param.req_rcvd.ppath_sgid_index, &sgid, &sgid_attr);
+ } else if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) {
+ err = ib_get_cached_gid(device, port_num,
+ ib_event->param.sidr_req_rcvd.sgid_index, &sgid, &sgid_attr);
+ }
+ if (err)
+ return (NULL);
+ return (sgid_attr.ndev);
+}
+
static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event,
const struct cma_req_info *req)
{
@@ -1379,8 +1414,14 @@ static struct net_device *cma_get_net_dev(struct ib_cm_event *ib_event,
if (err)
return ERR_PTR(err);
- net_dev = ib_get_net_dev_by_params(req->device, req->port, req->pkey,
- gid, listen_addr);
+ if (rdma_protocol_roce(req->device, req->port)) {
+ net_dev = roce_get_net_dev_by_cm_event(req->device, req->port,
+ ib_event);
+ } else {
+ net_dev = ib_get_net_dev_by_params(req->device, req->port,
+ req->pkey,
+ gid, listen_addr);
+ }
if (!net_dev)
return ERR_PTR(-ENODEV);
@@ -1516,10 +1557,6 @@ static struct rdma_id_private *cma_id_from_event(struct ib_cm_id *cm_id,
if (PTR_ERR(*net_dev) == -EAFNOSUPPORT) {
/* Assuming the protocol is AF_IB */
*net_dev = NULL;
- } else if (cma_protocol_roce_dev_port(req.device, req.port)) {
- /* TODO find the net dev matching the request parameters
- * through the RoCE GID table */
- *net_dev = NULL;
} else {
return ERR_CAST(*net_dev);
}
diff --git a/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c b/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
index 5a65207a82f3..1dae52bac08a 100644
--- a/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
+++ b/sys/ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c
@@ -149,16 +149,6 @@ roce_gid_enum_netdev_default(struct ib_device *ib_dev,
return (hweight_long(gid_type_mask));
}
-#define ETH_IPOIB_DRV_NAME "ib"
-
-static inline int
-is_eth_ipoib_intf(struct net_device *dev)
-{
- if (strcmp(dev->if_dname, ETH_IPOIB_DRV_NAME))
- return 0;
- return 1;
-}
-
static void
roce_gid_update_addr_callback(struct ib_device *device, u8 port,
struct net_device *ndev, void *cookie)
@@ -322,15 +312,15 @@ roce_gid_queue_scan_event(struct net_device *ndev)
struct roce_netdev_event_work *work;
retry:
- if (is_eth_ipoib_intf(ndev))
- return;
-
- if (ndev->if_type != IFT_ETHER) {
- if (ndev->if_type == IFT_L2VLAN) {
- ndev = rdma_vlan_dev_real_dev(ndev);
- if (ndev != NULL)
- goto retry;
- }
+ switch (ndev->if_type) {
+ case IFT_ETHER:
+ break;
+ case IFT_L2VLAN:
+ ndev = rdma_vlan_dev_real_dev(ndev);
+ if (ndev != NULL)
+ goto retry;
+ /* FALLTHROUGH */
+ default:
return;
}
diff --git a/sys/ofed/drivers/infiniband/core/ib_uverbs_marshall.c b/sys/ofed/drivers/infiniband/core/ib_uverbs_marshall.c
index 11df70fff697..bf23f264d903 100644
--- a/sys/ofed/drivers/infiniband/core/ib_uverbs_marshall.c
+++ b/sys/ofed/drivers/infiniband/core/ib_uverbs_marshall.c
@@ -146,7 +146,7 @@ void ib_copy_path_rec_from_user(struct ib_sa_path_rec *dst,
dst->packet_life_time_selector = src->packet_life_time_selector;
memset(dst->dmac, 0, sizeof(dst->dmac));
- dst->net = NULL;
+ dst->net = TD_TO_VNET(curthread);
dst->ifindex = 0;
dst->gid_type = IB_GID_TYPE_IB;
}
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
index aee91c29eb0a..6a8995a98d09 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -54,6 +54,8 @@ static int ipoib_resolvemulti(struct ifnet *, struct sockaddr **,
#include <net/ip.h>
#include <net/ipv6.h>
+#include <rdma/ib_cache.h>
+
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -90,6 +92,10 @@ struct ib_sa_client ipoib_sa_client;
static void ipoib_add_one(struct ib_device *device);
static void ipoib_remove_one(struct ib_device *device, void *client_data);
+static struct net_device *ipoib_get_net_dev_by_params(
+ struct ib_device *dev, u8 port, u16 pkey,
+ const union ib_gid *gid, const struct sockaddr *addr,
+ void *client_data);
static void ipoib_start(struct ifnet *dev);
static int ipoib_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro);
@@ -163,7 +169,8 @@ ipoib_mtap_proto(struct ifnet *ifp, struct mbuf *mb, uint16_t proto)
static struct ib_client ipoib_client = {
.name = "ipoib",
.add = ipoib_add_one,
- .remove = ipoib_remove_one
+ .remove = ipoib_remove_one,
+ .get_net_dev_by_params = ipoib_get_net_dev_by_params,
};
int
@@ -1113,6 +1120,156 @@ ipoib_remove_one(struct ib_device *device, void *client_data)
kfree(dev_list);
}
+static int
+ipoib_match_dev_addr(const struct sockaddr *addr, struct net_device *dev)
+{
+ struct ifaddr *ifa;
+ int retval = 0;
+
+ CURVNET_SET(dev->if_vnet);
+ IF_ADDR_RLOCK(dev);
+ CK_STAILQ_FOREACH(ifa, &dev->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr == NULL ||
+ ifa->ifa_addr->sa_family != addr->sa_family ||
+ ifa->ifa_addr->sa_len != addr->sa_len) {
+ continue;
+ }
+ if (memcmp(ifa->ifa_addr, addr, addr->sa_len) == 0) {
+ retval = 1;
+ break;
+ }
+ }
+ IF_ADDR_RUNLOCK(dev);
+ CURVNET_RESTORE();
+
+ return (retval);
+}
+
+/*
+ * ipoib_match_gid_pkey_addr - returns the number of IPoIB netdevs on
+ * top a given ipoib device matching a pkey_index and address, if one
+ * exists.
+ *
+ * @found_net_dev: contains a matching net_device if the return value
+ * >= 1, with a reference held.
+ */
+static int
+ipoib_match_gid_pkey_addr(struct ipoib_dev_priv *priv,
+ const union ib_gid *gid, u16 pkey_index, const struct sockaddr *addr,
+ struct net_device **found_net_dev)
+{
+ struct ipoib_dev_priv *child_priv;
+ int matches = 0;
+
+ if (priv->pkey_index == pkey_index &&
+ (!gid || !memcmp(gid, &priv->local_gid, sizeof(*gid)))) {
+ if (addr == NULL || ipoib_match_dev_addr(addr, priv->dev) != 0) {
+ if (*found_net_dev == NULL) {
+ struct net_device *net_dev;
+
+ if (priv->parent != NULL)
+ net_dev = priv->parent;
+ else
+ net_dev = priv->dev;
+ *found_net_dev = net_dev;
+ dev_hold(net_dev);
+ }
+ matches++;
+ }
+ }
+
+ /* Check child interfaces */
+ mutex_lock(&priv->vlan_mutex);
+ list_for_each_entry(child_priv, &priv->child_intfs, list) {
+ matches += ipoib_match_gid_pkey_addr(child_priv, gid,
+ pkey_index, addr, found_net_dev);
+ if (matches > 1)
+ break;
+ }
+ mutex_unlock(&priv->vlan_mutex);
+
+ return matches;
+}
+
+/*
+ * __ipoib_get_net_dev_by_params - returns the number of matching
+ * net_devs found (between 0 and 2). Also return the matching
+ * net_device in the @net_dev parameter, holding a reference to the
+ * net_device, if the number of matches >= 1
+ */
+static int
+__ipoib_get_net_dev_by_params(struct list_head *dev_list, u8 port,
+ u16 pkey_index, const union ib_gid *gid,
+ const struct sockaddr *addr, struct net_device **net_dev)
+{
+ struct ipoib_dev_priv *priv;
+ int matches = 0;
+
+ *net_dev = NULL;
+
+ list_for_each_entry(priv, dev_list, list) {
+ if (priv->port != port)
+ continue;
+
+ matches += ipoib_match_gid_pkey_addr(priv, gid, pkey_index,
+ addr, net_dev);
+
+ if (matches > 1)
+ break;
+ }
+
+ return matches;
+}
+
+static struct net_device *
+ipoib_get_net_dev_by_params(struct ib_device *dev, u8 port, u16 pkey,
+ const union ib_gid *gid, const struct sockaddr *addr, void *client_data)
+{
+ struct net_device *net_dev;
+ struct list_head *dev_list = client_data;
+ u16 pkey_index;
+ int matches;
+ int ret;
+
+ if (!rdma_protocol_ib(dev, port))
+ return NULL;
+
+ ret = ib_find_cached_pkey(dev, port, pkey, &pkey_index);
+ if (ret)
+ return NULL;
+
+ if (!dev_list)
+ return NULL;
+
+ /* See if we can find a unique device matching the L2 parameters */
+ matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index,
+ gid, NULL, &net_dev);
+
+ switch (matches) {
+ case 0:
+ return NULL;
+ case 1:
+ return net_dev;
+ }
+
+ dev_put(net_dev);
+
+ /* Couldn't find a unique device with L2 parameters only. Use L3
+ * address to uniquely match the net device */
+ matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index,
+ gid, addr, &net_dev);
+ switch (matches) {
+ case 0:
+ return NULL;
+ default:
+ dev_warn_ratelimited(&dev->dev,
+ "duplicate IP address detected\n");
+ /* Fall through */
+ case 1:
+ return net_dev;
+ }
+}
+
static void
ipoib_config_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
{
diff --git a/sys/ofed/include/rdma/ib_addr.h b/sys/ofed/include/rdma/ib_addr.h
index ab95e9e036d9..49caf7a7844d 100644
--- a/sys/ofed/include/rdma/ib_addr.h
+++ b/sys/ofed/include/rdma/ib_addr.h
@@ -167,7 +167,7 @@ static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev)
{
uint16_t tag;
- if (dev->if_pcp != IFNET_PCP_NONE)
+ if (dev->if_type == IFT_ETHER && dev->if_pcp != IFNET_PCP_NONE)
return 0x0000; /* prio-tagged traffic */
if (VLAN_TAG(__DECONST(struct ifnet *, dev), &tag) != 0)
return 0xffff;
@@ -221,7 +221,11 @@ static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
struct net_device *dev;
struct ifaddr *ifa;
- dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
+#ifdef VIMAGE
+ if (dev_addr->net == NULL)
+ return;
+#endif
+ dev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if);
if (dev) {
CK_STAILQ_FOREACH(ifa, &dev->if_addrhead, ifa_link) {
if (ifa->ifa_addr == NULL ||
@@ -350,7 +354,7 @@ static inline u16 rdma_get_vlan_id(union ib_gid *dgid)
static inline struct net_device *rdma_vlan_dev_real_dev(struct net_device *dev)
{
- if (dev->if_pcp != IFNET_PCP_NONE)
+ if (dev->if_type == IFT_ETHER && dev->if_pcp != IFNET_PCP_NONE)
return dev; /* prio-tagged traffic */
return VLAN_TRUNKDEV(__DECONST(struct ifnet *, dev));
}
diff --git a/sys/ofed/include/rdma/ib_cm.h b/sys/ofed/include/rdma/ib_cm.h
index 48309328d62a..8806494766f6 100644
--- a/sys/ofed/include/rdma/ib_cm.h
+++ b/sys/ofed/include/rdma/ib_cm.h
@@ -125,6 +125,13 @@ struct ib_cm_req_event_param {
struct ib_sa_path_rec *primary_path;
struct ib_sa_path_rec *alternate_path;
+ /*
+ * SGID index of the primary path. Currently only
+ * useful for RoCE. Alternate path GID attributes
+ * are not yet supported.
+ */
+ u8 ppath_sgid_index;
+
__be64 remote_ca_guid;
u32 remote_qkey;
u32 remote_qpn;
@@ -231,6 +238,13 @@ struct ib_cm_apr_event_param {
struct ib_cm_sidr_req_event_param {
struct ib_cm_id *listen_id;
__be64 service_id;
+
+ /*
+ * SGID index of the request. Currently only
+ * useful for RoCE.
+ */
+ u8 sgid_index;
+
/* P_Key that was used by the GMP's BTH header */
u16 bth_pkey;
u8 port;
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index 7bed3548ee7c..451b730225ca 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -56,6 +56,7 @@ struct pcb {
#define PCB_VEC 0x4 /* Process had Altivec initialized */
#define PCB_VSX 0x8 /* Process had VSX initialized */
#define PCB_CDSCR 0x10 /* Process had Custom DSCR initialized */
+#define PCB_HTM 0x20 /* Process had HTM initialized */
struct fpu {
union {
double fpr;
@@ -73,6 +74,11 @@ struct pcb {
} pcb_vec __aligned(16); /* Vector processor */
unsigned int pcb_veccpu; /* which CPU had our vector
stuff. */
+ struct htm {
+ uint64_t tfhar;
+ uint64_t texasr;
+ uint64_t tfiar;
+ } pcb_htm;
union {
struct {
diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h
index 5e5a24f7563b..48bc4a3f6d7a 100644
--- a/sys/powerpc/include/pcpu.h
+++ b/sys/powerpc/include/pcpu.h
@@ -45,6 +45,7 @@ struct pvo_entry;
struct pmap *pc_curpmap; /* current pmap */ \
struct thread *pc_fputhread; /* current fpu user */ \
struct thread *pc_vecthread; /* current vec user */ \
+ struct thread *pc_htmthread; /* current htm user */ \
uintptr_t pc_hwref; \
int pc_bsp; \
volatile int pc_awake; \
diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC
index 0405b1921cd7..2975ecbec413 100644
--- a/sys/riscv/conf/GENERIC
+++ b/sys/riscv/conf/GENERIC
@@ -88,6 +88,15 @@ device vtnet # VirtIO Ethernet device
device virtio_blk # VirtIO Block device
device virtio_mmio # VirtIO MMIO bus
+# DTrace support
+# device dtrace
+# device dtrace_profile
+# device dtrace_sdt
+# device dtrace_fbt
+# device dtrace_systrace
+# device dtrace_prototype
+# device dtraceall
+
# Serial (COM) ports
device uart # Generic UART driver
device uart_ns8250 # ns8250-type UART driver
diff --git a/sys/riscv/include/asm.h b/sys/riscv/include/asm.h
index 5b517322732c..87736980cdc0 100644
--- a/sys/riscv/include/asm.h
+++ b/sys/riscv/include/asm.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -63,4 +63,12 @@
ld tmp, TD_PCB(tmp); /* Load the pcb */ \
sd handler, PCB_ONFAULT(tmp) /* Set the handler */
+#define ENTER_USER_ACCESS(tmp) \
+ li tmp, SSTATUS_SUM; \
+ csrs sstatus, tmp
+
+#define EXIT_USER_ACCESS(tmp) \
+ li tmp, SSTATUS_SUM; \
+ csrc sstatus, tmp
+
#endif /* _MACHINE_ASM_H_ */
diff --git a/sys/riscv/include/riscv_opcode.h b/sys/riscv/include/riscv_opcode.h
deleted file mode 100644
index b346588f01df..000000000000
--- a/sys/riscv/include/riscv_opcode.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
- * 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.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 _MACHINE_RISCV_OPCODE_H_
-#define _MACHINE_RISCV_OPCODE_H_
-
-/*
- * Define the instruction formats and opcode values for the
- * RISC-V instruction set.
- */
-#include <machine/endian.h>
-
-/*
- * Define the instruction formats.
- */
-typedef union {
- unsigned word;
-
- struct {
- unsigned opcode: 7;
- unsigned rd: 5;
- unsigned funct3: 3;
- unsigned rs1: 5;
- unsigned rs2: 5;
- unsigned funct7: 7;
- } RType;
-
- struct {
- unsigned opcode: 7;
- unsigned rd: 5;
- unsigned funct3: 3;
- unsigned rs1: 5;
- unsigned rs2: 6;
- unsigned funct7: 6;
- } R2Type;
-
- struct {
- unsigned opcode: 7;
- unsigned rd: 5;
- unsigned funct3: 3;
- unsigned rs1: 5;
- unsigned imm: 12;
- } IType;
-
- struct {
- unsigned opcode: 7;
- unsigned imm0_4: 5;
- unsigned funct3: 3;
- unsigned rs1: 5;
- unsigned rs2: 5;
- unsigned imm5_11: 7;
- } SType;
-
- struct {
- unsigned opcode: 7;
- unsigned imm11: 1;
- unsigned imm1_4: 4;
- unsigned funct3: 3;
- unsigned rs1: 5;
- unsigned rs2: 5;
- unsigned imm5_10: 6;
- unsigned imm12: 1;
- } SBType;
-
- struct {
- unsigned opcode: 7;
- unsigned rd: 5;
- unsigned imm12_31: 20;
- } UType;
-
- struct {
- unsigned opcode: 7;
- unsigned rd: 5;
- unsigned imm12_19: 8;
- unsigned imm11: 1;
- unsigned imm1_10: 10;
- unsigned imm20: 1;
- } UJType;
-} InstFmt;
-
-#define RISCV_OPCODE(r) (r & 0x7f)
-
-#endif /* !_MACHINE_RISCV_OPCODE_H_ */
diff --git a/sys/riscv/include/riscvreg.h b/sys/riscv/include/riscvreg.h
index 421b6e074437..fae70d9e0441 100644
--- a/sys/riscv/include/riscvreg.h
+++ b/sys/riscv/include/riscvreg.h
@@ -157,10 +157,31 @@
#define XLEN 8
#define INSN_SIZE 4
+#define INSN_C_SIZE 2
-#define RISCV_INSN_NOP 0x00000013
-#define RISCV_INSN_BREAK 0x00100073
-#define RISCV_INSN_RET 0x00008067
+#define X_RA 1
+#define X_SP 2
+#define X_GP 3
+#define X_TP 4
+#define X_T0 5
+#define X_T1 6
+#define X_T2 7
+#define X_T3 28
+
+#define RD_SHIFT 7
+#define RD_MASK (0x1f << RD_SHIFT)
+#define RS1_SHIFT 15
+#define RS1_MASK (0x1f << RS1_SHIFT)
+#define RS1_SP (X_SP << RS1_SHIFT)
+#define RS2_SHIFT 20
+#define RS2_MASK (0x1f << RS2_SHIFT)
+#define RS2_RA (X_RA << RS2_SHIFT)
+#define IMM_SHIFT 20
+#define IMM_MASK (0xfff << IMM_SHIFT)
+
+#define RS2_C_SHIFT 2
+#define RS2_C_MASK (0x1f << RS2_C_SHIFT)
+#define RS2_C_RA (X_RA << RS2_C_SHIFT)
#define CSR_ZIMM(val) \
(__builtin_constant_p(val) && ((u_long)(val) < 32))
diff --git a/sys/riscv/riscv/copyinout.S b/sys/riscv/riscv/copyinout.S
index a36f7ce63593..5e80f4900c8b 100644
--- a/sys/riscv/riscv/copyinout.S
+++ b/sys/riscv/riscv/copyinout.S
@@ -35,6 +35,7 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+#include <machine/riscvreg.h>
#include <sys/errno.h>
#include "assym.inc"
@@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$");
*/
ENTRY(copyio_fault)
SET_FAULT_HANDLER(x0, a1) /* Clear the handler */
+ EXIT_USER_ACCESS(a1)
copyio_fault_nopcb:
li a0, EFAULT
ret
@@ -62,6 +64,7 @@ ENTRY(copyout)
la a6, copyio_fault /* Get the handler address */
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
+ ENTER_USER_ACCESS(a7)
1: lb a4, 0(a0) /* Load from kaddr */
addi a0, a0, 1
@@ -70,6 +73,7 @@ ENTRY(copyout)
addi a2, a2, -1 /* len-- */
bnez a2, 1b
+ EXIT_USER_ACCESS(a7)
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
2: li a0, 0 /* return 0 */
@@ -89,6 +93,7 @@ ENTRY(copyin)
la a6, copyio_fault /* Get the handler address */
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
+ ENTER_USER_ACCESS(a7)
1: lb a4, 0(a0) /* Load from uaddr */
addi a0, a0, 1
@@ -97,6 +102,7 @@ ENTRY(copyin)
addi a2, a2, -1 /* len-- */
bnez a2, 1b
+ EXIT_USER_ACCESS(a7)
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
2: li a0, 0 /* return 0 */
@@ -111,12 +117,13 @@ END(copyin)
ENTRY(copyinstr)
mv a5, x0 /* count = 0 */
beqz a2, 3f /* If len == 0 then skip loop */
- li a7, VM_MAXUSER_ADDRESS
la a6, copyio_fault /* Get the handler address */
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
+ ENTER_USER_ACCESS(a7)
-1: bgt a7, a0, copyio_fault
+ li a7, VM_MAXUSER_ADDRESS
+1: bgt a0, a7, copyio_fault
lb a4, 0(a0) /* Load from uaddr */
addi a0, a0, 1
sb a4, 0(a1) /* Store in kaddr */
@@ -125,8 +132,9 @@ ENTRY(copyinstr)
addi a2, a2, -1 /* len-- */
addi a5, a5, 1 /* count++ */
bnez a2, 1b
-
-2: SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
+
+2: EXIT_USER_ACCESS(a7)
+ SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
3: beqz a3, 4f /* Check if done != NULL */
addi a5, a5, 1 /* count++ */
diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S
index ef38fa1c108e..3904a67efae1 100644
--- a/sys/riscv/riscv/exception.S
+++ b/sys/riscv/riscv/exception.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -116,11 +116,8 @@ __FBSDID("$FreeBSD$");
.macro load_registers el
ld t0, (TF_SSTATUS)(sp)
.if \el == 0
- /*
- * Ensure user interrupts will be enabled on eret
- * and supervisor mode can access userspace on trap.
- */
- li t1, (SSTATUS_SPIE | SSTATUS_SUM)
+ /* Ensure user interrupts will be enabled on eret */
+ li t1, SSTATUS_SPIE
or t0, t0, t1
.else
/*
diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S
index 4b2e6ad6eed0..e8ba3ceefe96 100644
--- a/sys/riscv/riscv/locore.S
+++ b/sys/riscv/riscv/locore.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -62,9 +62,6 @@ _start:
mv s10, a0 /* s10 = hart id */
mv s11, a1 /* s11 = dtbp */
- li t0, SSTATUS_SUM
- csrs sstatus, t0
-
/* Direct secondary cores to mpentry */
bnez s10, mpentry
diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c
index 840f0bf3c0a9..64d20126f3ad 100644
--- a/sys/riscv/riscv/machdep.c
+++ b/sys/riscv/riscv/machdep.c
@@ -734,12 +734,14 @@ cache_setup(void)
vm_offset_t
fake_preload_metadata(struct riscv_bootparams *rvbp __unused)
{
+ static uint32_t fake_preload[35];
#ifdef DDB
vm_offset_t zstart = 0, zend = 0;
#endif
vm_offset_t lastaddr;
- int i = 0;
- static uint32_t fake_preload[35];
+ int i;
+
+ i = 0;
fake_preload[i++] = MODINFO_NAME;
fake_preload[i++] = strlen("kernel") + 1;
@@ -751,12 +753,13 @@ fake_preload_metadata(struct riscv_bootparams *rvbp __unused)
i += 3;
fake_preload[i++] = MODINFO_ADDR;
fake_preload[i++] = sizeof(vm_offset_t);
- fake_preload[i++] = (uint64_t)(KERNBASE + KERNENTRY);
+ *(vm_offset_t *)&fake_preload[i++] =
+ (vm_offset_t)(KERNBASE + KERNENTRY);
i += 1;
fake_preload[i++] = MODINFO_SIZE;
- fake_preload[i++] = sizeof(uint64_t);
- printf("end is 0x%016lx\n", (uint64_t)&end);
- fake_preload[i++] = (uint64_t)&end - (uint64_t)(KERNBASE + KERNENTRY);
+ fake_preload[i++] = sizeof(vm_offset_t);
+ fake_preload[i++] = (vm_offset_t)&end -
+ (vm_offset_t)(KERNBASE + KERNENTRY);
i += 1;
#ifdef DDB
#if 0
diff --git a/sys/riscv/riscv/support.S b/sys/riscv/riscv/support.S
index e3848cd94c9a..e59302bea9aa 100644
--- a/sys/riscv/riscv/support.S
+++ b/sys/riscv/riscv/support.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -36,6 +36,7 @@
__FBSDID("$FreeBSD$");
#include <machine/setjmp.h>
+#include <machine/riscvreg.h>
#include "assym.inc"
@@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$");
*/
ENTRY(fsu_fault)
SET_FAULT_HANDLER(x0, a1) /* Reset the handler function */
+ EXIT_USER_ACCESS(a1)
fsu_fault_nopcb:
li a0, -1
ret
@@ -57,11 +59,13 @@ ENTRY(casueword32)
bgt a0, a4, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a4) /* And set it */
+ ENTER_USER_ACCESS(a4)
1: lr.w a4, 0(a0) /* Load-exclusive the data */
bne a4, a1, 2f /* If not equal then exit */
sc.w a5, a3, 0(a0) /* Store the new data */
bnez a5, 1b /* Retry on failure */
-2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
+2: EXIT_USER_ACCESS(a5)
+ SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
sw a4, 0(a2) /* Store the read data */
li a0, 0 /* Success */
ret /* Return */
@@ -75,11 +79,13 @@ ENTRY(casueword)
bgt a0, a4, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a4) /* And set it */
+ ENTER_USER_ACCESS(a4)
1: lr.d a4, 0(a0) /* Load-exclusive the data */
bne a4, a1, 2f /* If not equal then exit */
sc.d a5, a3, 0(a0) /* Store the new data */
bnez a5, 1b /* Retry on failure */
-2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
+2: EXIT_USER_ACCESS(a5)
+ SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
sd a4, 0(a2) /* Store the read data */
li a0, 0 /* Success */
ret /* Return */
@@ -93,7 +99,9 @@ ENTRY(fubyte)
bgt a0, a1, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a1) /* And set it */
+ ENTER_USER_ACCESS(a1)
lb a0, 0(a0) /* Try loading the data */
+ EXIT_USER_ACCESS(a1)
SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */
ret /* Return */
END(fubyte)
@@ -106,7 +114,9 @@ ENTRY(fuword16)
bgt a0, a1, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a1) /* And set it */
+ ENTER_USER_ACCESS(a1)
lh a0, 0(a0) /* Try loading the data */
+ EXIT_USER_ACCESS(a1)
SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */
ret /* Return */
END(fuword16)
@@ -119,7 +129,9 @@ ENTRY(fueword32)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
lw a0, 0(a0) /* Try loading the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
sw a0, 0(a1) /* Save the data in kernel space */
li a0, 0 /* Success */
@@ -136,7 +148,9 @@ EENTRY(fueword64)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
ld a0, 0(a0) /* Try loading the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
sd a0, 0(a1) /* Save the data in kernel space */
li a0, 0 /* Success */
@@ -152,7 +166,9 @@ ENTRY(subyte)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
sb a1, 0(a0) /* Try storing the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
li a0, 0 /* Success */
ret /* Return */
@@ -166,7 +182,9 @@ ENTRY(suword16)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
sh a1, 0(a0) /* Try storing the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
li a0, 0 /* Success */
ret /* Return */
@@ -180,7 +198,9 @@ ENTRY(suword32)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
sw a1, 0(a0) /* Try storing the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
li a0, 0 /* Success */
ret /* Return */
@@ -195,7 +215,9 @@ EENTRY(suword64)
bgt a0, a2, fsu_fault_nopcb
la a6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(a6, a2) /* And set it */
+ ENTER_USER_ACCESS(a2)
sd a1, 0(a0) /* Try storing the data */
+ EXIT_USER_ACCESS(a2)
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
li a0, 0 /* Success */
ret /* Return */
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
index 9ba560d43a49..14bb0ee3430f 100644
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -105,7 +105,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
tf->tf_a[0] = 0;
tf->tf_a[1] = 0;
tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */
- tf->tf_sstatus |= (SSTATUS_SUM); /* Supervisor can access userspace. */
tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */
td2->td_frame = tf;
diff --git a/sys/security/audit/audit_bsm_db.c b/sys/security/audit/audit_bsm_db.c
index 36d79c960d0d..41a525a12ea1 100644
--- a/sys/security/audit/audit_bsm_db.c
+++ b/sys/security/audit/audit_bsm_db.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1999-2009 Apple Inc.
- * Copyright (c) 2005, 2016-2017 Robert N. M. Watson
+ * Copyright (c) 2005, 2016-2018 Robert N. M. Watson
* All rights reserved.
*
* Portions of this software were developed by BAE Systems, the University of
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/filedesc.h>
#include <sys/libkern.h>
+#include <sys/linker.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
@@ -91,6 +92,7 @@ static struct evclass_list evclass_hash[EVCLASSMAP_HASH_TABLE_SIZE];
* struct evname_elem is defined in audit_private.h so that audit_dtrace.c can
* use the definition.
*/
+#define EVNAMEMAP_HASH_TABLE_MODULE "etc_security_audit_event"
#define EVNAMEMAP_HASH_TABLE_SIZE 251
struct evname_list {
LIST_HEAD(, evname_elem) enl_head;
@@ -261,6 +263,85 @@ au_evnamemap_insert(au_event_t event, const char *name)
EVNAMEMAP_WUNLOCK();
}
+/*
+ * If /etc/security/audit_event has been preloaded by the boot loader, parse
+ * it to build an initial set of event number<->name mappings.
+ */
+static void
+au_evnamemap_init_preload(void)
+{
+ caddr_t kmdp;
+ char *endptr, *line, *nextline, *ptr;
+ const char *evnum_str, *evname;
+ size_t size;
+ long evnum;
+ u_int lineno;
+
+ kmdp = preload_search_by_type(EVNAMEMAP_HASH_TABLE_MODULE);
+ if (kmdp == NULL)
+ return;
+ ptr = preload_fetch_addr(kmdp);
+ size = preload_fetch_size(kmdp);
+
+ /*
+ * Parse preloaded configuration file "in place". Assume that the
+ * last character is a new line, meaning that we can replace it with a
+ * nul byte safely. We can then use strsep(3) to process the full
+ * buffer.
+ */
+ ptr[size - 1] = '\0';
+
+ /*
+ * Process line by line.
+ */
+ nextline = ptr;
+ lineno = 0;
+ while ((line = strsep(&nextline, "\n")) != NULL) {
+ /*
+ * Skip any leading white space.
+ */
+ while (line[0] == ' ' || line[0] == '\t')
+ line++;
+
+ /*
+ * Skip blank lines and comment lines.
+ */
+ if (line[0] == '\0' || line[0] == '#') {
+ lineno++;
+ continue;
+ }
+
+ /*
+ * Parse each line -- ":"-separated tuple of event number,
+ * event name, and other material we are less interested in.
+ */
+ evnum_str = strsep(&line, ":");
+ if (evnum_str == NULL || *evnum_str == '\0') {
+ printf("%s: Invalid line %u - evnum strsep\n",
+ __func__, lineno);
+ lineno++;
+ continue;
+ }
+ evnum = strtol(evnum_str, &endptr, 10);
+ if (*evnum_str == '\0' || *endptr != '\0' ||
+ evnum <= 0 || evnum > UINT16_MAX) {
+ printf("%s: Invalid line %u - evnum strtol\n",
+ __func__, lineno);
+ lineno++;
+ continue;
+ }
+ evname = strsep(&line, ":");
+ if (evname == NULL || *evname == '\0') {
+ printf("%s: Invalid line %u - evname strsp\n",
+ __func__, lineno);
+ lineno++;
+ continue;
+ }
+ au_evnamemap_insert(evnum, evname);
+ lineno++;
+ }
+}
+
void
au_evnamemap_init(void)
{
@@ -269,13 +350,7 @@ au_evnamemap_init(void)
EVNAMEMAP_LOCK_INIT();
for (i = 0; i < EVNAMEMAP_HASH_TABLE_SIZE; i++)
LIST_INIT(&evnamemap_hash[i].enl_head);
-
- /*
- * XXXRW: Unlike the event-to-class mapping, we don't attempt to
- * pre-populate the list. Perhaps we should...? But not sure we
- * really want to duplicate /etc/security/audit_event in the kernel
- * -- and we'd need a way to remove names?
- */
+ au_evnamemap_init_preload();
}
/*
diff --git a/sys/sys/efi.h b/sys/sys/efi.h
index 0a0699d43256..622df48e7f32 100644
--- a/sys/sys/efi.h
+++ b/sys/sys/efi.h
@@ -169,10 +169,13 @@ struct efi_systbl {
extern vm_paddr_t efi_systbl_phys;
+struct efirt_callinfo;
+
/* Internal MD EFI functions */
int efi_arch_enter(void);
void efi_arch_leave(void);
vm_offset_t efi_phys_to_kva(vm_paddr_t);
+int efi_rt_arch_call(struct efirt_callinfo *);
bool efi_create_1t1_map(struct efi_md *, int, int);
void efi_destroy_1t1_map(void);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 91b296c56304..d3a233867658 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1200083 /* Master, propagated to newvers */
+#define __FreeBSD_version 1200084 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 44d3cfab79dd..ab8a925715d0 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -363,15 +363,11 @@ void realitexpire(void *);
int sysbeep(int hertz, int period);
-void hardclock(int usermode, uintfptr_t pc);
-void hardclock_cnt(int cnt, int usermode);
-void hardclock_cpu(int usermode);
+void hardclock(int cnt, int usermode);
void hardclock_sync(int cpu);
void softclock(void *);
-void statclock(int usermode);
-void statclock_cnt(int cnt, int usermode);
-void profclock(int usermode, uintfptr_t pc);
-void profclock_cnt(int cnt, int usermode, uintfptr_t pc);
+void statclock(int cnt, int usermode);
+void profclock(int cnt, int usermode, uintfptr_t pc);
int hardclockintr(void);
diff --git a/sys/sys/vmmeter.h b/sys/sys/vmmeter.h
index 3c570b0a6b7f..c41b151fa502 100644
--- a/sys/sys/vmmeter.h
+++ b/sys/sys/vmmeter.h
@@ -187,6 +187,13 @@ vm_page_count_severe(void)
return (!DOMAINSET_EMPTY(&vm_severe_domains));
}
+static inline int
+vm_page_count_severe_set(domainset_t *mask)
+{
+
+ return (DOMAINSET_SUBSET(&vm_severe_domains, mask));
+}
+
/*
* Return TRUE if we are under our minimum low-free-pages threshold.
*
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 6cbec2d151e6..636e8e67257e 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -484,8 +484,8 @@ static int doreallocblks = 1;
SYSCTL_INT(_vfs_ffs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0,
"enable block reallocation");
-static int dotrimcons = 0;
-SYSCTL_INT(_vfs_ffs, OID_AUTO, dotrimcons, CTLFLAG_RW, &dotrimcons, 0,
+static int dotrimcons = 1;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, dotrimcons, CTLFLAG_RWTUN, &dotrimcons, 0,
"enable BIO_DELETE / TRIM consolidation");
static int maxclustersearch = 10;
diff --git a/sys/vm/vm_domainset.c b/sys/vm/vm_domainset.c
index eae083adade6..16b078e7dabd 100644
--- a/sys/vm/vm_domainset.c
+++ b/sys/vm/vm_domainset.c
@@ -100,6 +100,8 @@ vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj,
pindex += (((uintptr_t)obj) / sizeof(*obj));
di->di_offset = pindex;
}
+ /* Skip domains below min on the first pass. */
+ di->di_minskip = true;
}
static void
@@ -213,6 +215,8 @@ vm_domainset_iter_page_init(struct vm_domainset_iter *di, struct vm_object *obj,
*req = (di->di_flags & ~(VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) |
VM_ALLOC_NOWAIT;
vm_domainset_iter_first(di, domain);
+ if (DOMAINSET_ISSET(*domain, &vm_min_domains))
+ vm_domainset_iter_page(di, domain, req);
}
int
@@ -227,8 +231,15 @@ vm_domainset_iter_page(struct vm_domainset_iter *di, int *domain, int *req)
return (ENOMEM);
/* If there are more domains to visit we run the iterator. */
- if (--di->di_n != 0) {
+ while (--di->di_n != 0) {
vm_domainset_iter_next(di, domain);
+ if (!di->di_minskip ||
+ !DOMAINSET_ISSET(*domain, &vm_min_domains))
+ return (0);
+ }
+ if (di->di_minskip) {
+ di->di_minskip = false;
+ vm_domainset_iter_first(di, domain);
return (0);
}
@@ -258,6 +269,8 @@ vm_domainset_iter_malloc_init(struct vm_domainset_iter *di,
di->di_flags = *flags;
*flags = (di->di_flags & ~M_WAITOK) | M_NOWAIT;
vm_domainset_iter_first(di, domain);
+ if (DOMAINSET_ISSET(*domain, &vm_min_domains))
+ vm_domainset_iter_malloc(di, domain, flags);
}
int
@@ -265,8 +278,17 @@ vm_domainset_iter_malloc(struct vm_domainset_iter *di, int *domain, int *flags)
{
/* If there are more domains to visit we run the iterator. */
- if (--di->di_n != 0) {
+ while (--di->di_n != 0) {
vm_domainset_iter_next(di, domain);
+ if (!di->di_minskip ||
+ !DOMAINSET_ISSET(*domain, &vm_min_domains))
+ return (0);
+ }
+
+ /* If we skipped domains below min restart the search. */
+ if (di->di_minskip) {
+ di->di_minskip = false;
+ vm_domainset_iter_first(di, domain);
return (0);
}
diff --git a/sys/vm/vm_domainset.h b/sys/vm/vm_domainset.h
index 542fe47da677..10da5caa0ea7 100644
--- a/sys/vm/vm_domainset.h
+++ b/sys/vm/vm_domainset.h
@@ -34,9 +34,10 @@ struct vm_domainset_iter {
struct domainset *di_domain;
int *di_iter;
vm_pindex_t di_offset;
- int di_policy;
int di_flags;
- int di_n;
+ uint16_t di_policy;
+ domainid_t di_n;
+ bool di_minskip;
};
int vm_domainset_iter_page(struct vm_domainset_iter *, int *, int *);
@@ -46,4 +47,6 @@ int vm_domainset_iter_malloc(struct vm_domainset_iter *, int *, int *);
void vm_domainset_iter_malloc_init(struct vm_domainset_iter *,
struct vm_object *, int *, int *);
+void vm_wait_doms(const domainset_t *);
+
#endif /* __VM_DOMAINSET_H__ */
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 9b8d90a423af..d5a6b57f47e3 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -548,6 +548,7 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
{
struct faultstate fs;
struct vnode *vp;
+ struct domainset *dset;
vm_object_t next_object, retry_object;
vm_offset_t e_end, e_start;
vm_pindex_t retry_pindex;
@@ -791,7 +792,11 @@ RetryFault:;
* there, and allocation can fail, causing
* restart and new reading of the p_flag.
*/
- if (!vm_page_count_severe() || P_KILLED(curproc)) {
+ dset = fs.object->domain.dr_policy;
+ if (dset == NULL)
+ dset = curthread->td_domain.dr_policy;
+ if (!vm_page_count_severe_set(&dset->ds_mask) ||
+ P_KILLED(curproc)) {
#if VM_NRESERVLEVEL > 0
vm_object_color(fs.object, atop(vaddr) -
fs.pindex);
@@ -806,7 +811,7 @@ RetryFault:;
}
if (fs.m == NULL) {
unlock_and_deallocate(&fs);
- vm_waitpfault();
+ vm_waitpfault(dset);
goto RetryFault;
}
}
@@ -1124,7 +1129,7 @@ readrest:
*/
fs.object == fs.first_object->backing_object) {
vm_page_lock(fs.m);
- vm_page_remque(fs.m);
+ vm_page_dequeue(fs.m);
vm_page_remove(fs.m);
vm_page_unlock(fs.m);
vm_page_lock(fs.first_m);
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 7952c81a1afe..832dbce324ef 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <vm/vm_domainset.h>
#include <vm/vm_map.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
@@ -534,6 +535,7 @@ vm_forkproc(struct thread *td, struct proc *p2, struct thread *td2,
struct vmspace *vm2, int flags)
{
struct proc *p1 = td->td_proc;
+ struct domainset *dset;
int error;
if ((flags & RFPROC) == 0) {
@@ -557,9 +559,9 @@ vm_forkproc(struct thread *td, struct proc *p2, struct thread *td2,
p2->p_vmspace = p1->p_vmspace;
atomic_add_int(&p1->p_vmspace->vm_refcnt, 1);
}
-
- while (vm_page_count_severe()) {
- vm_wait_severe();
+ dset = td2->td_domain.dr_policy;
+ while (vm_page_count_severe_set(&dset->ds_mask)) {
+ vm_wait_doms(&dset->ds_mask);
}
if ((flags & RFMEM) == 0) {
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 8b25b86d0fcb..d022435704f1 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2627,7 +2627,7 @@ retry:
m_new->dirty = m->dirty;
m->flags &= ~PG_ZERO;
vm_page_xbusy(m);
- vm_page_remque(m);
+ vm_page_dequeue(m);
vm_page_replace_checked(m_new, object,
m->pindex, m);
if (vm_page_free_prep(m))
@@ -2642,7 +2642,7 @@ retry:
vm_page_deactivate(m_new);
} else {
m->flags &= ~PG_ZERO;
- vm_page_remque(m);
+ vm_page_dequeue(m);
vm_page_remove(m);
if (vm_page_free_prep(m))
SLIST_INSERT_HEAD(&free, m,
@@ -2935,7 +2935,7 @@ vm_wait_count(void)
return (vm_severe_waiters + vm_min_waiters + vm_pageproc_waiters);
}
-static void
+void
vm_wait_doms(const domainset_t *wdoms)
{
@@ -2961,10 +2961,10 @@ vm_wait_doms(const domainset_t *wdoms)
mtx_lock(&vm_domainset_lock);
if (DOMAINSET_SUBSET(&vm_min_domains, wdoms)) {
vm_min_waiters++;
- msleep(&vm_min_domains, &vm_domainset_lock, PVM,
- "vmwait", 0);
- }
- mtx_unlock(&vm_domainset_lock);
+ msleep(&vm_min_domains, &vm_domainset_lock,
+ PVM | PDROP, "vmwait", 0);
+ } else
+ mtx_unlock(&vm_domainset_lock);
}
}
@@ -3069,15 +3069,21 @@ vm_domain_alloc_fail(struct vm_domain *vmd, vm_object_t object, int req)
* this balance without careful testing first.
*/
void
-vm_waitpfault(void)
+vm_waitpfault(struct domainset *dset)
{
+ /*
+ * XXX Ideally we would wait only until the allocation could
+ * be satisfied. This condition can cause new allocators to
+ * consume all freed pages while old allocators wait.
+ */
mtx_lock(&vm_domainset_lock);
- if (vm_page_count_min()) {
+ if (DOMAINSET_SUBSET(&vm_min_domains, &dset->ds_mask)) {
vm_min_waiters++;
- msleep(&vm_min_domains, &vm_domainset_lock, PUSER, "pfault", 0);
- }
- mtx_unlock(&vm_domainset_lock);
+ msleep(&vm_min_domains, &vm_domainset_lock, PUSER | PDROP,
+ "pfault", 0);
+ } else
+ mtx_unlock(&vm_domainset_lock);
}
struct vm_pagequeue *
@@ -3101,28 +3107,35 @@ static inline void
vm_pqbatch_process_page(struct vm_pagequeue *pq, vm_page_t m)
{
struct vm_domain *vmd;
- uint8_t aflags;
+ uint8_t qflags;
CRITICAL_ASSERT(curthread);
vm_pagequeue_assert_locked(pq);
- KASSERT(pq == vm_page_pagequeue(m),
- ("page %p doesn't belong to %p", m, pq));
- aflags = m->aflags;
- if ((aflags & PGA_DEQUEUE) != 0) {
- if (__predict_true((aflags & PGA_ENQUEUED) != 0)) {
+ /*
+ * The page daemon is allowed to set m->queue = PQ_NONE without
+ * the page queue lock held. In this case it is about to free the page,
+ * which must not have any queue state.
+ */
+ qflags = atomic_load_8(&m->aflags) & PGA_QUEUE_STATE_MASK;
+ KASSERT(pq == vm_page_pagequeue(m) || qflags == 0,
+ ("page %p doesn't belong to queue %p but has queue state %#x",
+ m, pq, qflags));
+
+ if ((qflags & PGA_DEQUEUE) != 0) {
+ if (__predict_true((qflags & PGA_ENQUEUED) != 0)) {
TAILQ_REMOVE(&pq->pq_pl, m, plinks.q);
vm_pagequeue_cnt_dec(pq);
}
vm_page_dequeue_complete(m);
- } else if ((aflags & (PGA_REQUEUE | PGA_REQUEUE_HEAD)) != 0) {
- if ((aflags & PGA_ENQUEUED) != 0)
+ } else if ((qflags & (PGA_REQUEUE | PGA_REQUEUE_HEAD)) != 0) {
+ if ((qflags & PGA_ENQUEUED) != 0)
TAILQ_REMOVE(&pq->pq_pl, m, plinks.q);
else {
vm_pagequeue_cnt_inc(pq);
vm_page_aflag_set(m, PGA_ENQUEUED);
}
- if ((aflags & PGA_REQUEUE_HEAD) != 0) {
+ if ((qflags & PGA_REQUEUE_HEAD) != 0) {
KASSERT(m->queue == PQ_INACTIVE,
("head enqueue not supported for page %p", m));
vmd = vm_pagequeue_domain(m);
@@ -3393,18 +3406,18 @@ vm_page_requeue(vm_page_t m)
void
vm_page_activate(vm_page_t m)
{
- int queue;
vm_page_assert_locked(m);
- if ((queue = vm_page_queue(m)) == PQ_ACTIVE || m->wire_count > 0 ||
- (m->oflags & VPO_UNMANAGED) != 0) {
- if (queue == PQ_ACTIVE && m->act_count < ACT_INIT)
+ if (m->wire_count > 0 || (m->oflags & VPO_UNMANAGED) != 0)
+ return;
+ if (vm_page_queue(m) == PQ_ACTIVE) {
+ if (m->act_count < ACT_INIT)
m->act_count = ACT_INIT;
return;
}
- vm_page_remque(m);
+ vm_page_dequeue(m);
if (m->act_count < ACT_INIT)
m->act_count = ACT_INIT;
vm_page_enqueue(m, PQ_ACTIVE);
@@ -3676,7 +3689,7 @@ vm_page_deactivate(vm_page_t m)
return;
if (!vm_page_inactive(m)) {
- vm_page_remque(m);
+ vm_page_dequeue(m);
vm_page_enqueue(m, PQ_INACTIVE);
} else
vm_page_requeue(m);
@@ -3699,9 +3712,10 @@ vm_page_deactivate_noreuse(vm_page_t m)
if (m->wire_count > 0 || (m->oflags & VPO_UNMANAGED) != 0)
return;
- if (!vm_page_inactive(m))
- vm_page_remque(m);
- m->queue = PQ_INACTIVE;
+ if (!vm_page_inactive(m)) {
+ vm_page_dequeue(m);
+ m->queue = PQ_INACTIVE;
+ }
if ((m->aflags & PGA_REQUEUE_HEAD) == 0)
vm_page_aflag_set(m, PGA_REQUEUE_HEAD);
vm_pqbatch_submit_page(m, PQ_INACTIVE);
@@ -3723,7 +3737,7 @@ vm_page_launder(vm_page_t m)
if (vm_page_in_laundry(m))
vm_page_requeue(m);
else {
- vm_page_remque(m);
+ vm_page_dequeue(m);
vm_page_enqueue(m, PQ_LAUNDRY);
}
}
@@ -3741,7 +3755,7 @@ vm_page_unswappable(vm_page_t m)
KASSERT(m->wire_count == 0 && (m->oflags & VPO_UNMANAGED) == 0,
("page %p already unswappable", m));
- vm_page_remque(m);
+ vm_page_dequeue(m);
vm_page_enqueue(m, PQ_UNSWAPPABLE);
}
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 73d289fd8b13..cf00912487ef 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -740,22 +740,6 @@ vm_page_dirty(vm_page_t m)
}
/*
- * vm_page_remque:
- *
- * If the given page is in a page queue, then remove it from that page
- * queue.
- *
- * The page must be locked.
- */
-static inline void
-vm_page_remque(vm_page_t m)
-{
-
- if (m->queue != PQ_NONE)
- vm_page_dequeue(m);
-}
-
-/*
* vm_page_undirty:
*
* Set page to not be dirty. Note: does not clear pmap modify bits
diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h
index 935088f1f301..3b238a0ba3fb 100644
--- a/sys/vm/vm_pageout.h
+++ b/sys/vm/vm_pageout.h
@@ -96,7 +96,7 @@ extern int vm_pageout_page_count;
*/
void vm_wait(vm_object_t obj);
-void vm_waitpfault(void);
+void vm_waitpfault(struct domainset *);
void vm_wait_domain(int domain);
void vm_wait_min(void);
void vm_wait_severe(void);
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 6f0440cfdc2d..890f5dad9213 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -460,7 +460,7 @@ void
vm_phys_init(void)
{
struct vm_freelist *fl;
- struct vm_phys_seg *seg;
+ struct vm_phys_seg *end_seg, *prev_seg, *seg, *tmp_seg;
u_long npages;
int dom, flind, freelist, oind, pind, segind;
@@ -547,6 +547,29 @@ vm_phys_init(void)
}
/*
+ * Coalesce physical memory segments that are contiguous and share the
+ * same per-domain free queues.
+ */
+ prev_seg = vm_phys_segs;
+ seg = &vm_phys_segs[1];
+ end_seg = &vm_phys_segs[vm_phys_nsegs];
+ while (seg < end_seg) {
+ if (prev_seg->end == seg->start &&
+ prev_seg->free_queues == seg->free_queues) {
+ prev_seg->end = seg->end;
+ KASSERT(prev_seg->domain == seg->domain,
+ ("vm_phys_init: free queues cannot span domains"));
+ vm_phys_nsegs--;
+ end_seg--;
+ for (tmp_seg = seg; tmp_seg < end_seg; tmp_seg++)
+ *tmp_seg = *(tmp_seg + 1);
+ } else {
+ prev_seg = seg;
+ seg++;
+ }
+ }
+
+ /*
* Initialize the free queues.
*/
for (dom = 0; dom < vm_ndomains; dom++) {
diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c
index a879d616d17a..9f93ec96f837 100644
--- a/sys/x86/x86/intr_machdep.c
+++ b/sys/x86/x86/intr_machdep.c
@@ -173,8 +173,10 @@ intr_init_sources(void *arg)
interrupt_sources = mallocarray(num_io_irqs, sizeof(*interrupt_sources),
M_INTR, M_WAITOK | M_ZERO);
+#ifdef SMP
interrupt_sorted = mallocarray(num_io_irqs, sizeof(*interrupt_sorted),
M_INTR, M_WAITOK | M_ZERO);
+#endif
/*
* - 1 ??? dummy counter.