diff options
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/e1000/e1000_osdep.h | 46 | ||||
| -rw-r--r-- | sys/dev/e1000/if_em.c | 83 | ||||
| -rw-r--r-- | sys/dev/iommu/busdma_iommu.c | 7 | ||||
| -rw-r--r-- | sys/dev/le/lance.c | 2 | ||||
| -rw-r--r-- | sys/dev/nvme/nvme_ctrlr.c | 24 | ||||
| -rw-r--r-- | sys/dev/nvme/nvme_ns.c | 5 | ||||
| -rw-r--r-- | sys/dev/nvme/nvme_private.h | 1 | ||||
| -rw-r--r-- | sys/dev/random/fenestrasX/fx_pool.c | 15 | ||||
| -rw-r--r-- | sys/dev/random/ivy.c | 69 | ||||
| -rw-r--r-- | sys/dev/random/random_harvestq.c | 4 | ||||
| -rw-r--r-- | sys/dev/random/rdseed.c | 169 | ||||
| -rw-r--r-- | sys/dev/sound/dummy.c | 6 | ||||
| -rw-r--r-- | sys/dev/sound/pcm/dsp.c | 18 | ||||
| -rw-r--r-- | sys/dev/vmm/vmm_dev.c | 23 | ||||
| -rw-r--r-- | sys/dev/vmm/vmm_dev.h | 1 |
15 files changed, 349 insertions, 124 deletions
diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h index 893979025f01..ba1c8a16fad1 100644 --- a/sys/dev/e1000/e1000_osdep.h +++ b/sys/dev/e1000/e1000_osdep.h @@ -152,6 +152,9 @@ struct e1000_osdep { bus_space_tag_t mem_bus_space_tag; bus_space_handle_t mem_bus_space_handle; +#ifdef INVARIANTS + bus_size_t mem_bus_space_size; +#endif bus_space_tag_t io_bus_space_tag; bus_space_handle_t io_bus_space_handle; bus_space_tag_t flash_bus_space_tag; @@ -175,27 +178,44 @@ struct e1000_osdep bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset, value) +static __inline uint32_t +e1000_rd32(struct e1000_osdep *osdep, uint32_t reg) +{ + + KASSERT(reg < osdep->mem_bus_space_size, + ("e1000: register offset %#jx too large (max is %#jx)", + (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size)); + + return (bus_space_read_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, reg)); +} + + +static __inline void +e1000_wr32(struct e1000_osdep *osdep, uint32_t reg, uint32_t value) +{ + + KASSERT(reg < osdep->mem_bus_space_size, + ("e1000: register offset %#jx too large (max is %#jx)", + (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size)); + + bus_space_write_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, reg, value); +} + /* Register READ/WRITE macros */ -#define E1000_READ_REG(hw, reg) \ - bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ - ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ - E1000_REGISTER(hw, reg)) +#define E1000_READ_REG(hw, reg) \ + e1000_rd32((hw)->back, E1000_REGISTER(hw, reg)) #define E1000_WRITE_REG(hw, reg, value) \ - bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ - ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ - E1000_REGISTER(hw, reg), value) + e1000_wr32((hw)->back, E1000_REGISTER(hw, reg), value) #define E1000_READ_REG_ARRAY(hw, reg, index) \ - bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ - ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ - E1000_REGISTER(hw, reg) + ((index)<< 2)) + e1000_rd32((hw)->back, E1000_REGISTER(hw, reg) + ((index) << 2)) #define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \ - bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ - ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \ - E1000_REGISTER(hw, reg) + ((index)<< 2), value) + e1000_wr32((hw)->back, E1000_REGISTER(hw, reg) + ((index) << 2), value) #define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY #define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 247cf9d7fed3..e3d839b828ed 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1582,7 +1582,7 @@ em_if_init(if_ctx_t ctx) E1000_WRITE_REG(&sc->hw, E1000_VET, ETHERTYPE_VLAN); /* Clear bad data from Rx FIFOs */ - if (sc->hw.mac.type >= igb_mac_min) + if (sc->hw.mac.type >= igb_mac_min && !sc->vf_ifp) e1000_rx_fifo_flush_base(&sc->hw); /* Configure for OS presence */ @@ -1602,7 +1602,9 @@ em_if_init(if_ctx_t ctx) /* Don't lose promiscuous settings */ em_if_set_promisc(ctx, if_getflags(ifp)); - e1000_clear_hw_cntrs_base_generic(&sc->hw); + + if (sc->hw.mac.ops.clear_hw_cntrs != NULL) + sc->hw.mac.ops.clear_hw_cntrs(&sc->hw); /* MSI-X configuration for 82574 */ if (sc->hw.mac.type == e1000_82574) { @@ -2349,7 +2351,7 @@ em_if_stop(if_ctx_t ctx) em_flush_desc_rings(sc); e1000_reset_hw(&sc->hw); - if (sc->hw.mac.type >= e1000_82544) + if (sc->hw.mac.type >= e1000_82544 && !sc->vf_ifp) E1000_WRITE_REG(&sc->hw, E1000_WUFC, 0); e1000_led_off(&sc->hw); @@ -2408,6 +2410,9 @@ em_allocate_pci_resources(if_ctx_t ctx) } sc->osdep.mem_bus_space_tag = rman_get_bustag(sc->memory); sc->osdep.mem_bus_space_handle = rman_get_bushandle(sc->memory); +#ifdef INVARIANTS + sc->osdep.mem_bus_space_size = rman_get_size(sc->memory); +#endif sc->hw.hw_addr = (u8 *)&sc->osdep.mem_bus_space_handle; /* Only older adapters use IO mapping */ @@ -3259,11 +3264,13 @@ em_reset(if_ctx_t ctx) /* Issue a global reset */ e1000_reset_hw(hw); - if (hw->mac.type >= igb_mac_min) { - E1000_WRITE_REG(hw, E1000_WUC, 0); - } else { - E1000_WRITE_REG(hw, E1000_WUFC, 0); - em_disable_aspm(sc); + if (!sc->vf_ifp) { + if (hw->mac.type >= igb_mac_min) { + E1000_WRITE_REG(hw, E1000_WUC, 0); + } else { + E1000_WRITE_REG(hw, E1000_WUFC, 0); + em_disable_aspm(sc); + } } if (sc->flags & IGB_MEDIA_RESET) { e1000_setup_init_funcs(hw, true); @@ -3813,7 +3820,7 @@ em_initialize_receive_unit(if_ctx_t ctx) sc->rx_int_delay.value); } - if (hw->mac.type >= em_mac_min) { + if (hw->mac.type >= em_mac_min && !sc->vf_ifp) { uint32_t rfctl; /* Use extended rx descriptor formats */ rfctl = E1000_READ_REG(hw, E1000_RFCTL); @@ -3833,33 +3840,38 @@ em_initialize_receive_unit(if_ctx_t ctx) E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); } - /* Set up L3 and L4 csum Rx descriptor offloads */ - rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); - if (if_getcapenable(ifp) & IFCAP_RXCSUM) { - rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL; - if (hw->mac.type > e1000_82575) - rxcsum |= E1000_RXCSUM_CRCOFL; - else if (hw->mac.type < em_mac_min && - if_getcapenable(ifp) & IFCAP_HWCSUM_IPV6) - rxcsum |= E1000_RXCSUM_IPV6OFL; - } else { - rxcsum &= ~(E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); - if (hw->mac.type > e1000_82575) - rxcsum &= ~E1000_RXCSUM_CRCOFL; - else if (hw->mac.type < em_mac_min) - rxcsum &= ~E1000_RXCSUM_IPV6OFL; - } + /* + * Set up L3 and L4 csum Rx descriptor offloads only on Physical + * Functions. Virtual Functions have no access to this register. + */ + if (!sc->vf_ifp) { + rxcsum = E1000_READ_REG(hw, E1000_RXCSUM); + if (if_getcapenable(ifp) & IFCAP_RXCSUM) { + rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL; + if (hw->mac.type > e1000_82575) + rxcsum |= E1000_RXCSUM_CRCOFL; + else if (hw->mac.type < em_mac_min && + if_getcapenable(ifp) & IFCAP_HWCSUM_IPV6) + rxcsum |= E1000_RXCSUM_IPV6OFL; + } else { + rxcsum &= ~(E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); + if (hw->mac.type > e1000_82575) + rxcsum &= ~E1000_RXCSUM_CRCOFL; + else if (hw->mac.type < em_mac_min) + rxcsum &= ~E1000_RXCSUM_IPV6OFL; + } - if (sc->rx_num_queues > 1) { - /* RSS hash needed in the Rx descriptor */ - rxcsum |= E1000_RXCSUM_PCSD; + if (sc->rx_num_queues > 1) { + /* RSS hash needed in the Rx descriptor */ + rxcsum |= E1000_RXCSUM_PCSD; - if (hw->mac.type >= igb_mac_min) - igb_initialize_rss_mapping(sc); - else - em_initialize_rss_mapping(sc); + if (hw->mac.type >= igb_mac_min) + igb_initialize_rss_mapping(sc); + else + em_initialize_rss_mapping(sc); + } + E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum); } - E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum); for (i = 0, que = sc->rx_queues; i < sc->rx_num_queues; i++, que++) { struct rx_ring *rxr = &que->rxr; @@ -4367,6 +4379,8 @@ em_get_wakeup(if_ctx_t ctx) switch (sc->hw.mac.type) { case e1000_82542: case e1000_82543: + case e1000_vfadapt: + case e1000_vfadapt_i350: break; case e1000_82544: e1000_read_nvm(&sc->hw, @@ -4412,8 +4426,6 @@ em_get_wakeup(if_ctx_t ctx) case e1000_i354: case e1000_i210: case e1000_i211: - case e1000_vfadapt: - case e1000_vfadapt_i350: apme_mask = E1000_WUC_APME; sc->has_amt = true; eeprom_data = E1000_READ_REG(&sc->hw, E1000_WUC); @@ -4469,7 +4481,6 @@ em_get_wakeup(if_ctx_t ctx) global_quad_port_a = 0; break; } - return; } diff --git a/sys/dev/iommu/busdma_iommu.c b/sys/dev/iommu/busdma_iommu.c index 668ccf056463..82f73d469585 100644 --- a/sys/dev/iommu/busdma_iommu.c +++ b/sys/dev/iommu/busdma_iommu.c @@ -295,7 +295,6 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_t dev, bool rmrr) } else { iommu_free_ctx_locked(unit, ctx); } - ctx = NULL; } return (ctx); } @@ -303,6 +302,7 @@ iommu_instantiate_ctx(struct iommu_unit *unit, device_t dev, bool rmrr) struct iommu_ctx * iommu_get_dev_ctx(device_t dev) { + struct iommu_ctx *ctx; struct iommu_unit *unit; unit = iommu_find(dev, bootverbose); @@ -313,7 +313,10 @@ iommu_get_dev_ctx(device_t dev) return (NULL); iommu_unit_pre_instantiate_ctx(unit); - return (iommu_instantiate_ctx(unit, dev, false)); + ctx = iommu_instantiate_ctx(unit, dev, false); + if (ctx != NULL && (ctx->flags & IOMMU_CTX_DISABLED) != 0) + ctx = NULL; + return (ctx); } bus_dma_tag_t diff --git a/sys/dev/le/lance.c b/sys/dev/le/lance.c index f5e41e82bb42..df53242e80f4 100644 --- a/sys/dev/le/lance.c +++ b/sys/dev/le/lance.c @@ -193,7 +193,7 @@ lance_attach(struct lance_softc *sc) if_setcapabilitiesbit(ifp, IFCAP_VLAN_MTU, 0); if_setcapenablebit(ifp, IFCAP_VLAN_MTU, 0); - gone_in(15, "Warning! le(4) to be removed: no longer needed for " + gone_in(16, "Warning! le(4) to be removed: no longer needed for " "Qemu/MIPS\n"); } diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 3a1894bf754d..f212759a5500 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -33,6 +33,7 @@ #include <sys/buf.h> #include <sys/bus.h> #include <sys/conf.h> +#include <sys/disk.h> #include <sys/ioccom.h> #include <sys/proc.h> #include <sys/smp.h> @@ -1254,6 +1255,24 @@ nvme_ctrlr_poll(struct nvme_controller *ctrlr) } /* + * Copy the NVME device's serial number to the provided buffer, which must be + * at least DISK_IDENT_SIZE bytes large. + */ +void +nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn) +{ + _Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE, + "NVME serial number too big for disk ident"); + + memmove(sn, ctrlr->cdata.sn, NVME_SERIAL_NUMBER_LENGTH); + sn[NVME_SERIAL_NUMBER_LENGTH] = '\0'; + for (int i = 0; sn[i] != '\0'; i++) { + if (sn[i] < 0x20 || sn[i] >= 0x80) + sn[i] = ' '; + } +} + +/* * Poll the single-vector interrupt case: num_io_queues will be 1 and * there's only a single vector. While we're polling, we mask further * interrupts in the controller. @@ -1495,6 +1514,11 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, case NVME_GET_CONTROLLER_DATA: memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); break; + case DIOCGIDENT: { + uint8_t *sn = arg; + nvme_ctrlr_get_ident(ctrlr, sn); + break; + } /* Linux Compatible (see nvme_linux.h) */ case NVME_IOCTL_ID: td->td_retval[0] = 0xfffffffful; diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index e84d2066930e..a759181a8c16 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -88,6 +88,11 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, gnsid->nsid = ns->id; break; } + case DIOCGIDENT: { + uint8_t *sn = arg; + nvme_ctrlr_get_ident(ctrlr, sn); + break; + } case DIOCGMEDIASIZE: *(off_t *)arg = (off_t)nvme_ns_get_size(ns); break; diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index 52e9fcbbebcd..04a47d799350 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -563,6 +563,7 @@ void nvme_notify_new_controller(struct nvme_controller *ctrlr); void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid); void nvme_ctrlr_shared_handler(void *arg); +void nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn); void nvme_ctrlr_poll(struct nvme_controller *ctrlr); int nvme_ctrlr_suspend(struct nvme_controller *ctrlr); diff --git a/sys/dev/random/fenestrasX/fx_pool.c b/sys/dev/random/fenestrasX/fx_pool.c index f4ad1e295d54..858069035572 100644 --- a/sys/dev/random/fenestrasX/fx_pool.c +++ b/sys/dev/random/fenestrasX/fx_pool.c @@ -167,9 +167,6 @@ static const struct fxrng_ent_char { [RANDOM_RANDOMDEV] = { .entc_cls = &fxrng_lo_push, }, - [RANDOM_PURE_OCTEON] = { - .entc_cls = &fxrng_hi_push, /* Could be made pull. */ - }, [RANDOM_PURE_SAFE] = { .entc_cls = &fxrng_hi_push, }, @@ -182,6 +179,9 @@ static const struct fxrng_ent_char { [RANDOM_PURE_RDRAND] = { .entc_cls = &fxrng_hi_pull, }, + [RANDOM_PURE_RDSEED] = { + .entc_cls = &fxrng_hi_pull, + }, [RANDOM_PURE_NEHEMIAH] = { .entc_cls = &fxrng_hi_pull, }, @@ -206,6 +206,15 @@ static const struct fxrng_ent_char { [RANDOM_PURE_VMGENID] = { .entc_cls = &fxrng_hi_push, }, + [RANDOM_PURE_QUALCOMM] = { + .entc_cls = &fxrng_hi_pull, + }, + [RANDOM_PURE_ARMV8] = { + .entc_cls = &fxrng_hi_pull, + }, + [RANDOM_PURE_ARM_TRNG] = { + .entc_cls = &fxrng_hi_pull, + }, }; /* Useful for single-bit-per-source state. */ diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c index fa1e4831f1b9..3eb0f261e6dc 100644 --- a/sys/dev/random/ivy.c +++ b/sys/dev/random/ivy.c @@ -1,6 +1,6 @@ /*- + * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org> * Copyright (c) 2013 The FreeBSD Foundation - * Copyright (c) 2013 David E. O'Brien <obrien@NUXI.org> * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org> * All rights reserved. * @@ -48,7 +48,6 @@ #define RETRY_COUNT 10 -static bool has_rdrand, has_rdseed; static u_int random_ivy_read(void *, u_int); static const struct random_source random_ivy = { @@ -57,13 +56,7 @@ static const struct random_source random_ivy = { .rs_read = random_ivy_read }; -SYSCTL_NODE(_kern_random, OID_AUTO, rdrand, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, - "rdrand (ivy) entropy source"); static bool acquire_independent_seed_samples = false; -SYSCTL_BOOL(_kern_random_rdrand, OID_AUTO, rdrand_independent_seed, - CTLFLAG_RWTUN, &acquire_independent_seed_samples, 0, - "If non-zero, use more expensive and slow, but safer, seeded samples " - "where RDSEED is not present."); static bool x86_rdrand_store(u_long *buf) @@ -99,45 +92,6 @@ x86_rdrand_store(u_long *buf) return (true); } -static bool -x86_rdseed_store(u_long *buf) -{ - u_long rndval; - int retry; - - retry = RETRY_COUNT; - __asm __volatile( - "1:\n\t" - "rdseed %1\n\t" /* read randomness into rndval */ - "jc 2f\n\t" /* CF is set on success, exit retry loop */ - "dec %0\n\t" /* otherwise, retry-- */ - "jne 1b\n\t" /* and loop if retries are not exhausted */ - "2:" - : "+r" (retry), "=r" (rndval) : : "cc"); - *buf = rndval; - return (retry != 0); -} - -static bool -x86_unimpl_store(u_long *buf __unused) -{ - - panic("%s called", __func__); -} - -DEFINE_IFUNC(static, bool, x86_rng_store, (u_long *buf)) -{ - has_rdrand = (cpu_feature2 & CPUID2_RDRAND); - has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); - - if (has_rdseed) - return (x86_rdseed_store); - else if (has_rdrand) - return (x86_rdrand_store); - else - return (x86_unimpl_store); -} - /* It is required that buf length is a multiple of sizeof(u_long). */ static u_int random_ivy_read(void *buf, u_int c) @@ -148,7 +102,7 @@ random_ivy_read(void *buf, u_int c) KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); b = buf; for (count = c; count > 0; count -= sizeof(*b)) { - if (!x86_rng_store(&rndval)) + if (!x86_rdrand_store(&rndval)) break; *b++ = rndval; } @@ -158,18 +112,33 @@ random_ivy_read(void *buf, u_int c) static int rdrand_modevent(module_t mod, int type, void *unused) { + struct sysctl_ctx_list ctx; + struct sysctl_oid *o; + bool has_rdrand, has_rdseed; int error = 0; + has_rdrand = (cpu_feature2 & CPUID2_RDRAND); + has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); + switch (type) { case MOD_LOAD: - if (has_rdrand || has_rdseed) { + if (has_rdrand && !has_rdseed) { + sysctl_ctx_init(&ctx); + o = SYSCTL_ADD_NODE(&ctx, SYSCTL_STATIC_CHILDREN(_kern_random), + OID_AUTO, "rdrand", CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "rdrand (ivy) entropy source"); + SYSCTL_ADD_BOOL(&ctx, SYSCTL_CHILDREN(o), OID_AUTO, + "rdrand_independent_seed", CTLFLAG_RDTUN, + &acquire_independent_seed_samples, 0, + "If non-zero, use more expensive and slow, but safer, seeded samples " + "where RDSEED is not present."); random_source_register(&random_ivy); printf("random: fast provider: \"%s\"\n", random_ivy.rs_ident); } break; case MOD_UNLOAD: - if (has_rdrand || has_rdseed) + if (has_rdrand && !has_rdseed) random_source_deregister(&random_ivy); break; diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c index 2d7af254c52c..e38fd38c310b 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -661,11 +661,11 @@ static const char *random_source_descr[ENTROPYSOURCE] = { [RANDOM_UMA] = "UMA", [RANDOM_CALLOUT] = "CALLOUT", [RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */ - [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */ - [RANDOM_PURE_SAFE] = "PURE_SAFE", + [RANDOM_PURE_SAFE] = "PURE_SAFE", /* PURE_START */ [RANDOM_PURE_GLXSB] = "PURE_GLXSB", [RANDOM_PURE_HIFN] = "PURE_HIFN", [RANDOM_PURE_RDRAND] = "PURE_RDRAND", + [RANDOM_PURE_RDSEED] = "PURE_RDSEED", [RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH", [RANDOM_PURE_RNDTEST] = "PURE_RNDTEST", [RANDOM_PURE_VIRTIO] = "PURE_VIRTIO", diff --git a/sys/dev/random/rdseed.c b/sys/dev/random/rdseed.c new file mode 100644 index 000000000000..af084aab4ed9 --- /dev/null +++ b/sys/dev/random/rdseed.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org> + * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org> + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * 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 + * in this position and unchanged. + * 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 ``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 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/kernel.h> +#include <sys/conf.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/module.h> +#include <sys/random.h> +#include <sys/sysctl.h> +#include <sys/systm.h> + +#include <machine/md_var.h> +#include <machine/specialreg.h> +#include <x86/ifunc.h> + +#include <dev/random/randomdev.h> + +#define RETRY_COUNT 10 + +static u_int random_rdseed_read(void *, u_int); + +static struct random_source random_rdseed = { + .rs_ident = "Intel Secure Key Seed", + .rs_source = RANDOM_PURE_RDSEED, + .rs_read = random_rdseed_read +}; + +SYSCTL_NODE(_kern_random, OID_AUTO, rdseed, CTLFLAG_RW, 0, + "rdseed (x86) entropy source"); +/* XXX: kern.random.rdseed.enabled=0 also disables RDRAND */ +static bool enabled = true; +SYSCTL_BOOL(_kern_random_rdseed, OID_AUTO, enabled, CTLFLAG_RDTUN, &enabled, 0, + "If zero, disable the use of RDSEED."); + +static bool +x86_rdseed_store(u_long *buf) +{ + u_long rndval; + int retry; + + retry = RETRY_COUNT; + __asm __volatile( + "1:\n\t" + "rdseed %1\n\t" /* read randomness into rndval */ + "jc 2f\n\t" /* CF is set on success, exit retry loop */ + "dec %0\n\t" /* otherwise, retry-- */ + "jne 1b\n\t" /* and loop if retries are not exhausted */ + "2:" + : "+r" (retry), "=r" (rndval) : : "cc"); + *buf = rndval; + return (retry != 0); +} + +/* It is required that buf length is a multiple of sizeof(u_long). */ +static u_int +random_rdseed_read(void *buf, u_int c) +{ + u_long *b, rndval; + u_int count; + + KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); + b = buf; + for (count = c; count > 0; count -= sizeof(*b)) { + if (!x86_rdseed_store(&rndval)) + break; + *b++ = rndval; + } + return (c - count); +} + +static int +rdseed_modevent(module_t mod, int type, void *unused) +{ + bool has_rdseed; + int error = 0; + + has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); + + switch (type) { + case MOD_LOAD: + if (has_rdseed && enabled) { + random_source_register(&random_rdseed); + printf("random: fast provider: \"%s\"\n", random_rdseed.rs_ident); + } + break; + + case MOD_UNLOAD: + if (has_rdseed) + random_source_deregister(&random_rdseed); + break; + + case MOD_SHUTDOWN: + break; + + default: + error = EOPNOTSUPP; + break; + + } + + return (error); +} + +static moduledata_t rdseed_mod = { + "rdseed", + rdseed_modevent, + 0 +}; + +DECLARE_MODULE(rdseed, rdseed_mod, SI_SUB_RANDOM, SI_ORDER_FOURTH); +MODULE_VERSION(rdseed, 1); +MODULE_DEPEND(rdseed, random_harvestq, 1, 1, 1); + +/* + * Intel's RDSEED Entropy Assessment Report min-entropy claim is 0.6 Shannons + * per bit of data output. Rrefer to the following Entropy Source Validation + * (ESV) certificates: + * + * E#87: Junos OS Physical Entropy Source - Broadwell EP 10-Core Die + * Broadwell-EP-10 FCLGA2011 Intel(R) Xeon(R) E5-2620 V4 Processor + * https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/87 + * (URLs below omitted for brevity but follow same format.) + * + * E#121: Junos OS Physical Entropy Source - Intel Atom C3000 Series + * (Denverton) 16 Core Die with FCBGA1310 Package + * + * E#122: Junos OS Physical Entropy Source - Intel Xeon D-1500 Family + * (Broadwell) 8 Core Die with FCBGA1667 Package + * + * E#123: Junos OS Physical Entropy Source - Intel Xeon D-2100 Series + * (Skylake) 18 Core Die with FCBGA2518 Package + * + * E#141: Junos OS Physical Entropy Source - Intel Xeon D-10 Series + * (Ice Lake-D-10) Die with FCBGA2227 Package + * + * E#169: Junos OS Physical Entropy Source - Intel Xeon AWS-1000 v4 and + * E5 v4 (Broadwell EP) 15 Core Die with FCLGA2011 Package + */ diff --git a/sys/dev/sound/dummy.c b/sys/dev/sound/dummy.c index 4df5b112d3f4..1f2d69708eec 100644 --- a/sys/dev/sound/dummy.c +++ b/sys/dev/sound/dummy.c @@ -346,6 +346,12 @@ dummy_attach(device_t dev) return (ENXIO); mixer_init(dev, &dummy_mixer_class, sc); + /* + * Create an alias so that tests do not need to guess which one is the + * dummy device if there are more devices present in the system. + */ + make_dev_alias(sc->info.dsp_dev, "dsp.dummy"); + return (0); } diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index fe5576baf017..27d5b740b90b 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -83,15 +83,15 @@ static d_mmap_t dsp_mmap; static d_mmap_single_t dsp_mmap_single; struct cdevsw dsp_cdevsw = { - .d_version = D_VERSION, - .d_open = dsp_open, - .d_read = dsp_read, - .d_write = dsp_write, - .d_ioctl = dsp_ioctl, - .d_poll = dsp_poll, - .d_mmap = dsp_mmap, - .d_mmap_single = dsp_mmap_single, - .d_name = "dsp", + .d_version = D_VERSION, + .d_open = dsp_open, + .d_read = dsp_read, + .d_write = dsp_write, + .d_ioctl = dsp_ioctl, + .d_poll = dsp_poll, + .d_mmap = dsp_mmap, + .d_mmap_single = dsp_mmap_single, + .d_name = "dsp", }; static eventhandler_tag dsp_ehtag = NULL; diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index 4961b21180e1..ebbceb25b69e 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -14,6 +14,7 @@ #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mman.h> +#include <sys/priv.h> #include <sys/proc.h> #include <sys/queue.h> #include <sys/sx.h> @@ -470,6 +471,12 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, if (ioctl == NULL) return (ENOTTY); + if ((ioctl->flags & VMMDEV_IOCTL_PRIV_CHECK_DRIVER) != 0) { + error = priv_check(td, PRIV_DRIVER); + if (error != 0) + return (error); + } + if ((ioctl->flags & VMMDEV_IOCTL_XLOCK_MEMSEGS) != 0) vm_xlock_memsegs(sc->vm); else if ((ioctl->flags & VMMDEV_IOCTL_SLOCK_MEMSEGS) != 0) @@ -656,10 +663,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, error = EINVAL; break; } - regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, - M_WAITOK); - regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, - M_WAITOK); + regvals = mallocarray(vmregset->count, sizeof(regvals[0]), + M_VMMDEV, M_WAITOK); + regnums = mallocarray(vmregset->count, sizeof(regnums[0]), + M_VMMDEV, M_WAITOK); error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * vmregset->count); if (error == 0) @@ -682,10 +689,10 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, error = EINVAL; break; } - regvals = malloc(sizeof(regvals[0]) * vmregset->count, M_VMMDEV, - M_WAITOK); - regnums = malloc(sizeof(regnums[0]) * vmregset->count, M_VMMDEV, - M_WAITOK); + regvals = mallocarray(vmregset->count, sizeof(regvals[0]), + M_VMMDEV, M_WAITOK); + regnums = mallocarray(vmregset->count, sizeof(regnums[0]), + M_VMMDEV, M_WAITOK); error = copyin(vmregset->regnums, regnums, sizeof(regnums[0]) * vmregset->count); if (error == 0) diff --git a/sys/dev/vmm/vmm_dev.h b/sys/dev/vmm/vmm_dev.h index 410066c49cf2..2881a7063565 100644 --- a/sys/dev/vmm/vmm_dev.h +++ b/sys/dev/vmm/vmm_dev.h @@ -44,6 +44,7 @@ struct vmmdev_ioctl { #define VMMDEV_IOCTL_LOCK_ALL_VCPUS 0x08 #define VMMDEV_IOCTL_ALLOC_VCPU 0x10 #define VMMDEV_IOCTL_MAYBE_ALLOC_VCPU 0x20 +#define VMMDEV_IOCTL_PRIV_CHECK_DRIVER 0x40 int flags; }; |
