summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include
Commit message (Collapse)AuthorAgeFilesLines
* Revert "Revert "MFC r319871:""Luiz Souza2018-02-231-7/+7
| | | | This reverts commit 63302e53ed4b3fe59711d939ba87433a9a12199d.
* Revert "Revert "MFC ↵Luiz Souza2018-02-238-70/+232
| | | | | | r328083,328096,328116,328119,328120,328128,328135,328153,328157,"" This reverts commit d3d59b01294138e59995b31d2bcbbbdf45e26a3c.
* Revert "Revert "MFC r321899""Luiz Souza2018-02-231-1/+4
| | | | This reverts commit 364d23417fdf8cd90b896af94c6857c6ba13be8c.
* Revert "Revert "MFC r327818:""Luiz Souza2018-02-231-0/+1
| | | | This reverts commit c1ee180537f04875eccd8e9b3d630b73ad654b14.
* Revert "Revert "MFC r322762, r322799, r322832, r322833:""Luiz Souza2018-02-232-31/+11
| | | | This reverts commit 5919c0a9658dde48bd090704915aa3a85a6c0d26.
* Merge remote-tracking branch 'origin/RELENG_2_4-meltdown' into RELENG_2_4Luiz Souza2018-02-231-0/+32
|\
| * MFC r322495:kib2018-02-211-0/+32
| | | | | | | | | | | | Add {rd,wr}{fs,gs}base C wrappers for instructions. (cherry picked from commit 26ec28780cfd5213d56ad9d182c70613df690ba8)
* | Revert "MFC r322762, r322799, r322832, r322833:"Luiz Souza2018-02-212-11/+31
| | | | | | | | This reverts commit 2589da26b930eaf9441b6bf27c0f410062adf507.
* | Revert "MFC r327818:"Luiz Souza2018-02-211-1/+0
| | | | | | | | This reverts commit ba6ece08e939b4f3d25e9e81956e8d622ed1fc2e.
* | Revert "MFC r321899"Luiz Souza2018-02-211-4/+1
| | | | | | | | This reverts commit 1027b09f970c81aab8f721168a4500261978c198.
* | Revert "MFC r328083,328096,328116,328119,328120,328128,328135,328153,328157,"Luiz Souza2018-02-218-232/+70
| | | | | | | | This reverts commit 430a2bea3907149b30cc75fc722b6cf1f81da82a.
* | Revert "MFC r319871:"Luiz Souza2018-02-211-7/+7
|/ | | | This reverts commit 045793a68906243d204d36b336867187c1a33f00.
* MFC r319871:kib2018-02-191-7/+7
| | | | | | | Make struct syscall_args visible to userspace compilation environment from machine/proc.h, consistently on all architectures. (cherry picked from commit 06d5fa0600b92e97e90e41785ef10f641bdec89f)
* MFC r328083,328096,328116,328119,328120,328128,328135,328153,328157,kib2018-02-198-70/+232
| | | | | | | | | | | | | | 328166,328177,328199,328202,328205,328468,328470,328624,328625,328627, 328628,329214,329297,329365: Meltdown mitigation by PTI, PCID optimization of PTI, and kernel use of IBRS for some mitigations of Spectre. Tested by: emaste, Arshan Khanifar <arshankhanifar@gmail.com> Discussed with: jkim Sponsored by: The FreeBSD Foundation (cherry picked from commit 6dd025b40ee6870bea6ba670f30dcf684edc3f6c)
* MFC r321899truckman2018-02-191-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Lower the amd64 shared page, which contains the signal trampoline, from the top of user memory to one page lower on machines with the Ryzen (AMD Family 17h) CPU. This pushes ps_strings and the stack down by one page as well. On Ryzen there is some sort of interaction between code running at the top of user memory address space and interrupts that can cause FreeBSD to either hang or silently reset. This sounds similar to the problem found with DragonFly BSD that was fixed with this commit: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/b48dd28447fc8ef62fbc963accd301557fd9ac20 but our signal trampoline location was already lower than the address that DragonFly moved their signal trampoline to. It also does not appear to be related to SMT as described here: https://www.phoronix.com/forums/forum/hardware/processors-memory/955368-some-ryzen-linux-users-are-facing-issues-with-heavy-compilation-loads?p=955498#post955498 "Hi, Matt Dillon here. Yes, I did find what I believe to be a hardware issue with Ryzen related to concurrent operations. In a nutshell, for any given hyperthread pair, if one hyperthread is in a cpu-bound loop of any kind (can be in user mode), and the other hyperthread is returning from an interrupt via IRETQ, the hyperthread issuing the IRETQ can stall indefinitely until the other hyperthread with the cpu-bound loop pauses (aka HLT until next interrupt). After this situation occurs, the system appears to destabilize. The situation does not occur if the cpu-bound loop is on a different core than the core doing the IRETQ. The %rip the IRETQ returns to (e.g. userland %rip address) matters a *LOT*. The problem occurs more often with high %rip addresses such as near the top of the user stack, which is where DragonFly's signal trampoline traditionally resides. So a user program taking a signal on one thread while another thread is cpu-bound can cause this behavior. Changing the location of the signal trampoline makes it more difficult to reproduce the problem. I have not been because the able to completely mitigate it. When a cpu-thread stalls in this manner it appears to stall INSIDE the microcode for IRETQ. It doesn't make it to the return pc, and the cpu thread cannot take any IPIs or other hardware interrupts while in this state." since the system instability has been observed on FreeBSD with SMT disabled. Interrupts to appear to play a factor since running a signal-intensive process on the first CPU core, which handles most of the interrupts on my machine, is far more likely to trigger the problem than running such a process on any other core. Also lower sv_maxuser to prevent a malicious user from using mmap() to load and execute code in the top page of user memory that was made available when the shared page was moved down. Make the same changes to the 64-bit Linux emulator. PR: 219399 Reported by: nbe@renzel.net Reviewed by: kib Reviewed by: dchagin (previous version) Tested by: nbe@renzel.net (earlier version) Differential Revision: https://reviews.freebsd.org/D11780 (cherry picked from commit 4571a19dd885caa3f20979daa951df05cb5664a2)
* MFC r327818:kib2018-02-191-0/+1
| | | | | | Move the hardware setup for fast syscalls into a common function. (cherry picked from commit ee52c56e9fd3893f553479a1119972766e1bf10d)
* MFC r322762, r322799, r322832, r322833:kib2018-02-192-31/+11
| | | | | | Make WRFSBASE and WRGSBASE instructions functional. (cherry picked from commit b1a7a7418e73251aad628dc4f9418e550a9fd3d7)
* MFC r314310alc2017-06-281-0/+1
| | | | | | | | | | Refine the fix from r312954. Specifically, add a new PDE-only flag, PG_PROMOTED, that indicates whether lingering 4KB page mappings might need to be flushed on a PDE change that restricts or destroys a 2MB page mapping. This flag allows the pmap to avoid range invalidations that are both unnecessary and costly. Approved by: re (kib)
* MFC r318398:trasz2017-06-061-1/+1
| | | | | | | | | | | Bump default MAXTSIZ (kern.maxtsiz) from 128MB to 32GB. The old limit prevents one from running eg clang built with debug; the new one is arbitrary (equal to MAXDSIZ) and... well, should be quite future-proof. Same fix might be applicable to other 64 bit architectures; I'll ask their respective maintainers to make sure it won't break anything. Approved by: re (kib)
* MFC r303261,r315059:mmel2017-04-161-0/+3
| | | | | | | | r303261: Add more UEFI/e820 memory types from latest specifications. r315059: Split overbloated machep.c to multiple files and do basic cleanup of these fragments.
* MFC r311169,r311898,r312925,r312973,r312975,r313007,r313040,r313080,mjg2017-03-161-0/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | r313254,r313341 amd64: add atomic_fcmpset == sparc64: add atomic_fcmpset == Implement atomic_fcmpset_* for arm and arm64. == Add atomic_fcmpset_*() inlines for powerpc Summary: atomic_fcmpset_*() is analogous to atomic_cmpset(), but saves off the read value from the target memory location into the 'old' pointer in the case of failure. == i386: add atomic_fcmpset == Don't retry a lost reservation in atomic_fcmpset() The desired behavior of atomic_fcmpset_() is to always exit on error. Instead of retrying on lost reservation, leave the retry to the caller, and return == Add atomic_fcmpset_*() inlines for MIPS atomic_fcmpset_*() is analogous to atomic_cmpset(), but saves off the read value from the target memory location into the 'old' pointer. == i386: fixup fcmpset An incorrect output specifier was used which worked with clang by accident, but breaks with the in-tree gcc version. While here plug a whitespace nit. == Implement atomic_fcmpset_*() for RISC-V. == Use 64bit store instruction in atomic_fcmpset_64.
* MFC r312555:kib2017-02-031-0/+7
| | | | Use SFENCE for ordering CLFLUSHOPT.
* MFC 308142: Move declarations of invpcid_works and pmap_pcid_enabled to pmap.h.jhb2016-11-222-3/+2
| | | | | | Previously these were only declared under #ifdef SMP in <machine/smp.h>. However, these variables are defind in pmap.c unconditionally, and efirt.c references them unconditionally. This fixes non-SMP kernel builds.
* MFC 305836: Remove 'cpu' and 'cpu_class' on amd64.jhb2016-11-081-44/+2
| | | | | | | | The 'cpu' and 'cpu_class' variables were always set to the same value on amd64 and are legacy holdovers from i386. Remove them entirely on amd64. Requested by: kib (MFC)
* Merge bde improvements for ddb on x86, mostly for single-stepping andkib2016-11-071-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | vm86 mode. MFC r304085 (by bde): Fix the variables $esp, $ds, $es, $fs, $gs and $ss in vm86 mode. Fix PC_REGS() so that printing of instructions works in some useful cases. MFC r304962 (by bde): Expand error messages: print symbol names, parentheses and shift tokens, and negative shift counts. Fix error messages. MFC r305612 (by bde): Fix single-stepping of instructions emulated by vm86. MFC r305661 (by bde): Give the full syntax of the 'count' arg for all commmands that support it. Give the full syntax of the 'addr' arg for these commands and some others. Rename it from 'address' for the generic command. Fix description of how 'count' is supposed to work for the 'break' command. Don't (mis)describe the syntax of the comma for the 'step' command. Expand the description for the generic command. Give the full syntax for the 'examine' command. It was also missing the possible values for the modifier. MFC r305663 (by bde): Fix stopping when the specified breakpoint count is reached. MFC r305665 (by bde): Pass the trap type and code down from db_trap() to db_stop_at_pc() so that the latter can easily determine what the trap type actually is after callers are fixed to encode the type unambigously. MFC r305807 (by bde): Use the MI macro TRAPF_USERMODE() instead of open-coded checks for SEL_UPL and sometimes PSL_VM. Fix logic errors in treating vm86 bioscall mode as kernel mode. The main place checked all the necessary flags, but put the necessary parentheses for the PSL_VM and PCB_VM86CALL checks in the wrong place. MFC r305811 (by bz): Try to fix LINT builds after r305807. MFC r305840 (by bde): Abort single stepping in ddb if the trap is not for single-stepping. MFC r305862 (by bde): Ifdef the new dr6 variable for KDB. MFC r305864 (by bde): Statically initialize the run mode to the one that will become current on first entry. Don't reset to the run mode to STEP_NONE when stopping, and remove STEP_NONE. MFC r305865 (by bde): Fix decoding of tf_rsp on amd64, and move TF_HAS_STACKREGS() to the i386-only section, and fix a comment about the amd64 kernel trapframe not having stackregs. MFC r305897 (by bde): Silently ignore unexpected single-step traps. MFC r306311 (by bde): Determine the operand/address size of %cs in a new function db_segsize(). Use db_segsize() to set the default operand/address size for disassembling. Fix db_print_loc_and_inst() to ask for the normal format and not the alternate in normal operation. Use db_segsize() to avoid trying to print a garbage stack trace if %cs is 16 bits.
* MFC r306680:kib2016-10-241-1/+2
| | | | Reduce the cost of TLB invalidation on x86 by using per-CPU completion flags.
* MFC r306097:kib2016-10-051-0/+17
| | | | | | | | | | | | | Add kernel interfaces to call EFI Runtime Services. MFC r306104: Fix build of the module outside the kernel tree. MFC r306209 (by imp): Change the efi_get_table interface to a void **. MFC r306351: Handle TLB shootdown IPI during the EFI runtime calls, on SandyBridges.
* MFC r306091:kib2016-09-281-0/+42
| | | | | | Add a way for the architecture to specify the calling ABI for methods in the EFI Runtime Services Table. On amd64, the calling conventions are MS.
* MFC r306088:kib2016-09-281-0/+33
| | | | Add amd64 functions to load/store GDT register, store IDT and TR registers.
* MFC r306087:kib2016-09-281-0/+2
| | | | | Export the pmap_cache_bits() and pmap_pinit_pml4() functions from the amd64 pmap.
* MFC r306020:kib2016-09-271-0/+29
| | | | Move pmap_p*e_index() inline functions from pmap.c to pmap.h.
* MFC r305692:kib2016-09-252-0/+2
| | | | Add FPU_KERN_NOCTX flag to the fpu_kern_enter() function on amd64.
* MFC 304637: Fix build for !SMP kernels after the Xen MSIX workaround.jhb2016-09-091-1/+2
| | | | | | | Move msix_disable_migration under #ifdef SMP since it doesn't make sense for !SMP kernels. PR: 212014
* MFC r302635:royger2016-07-151-0/+2
| | | | | | xen: automatically disable MSI-X interrupt migration Approved by: re (kib)
* Replace a number of conflations of mp_ncpus and mp_maxid with eithernwhitehorn2016-07-061-1/+1
| | | | | | | | | | | | | | | | | | | mp_maxid or CPU_FOREACH() as appropriate. This fixes a number of places in the kernel that assumed CPU IDs are dense in [0, mp_ncpus) and would try, for example, to run tasks on CPUs that did not exist or to allocate too few buffers on systems with sparse CPU IDs in which there are holes in the range and mp_maxid > mp_ncpus. Such circumstances generally occur on systems with SMT, but on which SMT is disabled. This patch restores system operation at least on POWER8 systems configured in this way. There are a number of other places in the kernel with potential problems in these situations, but where sparse CPU IDs are not currently known to occur, mostly in the ARM machine-dependent code. These will be fixed in a follow-up commit after the stable/11 branch. PR: kern/210106 Reviewed by: jhb Approved by: re (glebius)
* atomic: Add testandclear on i386/amd64sephe2016-05-161-0/+38
| | | | | | Reviewed by: kib Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6381
* Eliminate pvh_global_lock from the amd64 pmap.kib2016-05-141-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The only current purpose of the pvh lock was explained there On Wed, Jan 09, 2013 at 11:46:13PM -0600, Alan Cox wrote: > Let me lay out one example for you in detail. Suppose that we have > three processors and two of these processors are actively using the same > pmap. Now, one of the two processors sharing the pmap performs a > pmap_remove(). Suppose that one of the removed mappings is to a > physical page P. Moreover, suppose that the other processor sharing > that pmap has this mapping cached with write access in its TLB. Here's > where the trouble might begin. As you might expect, the processor > performing the pmap_remove() will acquire the fine-grained lock on the > PV list for page P before destroying the mapping to page P. Moreover, > this processor will ensure that the vm_page's dirty field is updated > before releasing that PV list lock. However, the TLB shootdown for this > mapping may not be initiated until after the PV list lock is released. > The processor performing the pmap_remove() is not problematic, because > the code being executed by that processor won't presume that the mapping > is destroyed until the TLB shootdown has completed and pmap_remove() has > returned. However, the other processor sharing the pmap could be > problematic. Specifically, suppose that the third processor is > executing the page daemon and concurrently trying to reclaim page P. > This processor performs a pmap_remove_all() on page P in preparation for > reclaiming the page. At this instant, the PV list for page P may > already be empty but our second processor still has a stale TLB entry > mapping page P. So, changes might still occur to the page after the > page daemon believes that all mappings have been destroyed. (If the PV > entry had still existed, then the pmap lock would have ensured that the > TLB shootdown completed before the pmap_remove_all() finished.) Note, > however, the page daemon will know that the page is dirty. It can't > possibly mistake a dirty page for a clean one. However, without the > current pvh global locking, I don't think anything is stopping the page > daemon from starting the laundering process before the TLB shootdown has > completed. > > I believe that a similar example could be constructed with a clean page > P' and a stale read-only TLB entry. In this case, the page P' could be > "cached" in the cache/free queues and recycled before the stale TLB > entry is flushed. TLBs for addresses with updated PTEs are always flushed before pmap lock is unlocked. On the other hand, amd64 pmap code does not always flushes TLBs before PV list locks are unlocked, if previously PTEs were cleared and PV entries removed. To handle the situations where a thread might notice empty PV list but third thread still having access to the page due to TLB invalidation not finished yet, introduce delayed invalidation. Comparing with the pvh_global_lock, DI does not block entered thread when pmap_remove_all() or pmap_remove_write() (callers of pmap_delayed_invl_wait()) are executed in parallel. But _invl_wait() callers are blocked until all previously noted DI blocks are leaved, thus ensuring that neccessary TLB invalidations were performed before returning from pmap_remove_all() or pmap_remove_write(). See comments for detailed description of the mechanism, and also for the explanations why several pmap methods, most important pmap_enter(), do not need DI protection. Reviewed by: alc, jhb (turnstile KPI usage) Tested by: pho (previous version) Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D5747
* Add locking annotations to amd64 struct md_page members.kib2016-05-101-2/+6
| | | | | | Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week
* Add a new bus method to fetch device-specific CPU sets.jhb2016-05-091-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | bus_get_cpus() returns a specified set of CPUs for a device. It accepts an enum for the second parameter that indicates the type of cpuset to request. Currently two valus are supported: - LOCAL_CPUS (on x86 this returns all the CPUs in the package closest to the device when DEVICE_NUMA is enabled) - INTR_CPUS (like LOCAL_CPUS but only returns 1 SMT thread for each core) For systems that do not support NUMA (or if it is not enabled in the kernel config), LOCAL_CPUS fails with EINVAL. INTR_CPUS is mapped to 'all_cpus' by default. The idea is that INTR_CPUS should always return a valid set. Device drivers which want to use per-CPU interrupts should start using INTR_CPUS instead of simply assigning interrupts to all available CPUs. In the future we may wish to add tunables to control the policy of INTR_CPUS (e.g. should it be local-only or global, should it ignore SMT threads or not). The x86 nexus driver exposes the internal set of interrupt CPUs from the the x86 interrupt code via INTR_CPUS. The ACPI bus driver and PCI bridge drivers use _PXM to return a suitable LOCAL_CPUS set when _PXM exists and DEVICE_NUMA is enabled. They also and the global INTR_CPUS set from the nexus driver with the per-domain set from _PXM to generate a local INTR_CPUS set for child devices. Compared to the r298933, this version uses 'struct _cpuset' in <sys/bus.h> instead of 'cpuset_t' to avoid requiring <sys/param.h> (<sys/_cpuset.h> still requires <sys/param.h> for MAXCPU even though <sys/_bitset.h> does not after recent changes).
* sys/amd64: Small spelling fixes.pfg2016-05-031-1/+1
| | | | No functional change.
* Revert bus_get_cpus() for now.jhb2016-05-031-3/+0
| | | | | I really thought I had run this through the tinderbox before committing, but many places need <sys/types.h> -> <sys/param.h> for <sys/bus.h> now.
* Add a new bus method to fetch device-specific CPU sets.jhb2016-05-021-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | bus_get_cpus() returns a specified set of CPUs for a device. It accepts an enum for the second parameter that indicates the type of cpuset to request. Currently two valus are supported: - LOCAL_CPUS (on x86 this returns all the CPUs in the package closest to the device when DEVICE_NUMA is enabled) - INTR_CPUS (like LOCAL_CPUS but only returns 1 SMT thread for each core) For systems that do not support NUMA (or if it is not enabled in the kernel config), LOCAL_CPUS fails with EINVAL. INTR_CPUS is mapped to 'all_cpus' by default. The idea is that INTR_CPUS should always return a valid set. Device drivers which want to use per-CPU interrupts should start using INTR_CPUS instead of simply assigning interrupts to all available CPUs. In the future we may wish to add tunables to control the policy of INTR_CPUS (e.g. should it be local-only or global, should it ignore SMT threads or not). The x86 nexus driver exposes the internal set of interrupt CPUs from the the x86 interrupt code via INTR_CPUS. The ACPI bus driver and PCI bridge drivers use _PXM to return a suitable LOCAL_CPUS set when _PXM exists and DEVICE_NUMA is enabled. They also and the global INTR_CPUS set from the nexus driver with the per-domain set from _PXM to generate a local INTR_CPUS set for child devices. Reviewed by: wblock (manpage) Differential Revision: https://reviews.freebsd.org/D5519
* Enable DEVICE_NUMA with up to 8 domains by default on amd64.jhb2016-04-121-1/+1
| | | | | | | | | 8 memory domains should handle a quad-socket board with dual-domain processors. Reviewed by: kib Relnotes: maybe? Differential Revision: https://reviews.freebsd.org/D5893
* Type of the interrupt handlers on x86 cannot be expressed in C.kib2016-03-292-4/+1
| | | | | | | | Simplify and unify placeholder type definitions. Reviewed by: jhb Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D5771
* Add missing atomic wrapper macro.hselasky2016-01-211-0/+1
| | | | | | Reviewed by: alfred @ Sponsored by: Mellanox Technologies MFC after: 1 week
* Move amd64 metadata.h to x86 and share with i386emaste2016-01-071-54/+3
| | | | MFC after: 1 week
* Move shared variables from {amd64,i386}/initcpu.c to x86/identcpu.c.jhb2015-12-231-13/+2
| | | | | | | | While here, move the common bits of <machine/cputypes.h> to <x86/cputypes.h> as well. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D4670
* Remove redundant ctx_switch_xsave declaration in sys/amd64/include/md_var.hngie2015-12-221-1/+0
| | | | | | | | | | | | This variable was added to sys/x86/include/x86_var.h recently. This unbreaks building kernel source that #includes both md_var.h and x86_var.h with gcc 4.2.1 on amd64 Differential Revision: https://reviews.freebsd.org/D4686 Reviewed by: kib X-MFC with: r291949 Sponsored by: EMC / Isilon Storage Division
* Merge common parts of i386 and amd64 md_var.h and smp.h intokib2015-12-072-157/+9
| | | | | | | | new headers x86/include x86_var.h and x86_smp.h. Reviewed by: emaste, jhb Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D4358
* For amd64 non-PCID machines, and for i386 machines with support forkib2015-12-032-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | the PG_G global pte flag, pmap_invalidate_all() fails to flush global TLB entries [*]. This is because TLB shootdown handler for such configs reloads CR3, and on i386 pmap_invalidate_all() does the same for the initiating CPU. Note that current code does not issue total invalidation requests for the kernel_pmap. Rename amd64 function invltlb_globpcid() to invltlb_glob(), it is not specific for PCID for quite some time, and implement the same functionality for i386. Use the function instead of invltlb() in shootdown handlers and in i386 pmap_invalidate_all(), but only for the kernel pmap (which maps pages with the PG_G attribute set), which takes care of PG_G TLB entries on flush. To detect the affected pmap in i386 TLB shootdown handler, pmap should be passed to the smp_masked_invltlb() function, which makes amd64 and i386 TLB shootdown code almost identical. Merge the code under x86/. Noted by: jhb [*] Reviewed by: cem, jhb, pho Tested by: pho Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D4346
OpenPOWER on IntegriCloud