FreeBSD Bugzilla – Attachment 210808 Details for
Bug 236922
Virtio fails as QEMU-KVM guest with Q35 chipset on Ubuntu 18.04.2 LTS
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Consolidated Differences across VirtIO / netmap
diff-12-1-patched-12-1-REL.patch (text/plain), 97.31 KB, created by
John Hartley
on 2020-01-17 07:42:20 UTC
(
hide
)
Description:
Consolidated Differences across VirtIO / netmap
Filename:
MIME Type:
Creator:
John Hartley
Created:
2020-01-17 07:42:20 UTC
Size:
97.31 KB
patch
obsolete
>diff -r /usr/src/sys/amd64/amd64/pmap.c HD12/usr/src/sys/amd64/amd64/pmap.c >1792,1836d1791 >< static int pmap_allow_2m_x_ept; >< SYSCTL_INT(_vm_pmap, OID_AUTO, allow_2m_x_ept, CTLFLAG_RWTUN | CTLFLAG_NOFETCH, >< &pmap_allow_2m_x_ept, 0, >< "Allow executable superpage mappings in EPT"); >< >< void >< pmap_allow_2m_x_ept_recalculate(void) >< { >< /* >< * SKL002, SKL012S. Since the EPT format is only used by >< * Intel CPUs, the vendor check is merely a formality. >< */ >< if (!(cpu_vendor_id != CPU_VENDOR_INTEL || >< (cpu_ia32_arch_caps & IA32_ARCH_CAP_IF_PSCHANGE_MC_NO) != 0 || >< (CPUID_TO_FAMILY(cpu_id) == 0x6 && >< (CPUID_TO_MODEL(cpu_id) == 0x26 || /* Atoms */ >< CPUID_TO_MODEL(cpu_id) == 0x27 || >< CPUID_TO_MODEL(cpu_id) == 0x35 || >< CPUID_TO_MODEL(cpu_id) == 0x36 || >< CPUID_TO_MODEL(cpu_id) == 0x37 || >< CPUID_TO_MODEL(cpu_id) == 0x86 || >< CPUID_TO_MODEL(cpu_id) == 0x1c || >< CPUID_TO_MODEL(cpu_id) == 0x4a || >< CPUID_TO_MODEL(cpu_id) == 0x4c || >< CPUID_TO_MODEL(cpu_id) == 0x4d || >< CPUID_TO_MODEL(cpu_id) == 0x5a || >< CPUID_TO_MODEL(cpu_id) == 0x5c || >< CPUID_TO_MODEL(cpu_id) == 0x5d || >< CPUID_TO_MODEL(cpu_id) == 0x5f || >< CPUID_TO_MODEL(cpu_id) == 0x6e || >< CPUID_TO_MODEL(cpu_id) == 0x7a || >< CPUID_TO_MODEL(cpu_id) == 0x57 || /* Knights */ >< CPUID_TO_MODEL(cpu_id) == 0x85)))) >< pmap_allow_2m_x_ept = 1; >< TUNABLE_INT_FETCH("hw.allow_2m_x_ept", &pmap_allow_2m_x_ept); >< } >< >< static bool >< pmap_allow_2m_x_page(pmap_t pmap, bool executable) >< { >< >< return (pmap->pm_type != PT_EPT || !executable || >< !pmap_allow_2m_x_ept); >< } >< >1881,1883d1835 >< /* IFU */ >< pmap_allow_2m_x_ept_recalculate(); >< >5453,5461d5404 >< static bool >< pmap_pde_ept_executable(pmap_t pmap, pd_entry_t pde) >< { >< >< if (pmap->pm_type != PT_EPT) >< return (false); >< return ((pde & EPT_PG_EXECUTE) != 0); >< } >< >5497,5499c5440 >< if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V) || >< !pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap, >< newpde))) { >--- >> if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) { >5929,5934d5869 >< if (!pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap, >< newpde))) { >< CTR2(KTR_PMAP, "pmap_enter_pde: 2m x blocked for va %#lx" >< " in pmap %p", va, pmap); >< return (KERN_FAILURE); >< } >6081d6015 >< pmap_allow_2m_x_page(pmap, (prot & VM_PROT_EXECUTE) != 0) && >diff -r /usr/src/sys/amd64/include/pmap.h HD12/usr/src/sys/amd64/include/pmap.h >427d426 >< void pmap_allow_2m_x_ept_recalculate(void); >diff -r /usr/src/sys/conf/files HD12/usr/src/sys/conf/files >3481,3483d3480 >< dev/virtio/pci/virtio_pci_if.m optional virtio_pci >< dev/virtio/pci/virtio_pci_legacy.c optional virtio_pci >< dev/virtio/pci/virtio_pci_modern.c optional virtio_pci >Only in /usr/src/sys/conf: files.orig >diff -r /usr/src/sys/conf/newvers.sh HD12/usr/src/sys/conf/newvers.sh >49c49 >< BRANCH="RELEASE-p1" >--- >> BRANCH="RELEASE" >diff -r /usr/src/sys/dev/cpuctl/cpuctl.c HD12/usr/src/sys/dev/cpuctl/cpuctl.c >53,56d52 >< #include <vm/vm.h> >< #include <vm/vm_param.h> >< #include <vm/pmap.h> >< >546d541 >< pmap_allow_2m_x_ept_recalculate(); >diff -r /usr/src/sys/dev/netmap/if_ptnet.c HD12/usr/src/sys/dev/netmap/if_ptnet.c >90,91d89 >< #ifdef WITH_PTNETMAP >< >2296d2293 >< #endif /* WITH_PTNETMAP */ >Only in HD12/usr/src/sys/dev/netmap: netmap_kern.h >diff -r /usr/src/sys/dev/virtio/balloon/virtio_balloon.c HD12/usr/src/sys/dev/virtio/balloon/virtio_balloon.c >32c32 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/balloon/virtio_balloon.c 326255 2017-11-27 14:52:40Z pfg $"); >83d82 >< { VIRTIO_BALLOON_F_DEFLATE_ON_OOM, "DeflateOnOOM" }, >93,94c92 >< static int vtballoon_negotiate_features(struct vtballoon_softc *); >< static int vtballoon_setup_features(struct vtballoon_softc *); >--- >> static void vtballoon_negotiate_features(struct vtballoon_softc *); >114c112 >< static void vtballoon_setup_sysctl(struct vtballoon_softc *); >--- >> static void vtballoon_add_sysctl(struct vtballoon_softc *); >116,118d113 >< #define vtballoon_modern(_sc) \ >< (((_sc)->vtballoon_features & VIRTIO_F_VERSION_1) != 0) >< >120c115 >< #define VTBALLOON_FEATURES VIRTIO_BALLOON_F_MUST_TELL_HOST >--- >> #define VTBALLOON_FEATURES 0 >161c156 >< DRIVER_MODULE(virtio_balloon, vtpcil, vtballoon_driver, >--- >> DRIVER_MODULE(virtio_balloon, virtio_pci, vtballoon_driver, >163,164d157 >< DRIVER_MODULE(virtio_balloon, vtpcim, vtballoon_driver, >< vtballoon_devclass, 0, 0); >188d180 >< virtio_set_feature_desc(dev, vtballoon_feature_desc); >193c185 >< vtballoon_setup_sysctl(sc); >--- >> vtballoon_add_sysctl(sc); >195,199c187,188 >< error = vtballoon_setup_features(sc); >< if (error) { >< device_printf(dev, "cannot setup features\n"); >< goto fail; >< } >--- >> virtio_set_feature_desc(dev, vtballoon_feature_desc); >> vtballoon_negotiate_features(sc); >285c274 >< static int >--- >> static void >292,295c281,282 >< features = VTBALLOON_FEATURES; >< >< sc->vtballoon_features = virtio_negotiate_features(dev, features); >< return (virtio_finalize_features(dev)); >--- >> features = virtio_negotiate_features(dev, VTBALLOON_FEATURES); >> sc->vtballoon_features = features; >299,310d285 >< vtballoon_setup_features(struct vtballoon_softc *sc) >< { >< int error; >< >< error = vtballoon_negotiate_features(sc); >< if (error) >< return (error); >< >< return (0); >< } >< >< static int >468,469c443 >< m = vm_page_alloc(NULL, 0, >< VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_NODUMP); >--- >> m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ); >492,495c466 >< if (vtballoon_modern(sc)) >< return (desired); >< else >< return (le32toh(desired)); >--- >> return (le32toh(desired)); >501d471 >< uint32_t npages; >503,506d472 >< npages = sc->vtballoon_current_npages; >< if (!vtballoon_modern(sc)) >< npages = htole32(npages); >< >508c474,475 >< offsetof(struct virtio_balloon_config, actual), npages); >--- >> offsetof(struct virtio_balloon_config, actual), >> htole32(sc->vtballoon_current_npages)); >580c547 >< vtballoon_setup_sysctl(struct vtballoon_softc *sc) >--- >> vtballoon_add_sysctl(struct vtballoon_softc *sc) >diff -r /usr/src/sys/dev/virtio/balloon/virtio_balloon.h HD12/usr/src/sys/dev/virtio/balloon/virtio_balloon.h >30c30 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/balloon/virtio_balloon.h 326022 2017-11-20 19:36:21Z pfg $ >39d38 >< #define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 0x4 /* Deflate balloon on OOM */ >58,60c57 >< #define VIRTIO_BALLOON_S_AVAIL 6 /* Available memory as in /proc */ >< #define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */ >< #define VIRTIO_BALLOON_S_NR 8 >--- >> #define VIRTIO_BALLOON_S_NR 6 >62,84d58 >< /* >< * Memory statistics structure. >< * Driver fills an array of these structures and passes to device. >< * >< * NOTE: fields are laid out in a way that would make compiler add padding >< * between and after fields, so we have to use compiler-specific attributes to >< * pack it, to disable this padding. This also often causes compiler to >< * generate suboptimal code. >< * >< * We maintain this statistics structure format for backwards compatibility, >< * but don't follow this example. >< * >< * If implementing a similar structure, do something like the below instead: >< * struct virtio_balloon_stat { >< * __virtio16 tag; >< * __u8 reserved[6]; >< * __virtio64 val; >< * }; >< * >< * In other words, add explicit reserved fields to align field and >< * structure boundaries at field size, avoiding compiler padding >< * without the packed attribute. >< */ >diff -r /usr/src/sys/dev/virtio/block/virtio_blk.c HD12/usr/src/sys/dev/virtio/block/virtio_blk.c >32c32 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/block/virtio_blk.c 326255 2017-11-27 14:52:40Z pfg $"); >79,82c79,83 >< #define VTBLK_FLAG_DETACH 0x0002 >< #define VTBLK_FLAG_SUSPEND 0x0004 >< #define VTBLK_FLAG_BARRIER 0x0008 >< #define VTBLK_FLAG_WCE_CONFIG 0x0010 >--- >> #define VTBLK_FLAG_READONLY 0x0002 >> #define VTBLK_FLAG_DETACH 0x0004 >> #define VTBLK_FLAG_SUSPEND 0x0008 >> #define VTBLK_FLAG_BARRIER 0x0010 >> #define VTBLK_FLAG_WC_CONFIG 0x0020 >111c112 >< { VIRTIO_BLK_F_FLUSH, "FlushCmd" }, >--- >> { VIRTIO_BLK_F_WCE, "WriteCache" }, >114d114 >< { VIRTIO_BLK_F_MQ, "Multiqueue" }, >136,137c136,137 >< static int vtblk_negotiate_features(struct vtblk_softc *); >< static int vtblk_setup_features(struct vtblk_softc *); >--- >> static void vtblk_negotiate_features(struct vtblk_softc *); >> static void vtblk_setup_features(struct vtblk_softc *); >196,203d195 >< #define vtblk_modern(_sc) (((_sc)->vtblk_features & VIRTIO_F_VERSION_1) != 0) >< #define vtblk_htog16(_sc, _val) virtio_htog16(vtblk_modern(_sc), _val) >< #define vtblk_htog32(_sc, _val) virtio_htog32(vtblk_modern(_sc), _val) >< #define vtblk_htog64(_sc, _val) virtio_htog64(vtblk_modern(_sc), _val) >< #define vtblk_gtoh16(_sc, _val) virtio_gtoh16(vtblk_modern(_sc), _val) >< #define vtblk_gtoh32(_sc, _val) virtio_gtoh32(vtblk_modern(_sc), _val) >< #define vtblk_gtoh64(_sc, _val) virtio_gtoh64(vtblk_modern(_sc), _val) >< >210,211c202,205 >< #define VTBLK_COMMON_FEATURES \ >< (VIRTIO_BLK_F_SIZE_MAX | \ >--- >> /* Features desired/implemented by this driver. */ >> #define VTBLK_FEATURES \ >> (VIRTIO_BLK_F_BARRIER | \ >> VIRTIO_BLK_F_SIZE_MAX | \ >216c210 >< VIRTIO_BLK_F_FLUSH | \ >--- >> VIRTIO_BLK_F_WCE | \ >221,223d214 >< #define VTBLK_MODERN_FEATURES (VTBLK_COMMON_FEATURES) >< #define VTBLK_LEGACY_FEATURES (VIRTIO_BLK_F_BARRIER | VTBLK_COMMON_FEATURES) >< >268c259 >< DRIVER_MODULE(virtio_blk, vtpcil, vtblk_driver, vtblk_devclass, >--- >> DRIVER_MODULE(virtio_blk, virtio_pci, vtblk_driver, vtblk_devclass, >270,271d260 >< DRIVER_MODULE(virtio_blk, vtpcim, vtblk_driver, vtblk_devclass, >< vtblk_modevent, 0); >315,316d303 >< sc = device_get_softc(dev); >< sc->vtblk_dev = dev; >318a306,307 >> sc = device_get_softc(dev); >> sc->vtblk_dev = dev; >325a315 >> vtblk_setup_features(sc); >327,332d316 >< error = vtblk_setup_features(sc); >< if (error) { >< device_printf(dev, "cannot setup features\n"); >< goto fail; >< } >< >559a544,553 >> /* >> * Fail any write if RO. Unfortunately, there does not seem to >> * be a better way to report our readonly'ness to GEOM above. >> */ >> if (sc->vtblk_flags & VTBLK_FLAG_READONLY && >> (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_FLUSH)) { >> vtblk_bio_done(sc, bp, EROFS); >> return; >> } >> >574c568 >< static int >--- >> static void >581,582c575 >< features = virtio_bus_is_modern(dev) ? VTBLK_MODERN_FEATURES : >< VTBLK_LEGACY_FEATURES; >--- >> features = VTBLK_FEATURES; >585d577 >< return (virtio_finalize_features(dev)); >588c580 >< static int >--- >> static void >592d583 >< int error; >596,598c587 >< error = vtblk_negotiate_features(sc); >< if (error) >< return (error); >--- >> vtblk_negotiate_features(sc); >602,603c591,592 >< if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE)) >< sc->vtblk_flags |= VTBLK_FLAG_WCE_CONFIG; >--- >> if (virtio_with_feature(dev, VIRTIO_BLK_F_RO)) >> sc->vtblk_flags |= VTBLK_FLAG_READONLY; >605,607c594,596 >< sc->vtblk_flags |= VTBLK_FLAG_BARRIER; /* Legacy. */ >< >< return (0); >--- >> sc->vtblk_flags |= VTBLK_FLAG_BARRIER; >> if (virtio_with_feature(dev, VIRTIO_BLK_F_CONFIG_WCE)) >> sc->vtblk_flags |= VTBLK_FLAG_WC_CONFIG; >686c675,676 >< dp->d_flags = DISKFLAG_UNMAPPED_BIO | DISKFLAG_DIRECT_COMPLETION; >--- >> dp->d_flags = DISKFLAG_CANFLUSHCACHE | DISKFLAG_UNMAPPED_BIO | >> DISKFLAG_DIRECT_COMPLETION; >692,696c682 >< if (virtio_with_feature(dev, VIRTIO_BLK_F_RO)) >< dp->d_flags |= DISKFLAG_WRITE_PROTECT; >< else { >< if (virtio_with_feature(dev, VIRTIO_BLK_F_FLUSH)) >< dp->d_flags |= DISKFLAG_CANFLUSHCACHE; >--- >> if ((sc->vtblk_flags & VTBLK_FLAG_READONLY) == 0) >698d683 >< } >882c867 >< req->vbr_hdr.ioprio = vtblk_gtoh32(sc, 1); >--- >> req->vbr_hdr.ioprio = 1; >886,887c871 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_FLUSH); >< req->vbr_hdr.sector = 0; >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_FLUSH; >890,891c874,875 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_IN); >< req->vbr_hdr.sector = vtblk_gtoh64(sc, bp->bio_offset / 512); >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_IN; >> req->vbr_hdr.sector = bp->bio_offset / 512; >894,895c878,879 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_OUT); >< req->vbr_hdr.sector = vtblk_gtoh64(sc, bp->bio_offset / 512); >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_OUT; >> req->vbr_hdr.sector = bp->bio_offset / 512; >902c886 >< req->vbr_hdr.type |= vtblk_gtoh32(sc, VIRTIO_BLK_T_BARRIER); >--- >> req->vbr_hdr.type |= VIRTIO_BLK_T_BARRIER; >933,934c917 >< req->vbr_hdr.type &= vtblk_gtoh32(sc, >< ~VIRTIO_BLK_T_BARRIER); >--- >> req->vbr_hdr.type &= ~VIRTIO_BLK_T_BARRIER; >1037a1021 >> struct bio_queue queue; >1042a1027 >> TAILQ_INIT(&queue); >1045,1047d1029 >< struct bio_queue queue; >< >< TAILQ_INIT(&queue); >1138,1143c1120 >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_GEOMETRY, >< geometry.cylinders, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_GEOMETRY, >< geometry.heads, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_GEOMETRY, >< geometry.sectors, blkcfg); >--- >> VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_GEOMETRY, geometry, blkcfg); >1145,1153c1122,1123 >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, >< topology.physical_block_exp, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, >< topology.alignment_offset, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, >< topology.min_io_size, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, >< topology.opt_io_size, blkcfg); >< VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_CONFIG_WCE, wce, blkcfg); >--- >> VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_TOPOLOGY, topology, blkcfg); >> VTBLK_GET_CONFIG(dev, VIRTIO_BLK_F_CONFIG_WCE, writeback, blkcfg); >1177,1178c1147,1148 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_GET_ID); >< req->vbr_hdr.ioprio = vtblk_gtoh32(sc, 1); >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_GET_ID; >> req->vbr_hdr.ioprio = 1; >1309,1311c1279,1281 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_OUT); >< req->vbr_hdr.ioprio = vtblk_gtoh32(sc, 1); >< req->vbr_hdr.sector = vtblk_gtoh64(sc, offset / 512); >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_OUT; >> req->vbr_hdr.ioprio = 1; >> req->vbr_hdr.sector = offset / 512; >1331,1332c1301,1302 >< req->vbr_hdr.type = vtblk_gtoh32(sc, VIRTIO_BLK_T_FLUSH); >< req->vbr_hdr.ioprio = vtblk_gtoh32(sc, 1); >--- >> req->vbr_hdr.type = VIRTIO_BLK_T_FLUSH; >> req->vbr_hdr.ioprio = 1; >1360c1330 >< offsetof(struct virtio_blk_config, wce), wc); >--- >> offsetof(struct virtio_blk_config, writeback), wc); >1369c1339 >< if (sc->vtblk_flags & VTBLK_FLAG_WCE_CONFIG) { >--- >> if (sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) { >1375c1345 >< wc = blkcfg->wce; >--- >> wc = blkcfg->writeback; >1377c1347 >< wc = virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_FLUSH); >--- >> wc = virtio_with_feature(sc->vtblk_dev, VIRTIO_BLK_F_WCE); >1394c1364 >< if ((sc->vtblk_flags & VTBLK_FLAG_WCE_CONFIG) == 0) >--- >> if ((sc->vtblk_flags & VTBLK_FLAG_WC_CONFIG) == 0) >diff -r /usr/src/sys/dev/virtio/block/virtio_blk.h HD12/usr/src/sys/dev/virtio/block/virtio_blk.h >30c30 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/block/virtio_blk.h 326022 2017-11-20 19:36:21Z pfg $ >36a37 >> #define VIRTIO_BLK_F_BARRIER 0x0001 /* Does host support barriers? */ >42c43,44 >< #define VIRTIO_BLK_F_FLUSH 0x0200 /* Flush command supported */ >--- >> #define VIRTIO_BLK_F_SCSI 0x0080 /* Supports scsi command passthru */ >> #define VIRTIO_BLK_F_WCE 0x0200 /* Writeback mode enabled after reset */ >45d46 >< #define VIRTIO_BLK_F_MQ 0x1000 /* Support more than one vq */ >47,53d47 >< /* Legacy feature bits */ >< #define VIRTIO_BLK_F_BARRIER 0x0001 /* Does host support barriers? */ >< #define VIRTIO_BLK_F_SCSI 0x0080 /* Supports scsi command passthru */ >< >< /* Old (deprecated) name for VIRTIO_BLK_F_FLUSH. */ >< #define VIRTIO_BLK_F_WCE VIRTIO_BLK_F_FLUSH >< >75d68 >< /* exponent for physical block per logical block. */ >77d69 >< /* alignment offset in logical blocks. */ >79,80d70 >< /* minimum I/O size without performance penalty in logical >< * blocks. */ >82d71 >< /* optimal sustained I/O size in logical blocks. */ >87,88c76 >< uint8_t wce; >< uint8_t unused; >--- >> uint8_t writeback; >90,91d77 >< /* Number of vqs, only available when VIRTIO_BLK_F_MQ is set */ >< uint16_t num_queues; >124,128c110 >< /* >< * This comes first in the read scatter-gather list. >< * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, >< * this is the first element of the read scatter-gather list. >< */ >--- >> /* This is the first element of the read scatter-gather list. */ >diff -r /usr/src/sys/dev/virtio/console/virtio_console.c HD12/usr/src/sys/dev/virtio/console/virtio_console.c >30c30 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/console/virtio_console.c 328218 2018-01-21 15:42:36Z pfg $"); >161,162c161,162 >< static int vtcon_setup_features(struct vtcon_softc *); >< static int vtcon_negotiate_features(struct vtcon_softc *); >--- >> static void vtcon_setup_features(struct vtcon_softc *); >> static void vtcon_negotiate_features(struct vtcon_softc *); >230,237d229 >< #define vtcon_modern(_sc) (((_sc)->vtcon_features & VIRTIO_F_VERSION_1) != 0) >< #define vtcon_htog16(_sc, _val) virtio_htog16(vtcon_modern(_sc), _val) >< #define vtcon_htog32(_sc, _val) virtio_htog32(vtcon_modern(_sc), _val) >< #define vtcon_htog64(_sc, _val) virtio_htog64(vtcon_modern(_sc), _val) >< #define vtcon_gtoh16(_sc, _val) virtio_gtoh16(vtcon_modern(_sc), _val) >< #define vtcon_gtoh32(_sc, _val) virtio_gtoh32(vtcon_modern(_sc), _val) >< #define vtcon_gtoh64(_sc, _val) virtio_gtoh64(vtcon_modern(_sc), _val) >< >267c259 >< DRIVER_MODULE(virtio_console, vtpcil, vtcon_driver, vtcon_devclass, >--- >> DRIVER_MODULE(virtio_console, virtio_pci, vtcon_driver, vtcon_devclass, >269,270d260 >< DRIVER_MODULE(virtio_console, vtpcim, vtcon_driver, vtcon_devclass, >< vtcon_modevent, 0); >336d325 >< virtio_set_feature_desc(dev, vtcon_feature_desc); >341,345c330,331 >< error = vtcon_setup_features(sc); >< if (error) { >< device_printf(dev, "cannot setup features\n"); >< goto fail; >< } >--- >> virtio_set_feature_desc(dev, vtcon_feature_desc); >> vtcon_setup_features(sc); >437c423 >< static int >--- >> static void >447d432 >< return (virtio_finalize_features(dev)); >450c435 >< static int >--- >> static void >454d438 >< int error; >458,460c442 >< error = vtcon_negotiate_features(sc); >< if (error) >< return (error); >--- >> vtcon_negotiate_features(sc); >466,467d447 >< >< return (0); >870,871c850 >< uint32_t id; >< uint16_t event; >--- >> int id; >874,875c853 >< id = vtcon_htog32(sc, control->id); >< event = vtcon_htog16(sc, control->event); >--- >> id = control->id; >877,879c855,856 >< if (id >= sc->vtcon_max_ports) { >< device_printf(dev, "%s: event %d invalid port ID %d\n", >< __func__, event, id); >--- >> if (id < 0 || id >= sc->vtcon_max_ports) { >> device_printf(dev, "%s: invalid port ID %d\n", __func__, id); >883c860 >< switch (event) { >--- >> switch (control->event) { >1011,1013c988,990 >< control.id = vtcon_gtoh32(sc, portid); >< control.event = vtcon_gtoh16(sc, event); >< control.value = vtcon_gtoh16(sc, value); >--- >> control.id = portid; >> control.event = event; >> control.value = value; >diff -r /usr/src/sys/dev/virtio/console/virtio_console.h HD12/usr/src/sys/dev/virtio/console/virtio_console.h >31c31 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/console/virtio_console.h 273515 2014-10-23 04:47:32Z bryanv $ >diff -r /usr/src/sys/dev/virtio/mmio/virtio_mmio.c HD12/usr/src/sys/dev/virtio/mmio/virtio_mmio.c >51c51 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/mmio/virtio_mmio.c 335211 2018-06-15 16:19:10Z br $"); >428,431d427 >< break; >< case VIRTIO_IVAR_SUBVENDOR: >< case VIRTIO_IVAR_MODERN: >< *result = 0; >diff -r /usr/src/sys/dev/virtio/mmio/virtio_mmio.h HD12/usr/src/sys/dev/virtio/mmio/virtio_mmio.h >30c30 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/mmio/virtio_mmio.h 284544 2015-06-18 10:33:04Z br $ >diff -r /usr/src/sys/dev/virtio/mmio/virtio_mmio_if.m HD12/usr/src/sys/dev/virtio/mmio/virtio_mmio_if.m >30c30 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/dev/virtio/mmio/virtio_mmio_if.m 285091 2015-07-03 14:13:16Z br $ >diff -r /usr/src/sys/dev/virtio/pci/virtio_pci.c HD12/usr/src/sys/dev/virtio/pci/virtio_pci.c >4c4 >< * Copyright (c) 2017, Bryan Venteicher <bryanv@FreeBSD.org> >--- >> * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org> >28a29,30 >> /* Driver for the VirtIO PCI interface. */ >> >30c32 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/pci/virtio_pci.c 328218 2018-01-21 15:42:36Z pfg $"); >36,37d37 >< #include <sys/sbuf.h> >< #include <sys/sysctl.h> >52d51 >< #include <dev/virtio/pci/virtio_pci_var.h> >54c53 >< #include "virtio_pci_if.h" >--- >> #include "virtio_bus_if.h" >57c56,128 >< static void vtpci_describe_features(struct vtpci_common *, const char *, >--- >> struct vtpci_interrupt { >> struct resource *vti_irq; >> int vti_rid; >> void *vti_handler; >> }; >> >> struct vtpci_virtqueue { >> struct virtqueue *vtv_vq; >> int vtv_no_intr; >> }; >> >> struct vtpci_softc { >> device_t vtpci_dev; >> struct resource *vtpci_res; >> struct resource *vtpci_msix_res; >> uint64_t vtpci_features; >> uint32_t vtpci_flags; >> #define VTPCI_FLAG_NO_MSI 0x0001 >> #define VTPCI_FLAG_NO_MSIX 0x0002 >> #define VTPCI_FLAG_LEGACY 0x1000 >> #define VTPCI_FLAG_MSI 0x2000 >> #define VTPCI_FLAG_MSIX 0x4000 >> #define VTPCI_FLAG_SHARED_MSIX 0x8000 >> #define VTPCI_FLAG_ITYPE_MASK 0xF000 >> >> /* This "bus" will only ever have one child. */ >> device_t vtpci_child_dev; >> struct virtio_feature_desc *vtpci_child_feat_desc; >> >> int vtpci_nvqs; >> struct vtpci_virtqueue *vtpci_vqs; >> >> /* >> * Ideally, each virtqueue that the driver provides a callback for will >> * receive its own MSIX vector. If there are not sufficient vectors >> * available, then attempt to have all the VQs share one vector. For >> * MSIX, the configuration changed notifications must be on their own >> * vector. >> * >> * If MSIX is not available, we will attempt to have the whole device >> * share one MSI vector, and then, finally, one legacy interrupt. >> */ >> struct vtpci_interrupt vtpci_device_interrupt; >> struct vtpci_interrupt *vtpci_msix_vq_interrupts; >> int vtpci_nmsix_resources; >> }; >> >> static int vtpci_probe(device_t); >> static int vtpci_attach(device_t); >> static int vtpci_detach(device_t); >> static int vtpci_suspend(device_t); >> static int vtpci_resume(device_t); >> static int vtpci_shutdown(device_t); >> static void vtpci_driver_added(device_t, driver_t *); >> static void vtpci_child_detached(device_t, device_t); >> static int vtpci_read_ivar(device_t, device_t, int, uintptr_t *); >> static int vtpci_write_ivar(device_t, device_t, int, uintptr_t); >> >> static uint64_t vtpci_negotiate_features(device_t, uint64_t); >> static int vtpci_with_feature(device_t, uint64_t); >> static int vtpci_alloc_virtqueues(device_t, int, int, >> struct vq_alloc_info *); >> static int vtpci_setup_intr(device_t, enum intr_type); >> static void vtpci_stop(device_t); >> static int vtpci_reinit(device_t, uint64_t); >> static void vtpci_reinit_complete(device_t); >> static void vtpci_notify_virtqueue(device_t, uint16_t); >> static uint8_t vtpci_get_status(device_t); >> static void vtpci_set_status(device_t, uint8_t); >> static void vtpci_read_dev_config(device_t, bus_size_t, void *, int); >> static void vtpci_write_dev_config(device_t, bus_size_t, void *, int); >> >> static void vtpci_describe_features(struct vtpci_softc *, const char *, >59,65c130,138 >< static int vtpci_alloc_msix(struct vtpci_common *, int); >< static int vtpci_alloc_msi(struct vtpci_common *); >< static int vtpci_alloc_intr_msix_pervq(struct vtpci_common *); >< static int vtpci_alloc_intr_msix_shared(struct vtpci_common *); >< static int vtpci_alloc_intr_msi(struct vtpci_common *); >< static int vtpci_alloc_intr_intx(struct vtpci_common *); >< static int vtpci_alloc_interrupt(struct vtpci_common *, int, int, >--- >> static void vtpci_probe_and_attach_child(struct vtpci_softc *); >> >> static int vtpci_alloc_msix(struct vtpci_softc *, int); >> static int vtpci_alloc_msi(struct vtpci_softc *); >> static int vtpci_alloc_intr_msix_pervq(struct vtpci_softc *); >> static int vtpci_alloc_intr_msix_shared(struct vtpci_softc *); >> static int vtpci_alloc_intr_msi(struct vtpci_softc *); >> static int vtpci_alloc_intr_legacy(struct vtpci_softc *); >> static int vtpci_alloc_interrupt(struct vtpci_softc *, int, int, >67,68c140 >< static void vtpci_free_interrupt(struct vtpci_common *, >< struct vtpci_interrupt *); >--- >> static int vtpci_alloc_intr_resources(struct vtpci_softc *); >70,74c142 >< static void vtpci_free_interrupts(struct vtpci_common *); >< static void vtpci_free_virtqueues(struct vtpci_common *); >< static void vtpci_cleanup_setup_intr_attempt(struct vtpci_common *); >< static int vtpci_alloc_intr_resources(struct vtpci_common *); >< static int vtpci_setup_intx_interrupt(struct vtpci_common *, >--- >> static int vtpci_setup_legacy_interrupt(struct vtpci_softc *, >76c144 >< static int vtpci_setup_pervq_msix_interrupts(struct vtpci_common *, >--- >> static int vtpci_setup_pervq_msix_interrupts(struct vtpci_softc *, >78,79c146 >< static int vtpci_set_host_msix_vectors(struct vtpci_common *); >< static int vtpci_setup_msix_interrupts(struct vtpci_common *, >--- >> static int vtpci_setup_msix_interrupts(struct vtpci_softc *, >81,83c148,165 >< static int vtpci_setup_intrs(struct vtpci_common *, enum intr_type); >< static int vtpci_reinit_virtqueue(struct vtpci_common *, int); >< static void vtpci_intx_intr(void *); >--- >> static int vtpci_setup_interrupts(struct vtpci_softc *, enum intr_type); >> >> static int vtpci_register_msix_vector(struct vtpci_softc *, int, >> struct vtpci_interrupt *); >> static int vtpci_set_host_msix_vectors(struct vtpci_softc *); >> static int vtpci_reinit_virtqueue(struct vtpci_softc *, int); >> >> static void vtpci_free_interrupt(struct vtpci_softc *, >> struct vtpci_interrupt *); >> static void vtpci_free_interrupts(struct vtpci_softc *); >> static void vtpci_free_virtqueues(struct vtpci_softc *); >> static void vtpci_release_child_resources(struct vtpci_softc *); >> static void vtpci_cleanup_setup_intr_attempt(struct vtpci_softc *); >> static void vtpci_reset(struct vtpci_softc *); >> >> static void vtpci_select_virtqueue(struct vtpci_softc *, int); >> >> static void vtpci_legacy_intr(void *); >90c172 >< static void vtpci_setup_sysctl(struct vtpci_common *); >--- >> #define vtpci_setup_msi_interrupt vtpci_setup_legacy_interrupt >92c174,175 >< #define vtpci_setup_msi_interrupt vtpci_setup_intx_interrupt >--- >> #define VIRTIO_PCI_CONFIG(_sc) \ >> VIRTIO_PCI_CONFIG_OFF((((_sc)->vtpci_flags & VTPCI_FLAG_MSIX)) != 0) >95,97c178 >< * This module contains two drivers: >< * - virtio_pci_legacy (vtpcil) for pre-V1 support >< * - virtio_pci_modern (vtpcim) for V1 support >--- >> * I/O port read/write wrappers. >99,101c180,185 >< MODULE_VERSION(virtio_pci, 1); >< MODULE_DEPEND(virtio_pci, pci, 1, 1, 1); >< MODULE_DEPEND(virtio_pci, virtio, 1, 1, 1); >--- >> #define vtpci_read_config_1(sc, o) bus_read_1((sc)->vtpci_res, (o)) >> #define vtpci_read_config_2(sc, o) bus_read_2((sc)->vtpci_res, (o)) >> #define vtpci_read_config_4(sc, o) bus_read_4((sc)->vtpci_res, (o)) >> #define vtpci_write_config_1(sc, o, v) bus_write_1((sc)->vtpci_res, (o), (v)) >> #define vtpci_write_config_2(sc, o, v) bus_write_2((sc)->vtpci_res, (o), (v)) >> #define vtpci_write_config_4(sc, o, v) bus_write_4((sc)->vtpci_res, (o), (v)) >103c187,188 >< int vtpci_disable_msix = 0; >--- >> /* Tunables. */ >> static int vtpci_disable_msix = 0; >106,110c191,198 >< static uint8_t >< vtpci_read_isr(struct vtpci_common *cn) >< { >< return (VIRTIO_PCI_READ_ISR(cn->vtpci_dev)); >< } >--- >> static device_method_t vtpci_methods[] = { >> /* Device interface. */ >> DEVMETHOD(device_probe, vtpci_probe), >> DEVMETHOD(device_attach, vtpci_attach), >> DEVMETHOD(device_detach, vtpci_detach), >> DEVMETHOD(device_suspend, vtpci_suspend), >> DEVMETHOD(device_resume, vtpci_resume), >> DEVMETHOD(device_shutdown, vtpci_shutdown), >112,116c200,204 >< static uint16_t >< vtpci_get_vq_size(struct vtpci_common *cn, int idx) >< { >< return (VIRTIO_PCI_GET_VQ_SIZE(cn->vtpci_dev, idx)); >< } >--- >> /* Bus interface. */ >> DEVMETHOD(bus_driver_added, vtpci_driver_added), >> DEVMETHOD(bus_child_detached, vtpci_child_detached), >> DEVMETHOD(bus_read_ivar, vtpci_read_ivar), >> DEVMETHOD(bus_write_ivar, vtpci_write_ivar), >118,122c206,216 >< static bus_size_t >< vtpci_get_vq_notify_off(struct vtpci_common *cn, int idx) >< { >< return (VIRTIO_PCI_GET_VQ_NOTIFY_OFF(cn->vtpci_dev, idx)); >< } >--- >> /* VirtIO bus interface. */ >> DEVMETHOD(virtio_bus_negotiate_features, vtpci_negotiate_features), >> DEVMETHOD(virtio_bus_with_feature, vtpci_with_feature), >> DEVMETHOD(virtio_bus_alloc_virtqueues, vtpci_alloc_virtqueues), >> DEVMETHOD(virtio_bus_setup_intr, vtpci_setup_intr), >> DEVMETHOD(virtio_bus_stop, vtpci_stop), >> DEVMETHOD(virtio_bus_reinit, vtpci_reinit), >> DEVMETHOD(virtio_bus_reinit_complete, vtpci_reinit_complete), >> DEVMETHOD(virtio_bus_notify_vq, vtpci_notify_virtqueue), >> DEVMETHOD(virtio_bus_read_device_config, vtpci_read_dev_config), >> DEVMETHOD(virtio_bus_write_device_config, vtpci_write_dev_config), >124,128c218,219 >< static void >< vtpci_set_vq(struct vtpci_common *cn, struct virtqueue *vq) >< { >< VIRTIO_PCI_SET_VQ(cn->vtpci_dev, vq); >< } >--- >> DEVMETHOD_END >> }; >130,134c221,225 >< static void >< vtpci_disable_vq(struct vtpci_common *cn, int idx) >< { >< VIRTIO_PCI_DISABLE_VQ(cn->vtpci_dev, idx); >< } >--- >> static driver_t vtpci_driver = { >> "virtio_pci", >> vtpci_methods, >> sizeof(struct vtpci_softc) >> }; >135a227,233 >> devclass_t vtpci_devclass; >> >> DRIVER_MODULE(virtio_pci, pci, vtpci_driver, vtpci_devclass, 0, 0); >> MODULE_VERSION(virtio_pci, 1); >> MODULE_DEPEND(virtio_pci, pci, 1, 1, 1); >> MODULE_DEPEND(virtio_pci, virtio, 1, 1, 1); >> >137c235 >< vtpci_register_cfg_msix(struct vtpci_common *cn, struct vtpci_interrupt *intr) >--- >> vtpci_probe(device_t dev) >139c237,257 >< return (VIRTIO_PCI_REGISTER_CFG_MSIX(cn->vtpci_dev, intr)); >--- >> char desc[36]; >> const char *name; >> >> if (pci_get_vendor(dev) != VIRTIO_PCI_VENDORID) >> return (ENXIO); >> >> if (pci_get_device(dev) < VIRTIO_PCI_DEVICEID_MIN || >> pci_get_device(dev) > VIRTIO_PCI_DEVICEID_MAX) >> return (ENXIO); >> >> if (pci_get_revid(dev) != VIRTIO_PCI_ABI_VERSION) >> return (ENXIO); >> >> name = virtio_device_name(pci_get_subdevice(dev)); >> if (name == NULL) >> name = "Unknown"; >> >> snprintf(desc, sizeof(desc), "VirtIO PCI %s adapter", name); >> device_set_desc_copy(dev, desc); >> >> return (BUS_PROBE_DEFAULT); >143,144c261 >< vtpci_register_vq_msix(struct vtpci_common *cn, int idx, >< struct vtpci_interrupt *intr) >--- >> vtpci_attach(device_t dev) >146,147c263,265 >< return (VIRTIO_PCI_REGISTER_VQ_MSIX(cn->vtpci_dev, idx, intr)); >< } >--- >> struct vtpci_softc *sc; >> device_t child; >> int rid; >149,151c267,268 >< void >< vtpci_init(struct vtpci_common *cn, device_t dev, bool modern) >< { >--- >> sc = device_get_softc(dev); >> sc->vtpci_dev = dev; >153,154d269 >< cn->vtpci_dev = dev; >< >157,158c272,279 >< if (modern) >< cn->vtpci_flags |= VTPCI_FLAG_MODERN; >--- >> rid = PCIR_BAR(0); >> sc->vtpci_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, >> RF_ACTIVE); >> if (sc->vtpci_res == NULL) { >> device_printf(dev, "cannot map I/O space\n"); >> return (ENXIO); >> } >> >160,162c281 >< cn->vtpci_flags |= VTPCI_FLAG_NO_MSI; >< if (pci_find_cap(dev, PCIY_MSIX, NULL) != 0) >< cn->vtpci_flags |= VTPCI_FLAG_NO_MSIX; >--- >> sc->vtpci_flags |= VTPCI_FLAG_NO_MSI; >164,165c283,287 >< vtpci_setup_sysctl(cn); >< } >--- >> if (pci_find_cap(dev, PCIY_MSIX, NULL) == 0) { >> rid = PCIR_BAR(1); >> sc->vtpci_msix_res = bus_alloc_resource_any(dev, >> SYS_RES_MEMORY, &rid, RF_ACTIVE); >> } >167,170c289,290 >< int >< vtpci_add_child(struct vtpci_common *cn) >< { >< device_t dev, child; >--- >> if (sc->vtpci_msix_res == NULL) >> sc->vtpci_flags |= VTPCI_FLAG_NO_MSIX; >172c292 >< dev = cn->vtpci_dev; >--- >> vtpci_reset(sc); >174,175c294,297 >< child = device_add_child(dev, NULL, -1); >< if (child == NULL) { >--- >> /* Tell the host we've noticed this device. */ >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); >> >> if ((child = device_add_child(dev, NULL, -1)) == NULL) { >176a299,300 >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); >> vtpci_detach(dev); >180c304,305 >< cn->vtpci_child_dev = child; >--- >> sc->vtpci_child_dev = child; >> vtpci_probe_and_attach_child(sc); >185,186c310,311 >< int >< vtpci_delete_child(struct vtpci_common *cn) >--- >> static int >> vtpci_detach(device_t dev) >188c313,314 >< device_t dev, child; >--- >> struct vtpci_softc *sc; >> device_t child; >191c317 >< dev = cn->vtpci_dev; >--- >> sc = device_get_softc(dev); >193,194c319 >< child = cn->vtpci_child_dev; >< if (child != NULL) { >--- >> if ((child = sc->vtpci_child_dev) != NULL) { >198c323 >< cn->vtpci_child_dev = NULL; >--- >> sc->vtpci_child_dev = NULL; >200a326,339 >> vtpci_reset(sc); >> >> if (sc->vtpci_msix_res != NULL) { >> bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(1), >> sc->vtpci_msix_res); >> sc->vtpci_msix_res = NULL; >> } >> >> if (sc->vtpci_res != NULL) { >> bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), >> sc->vtpci_res); >> sc->vtpci_res = NULL; >> } >> >204,205c343,344 >< void >< vtpci_child_detached(struct vtpci_common *cn) >--- >> static int >> vtpci_suspend(device_t dev) >208,212c347 >< vtpci_release_child_resources(cn); >< >< cn->vtpci_child_feat_desc = NULL; >< cn->vtpci_host_features = 0; >< cn->vtpci_features = 0; >--- >> return (bus_generic_suspend(dev)); >215,216c350,351 >< int >< vtpci_reinit(struct vtpci_common *cn) >--- >> static int >> vtpci_resume(device_t dev) >218d352 >< int idx, error; >220,224c354,355 >< for (idx = 0; idx < cn->vtpci_nvqs; idx++) { >< error = vtpci_reinit_virtqueue(cn, idx); >< if (error) >< return (error); >< } >--- >> return (bus_generic_resume(dev)); >> } >226,230c357,359 >< if (vtpci_is_msix_enabled(cn)) { >< error = vtpci_set_host_msix_vectors(cn); >< if (error) >< return (error); >< } >--- >> static int >> vtpci_shutdown(device_t dev) >> { >231a361,364 >> (void) bus_generic_shutdown(dev); >> /* Forcibly stop the host device. */ >> vtpci_stop(dev); >> >236,237c369 >< vtpci_describe_features(struct vtpci_common *cn, const char *msg, >< uint64_t features) >--- >> vtpci_driver_added(device_t dev, driver_t *driver) >239c371 >< device_t dev, child; >--- >> struct vtpci_softc *sc; >241,242c373 >< dev = cn->vtpci_dev; >< child = cn->vtpci_child_dev; >--- >> sc = device_get_softc(dev); >244,247c375 >< if (device_is_attached(child) || bootverbose == 0) >< return; >< >< virtio_describe(dev, msg, features, cn->vtpci_child_feat_desc); >--- >> vtpci_probe_and_attach_child(sc); >250,252c378,379 >< uint64_t >< vtpci_negotiate_features(struct vtpci_common *cn, >< uint64_t child_features, uint64_t host_features) >--- >> static void >> vtpci_child_detached(device_t dev, device_t child) >254c381 >< uint64_t features; >--- >> struct vtpci_softc *sc; >256,257c383 >< cn->vtpci_host_features = host_features; >< vtpci_describe_features(cn, "host", host_features); >--- >> sc = device_get_softc(dev); >259,269c385,386 >< /* >< * Limit negotiated features to what the driver, virtqueue, and >< * host all support. >< */ >< features = host_features & child_features; >< features = virtio_filter_transport_features(features); >< >< cn->vtpci_features = features; >< vtpci_describe_features(cn, "negotiated", features); >< >< return (features); >--- >> vtpci_reset(sc); >> vtpci_release_child_resources(sc); >272,273c389,390 >< int >< vtpci_with_feature(struct vtpci_common *cn, uint64_t feature) >--- >> static int >> vtpci_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) >275,276c392 >< return ((cn->vtpci_features & feature) != 0); >< } >--- >> struct vtpci_softc *sc; >278,282c394 >< int >< vtpci_read_ivar(struct vtpci_common *cn, int index, uintptr_t *result) >< { >< device_t dev; >< int error; >--- >> sc = device_get_softc(dev); >284,285c396,397 >< dev = cn->vtpci_dev; >< error = 0; >--- >> if (sc->vtpci_child_dev != child) >> return (ENOENT); >287a400 >> case VIRTIO_IVAR_DEVTYPE: >300,302d412 >< case VIRTIO_IVAR_MODERN: >< *result = vtpci_is_modern(cn); >< break; >304c414 >< error = ENOENT; >--- >> return (ENOENT); >307c417 >< return (error); >--- >> return (0); >310,311c420,421 >< int >< vtpci_write_ivar(struct vtpci_common *cn, int index, uintptr_t value) >--- >> static int >> vtpci_write_ivar(device_t dev, device_t child, int index, uintptr_t value) >313c423 >< int error; >--- >> struct vtpci_softc *sc; >315c425 >< error = 0; >--- >> sc = device_get_softc(dev); >316a427,429 >> if (sc->vtpci_child_dev != child) >> return (ENOENT); >> >319c432 >< cn->vtpci_child_feat_desc = (void *) value; >--- >> sc->vtpci_child_feat_desc = (void *) value; >322c435 >< error = ENOENT; >--- >> return (ENOENT); >325c438 >< return (error); >--- >> return (0); >328,330c441,442 >< int >< vtpci_alloc_virtqueues(struct vtpci_common *cn, int flags, int nvqs, >< struct vq_alloc_info *vq_info) >--- >> static uint64_t >> vtpci_negotiate_features(device_t dev, uint64_t child_features) >332,333c444,445 >< device_t dev; >< int idx, align, error; >--- >> struct vtpci_softc *sc; >> uint64_t host_features, features; >335c447 >< dev = cn->vtpci_dev; >--- >> sc = device_get_softc(dev); >336a449,451 >> host_features = vtpci_read_config_4(sc, VIRTIO_PCI_HOST_FEATURES); >> vtpci_describe_features(sc, "host", host_features); >> >338,340c453,454 >< * This is VIRTIO_PCI_VRING_ALIGN from legacy VirtIO. In modern VirtIO, >< * the tables do not have to be allocated contiguously, but we do so >< * anyways. >--- >> * Limit negotiated features to what the driver, virtqueue, and >> * host all support. >342c456,458 >< align = 4096; >--- >> features = host_features & child_features; >> features = virtqueue_filter_features(features); >> sc->vtpci_features = features; >344c460,489 >< if (cn->vtpci_nvqs != 0) >--- >> vtpci_describe_features(sc, "negotiated", features); >> vtpci_write_config_4(sc, VIRTIO_PCI_GUEST_FEATURES, features); >> >> return (features); >> } >> >> static int >> vtpci_with_feature(device_t dev, uint64_t feature) >> { >> struct vtpci_softc *sc; >> >> sc = device_get_softc(dev); >> >> return ((sc->vtpci_features & feature) != 0); >> } >> >> static int >> vtpci_alloc_virtqueues(device_t dev, int flags, int nvqs, >> struct vq_alloc_info *vq_info) >> { >> struct vtpci_softc *sc; >> struct virtqueue *vq; >> struct vtpci_virtqueue *vqx; >> struct vq_alloc_info *info; >> int idx, error; >> uint16_t size; >> >> sc = device_get_softc(dev); >> >> if (sc->vtpci_nvqs != 0) >349c494 >< cn->vtpci_vqs = malloc(nvqs * sizeof(struct vtpci_virtqueue), >--- >> sc->vtpci_vqs = malloc(nvqs * sizeof(struct vtpci_virtqueue), >351c496 >< if (cn->vtpci_vqs == NULL) >--- >> if (sc->vtpci_vqs == NULL) >355,361c500 >< struct vtpci_virtqueue *vqx; >< struct vq_alloc_info *info; >< struct virtqueue *vq; >< bus_size_t notify_offset; >< uint16_t size; >< >< vqx = &cn->vtpci_vqs[idx]; >--- >> vqx = &sc->vtpci_vqs[idx]; >364,365c503,504 >< size = vtpci_get_vq_size(cn, idx); >< notify_offset = vtpci_get_vq_notify_off(cn, idx); >--- >> vtpci_select_virtqueue(sc, idx); >> size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM); >367c506 >< error = virtqueue_alloc(dev, idx, size, notify_offset, align, >--- >> error = virtqueue_alloc(dev, idx, size, VIRTIO_PCI_VRING_ALIGN, >375c514,515 >< vtpci_set_vq(cn, vq); >--- >> vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN, >> virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT); >380c520 >< cn->vtpci_nvqs++; >--- >> sc->vtpci_nvqs++; >384c524 >< vtpci_free_virtqueues(cn); >--- >> vtpci_free_virtqueues(sc); >390c530 >< vtpci_alloc_msix(struct vtpci_common *cn, int nvectors) >--- >> vtpci_setup_intr(device_t dev, enum intr_type type) >391a532,773 >> struct vtpci_softc *sc; >> int attempt, error; >> >> sc = device_get_softc(dev); >> >> for (attempt = 0; attempt < 5; attempt++) { >> /* >> * Start with the most desirable interrupt configuration and >> * fallback towards less desirable ones. >> */ >> switch (attempt) { >> case 0: >> error = vtpci_alloc_intr_msix_pervq(sc); >> break; >> case 1: >> error = vtpci_alloc_intr_msix_shared(sc); >> break; >> case 2: >> error = vtpci_alloc_intr_msi(sc); >> break; >> case 3: >> error = vtpci_alloc_intr_legacy(sc); >> break; >> default: >> device_printf(dev, >> "exhausted all interrupt allocation attempts\n"); >> return (ENXIO); >> } >> >> if (error == 0 && vtpci_setup_interrupts(sc, type) == 0) >> break; >> >> vtpci_cleanup_setup_intr_attempt(sc); >> } >> >> if (bootverbose) { >> if (sc->vtpci_flags & VTPCI_FLAG_LEGACY) >> device_printf(dev, "using legacy interrupt\n"); >> else if (sc->vtpci_flags & VTPCI_FLAG_MSI) >> device_printf(dev, "using MSI interrupt\n"); >> else if (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) >> device_printf(dev, "using shared MSIX interrupts\n"); >> else >> device_printf(dev, "using per VQ MSIX interrupts\n"); >> } >> >> return (0); >> } >> >> static void >> vtpci_stop(device_t dev) >> { >> >> vtpci_reset(device_get_softc(dev)); >> } >> >> static int >> vtpci_reinit(device_t dev, uint64_t features) >> { >> struct vtpci_softc *sc; >> int idx, error; >> >> sc = device_get_softc(dev); >> >> /* >> * Redrive the device initialization. This is a bit of an abuse of >> * the specification, but VirtualBox, QEMU/KVM, and BHyVe seem to >> * play nice. >> * >> * We do not allow the host device to change from what was originally >> * negotiated beyond what the guest driver changed. MSIX state should >> * not change, number of virtqueues and their size remain the same, etc. >> * This will need to be rethought when we want to support migration. >> */ >> >> if (vtpci_get_status(dev) != VIRTIO_CONFIG_STATUS_RESET) >> vtpci_stop(dev); >> >> /* >> * Quickly drive the status through ACK and DRIVER. The device >> * does not become usable again until vtpci_reinit_complete(). >> */ >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); >> >> vtpci_negotiate_features(dev, features); >> >> for (idx = 0; idx < sc->vtpci_nvqs; idx++) { >> error = vtpci_reinit_virtqueue(sc, idx); >> if (error) >> return (error); >> } >> >> if (sc->vtpci_flags & VTPCI_FLAG_MSIX) { >> error = vtpci_set_host_msix_vectors(sc); >> if (error) >> return (error); >> } >> >> return (0); >> } >> >> static void >> vtpci_reinit_complete(device_t dev) >> { >> >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); >> } >> >> static void >> vtpci_notify_virtqueue(device_t dev, uint16_t queue) >> { >> struct vtpci_softc *sc; >> >> sc = device_get_softc(dev); >> >> vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_NOTIFY, queue); >> } >> >> static uint8_t >> vtpci_get_status(device_t dev) >> { >> struct vtpci_softc *sc; >> >> sc = device_get_softc(dev); >> >> return (vtpci_read_config_1(sc, VIRTIO_PCI_STATUS)); >> } >> >> static void >> vtpci_set_status(device_t dev, uint8_t status) >> { >> struct vtpci_softc *sc; >> >> sc = device_get_softc(dev); >> >> if (status != VIRTIO_CONFIG_STATUS_RESET) >> status |= vtpci_get_status(dev); >> >> vtpci_write_config_1(sc, VIRTIO_PCI_STATUS, status); >> } >> >> static void >> vtpci_read_dev_config(device_t dev, bus_size_t offset, >> void *dst, int length) >> { >> struct vtpci_softc *sc; >> bus_size_t off; >> uint8_t *d; >> int size; >> >> sc = device_get_softc(dev); >> off = VIRTIO_PCI_CONFIG(sc) + offset; >> >> for (d = dst; length > 0; d += size, off += size, length -= size) { >> if (length >= 4) { >> size = 4; >> *(uint32_t *)d = vtpci_read_config_4(sc, off); >> } else if (length >= 2) { >> size = 2; >> *(uint16_t *)d = vtpci_read_config_2(sc, off); >> } else { >> size = 1; >> *d = vtpci_read_config_1(sc, off); >> } >> } >> } >> >> static void >> vtpci_write_dev_config(device_t dev, bus_size_t offset, >> void *src, int length) >> { >> struct vtpci_softc *sc; >> bus_size_t off; >> uint8_t *s; >> int size; >> >> sc = device_get_softc(dev); >> off = VIRTIO_PCI_CONFIG(sc) + offset; >> >> for (s = src; length > 0; s += size, off += size, length -= size) { >> if (length >= 4) { >> size = 4; >> vtpci_write_config_4(sc, off, *(uint32_t *)s); >> } else if (length >= 2) { >> size = 2; >> vtpci_write_config_2(sc, off, *(uint16_t *)s); >> } else { >> size = 1; >> vtpci_write_config_1(sc, off, *s); >> } >> } >> } >> >> static void >> vtpci_describe_features(struct vtpci_softc *sc, const char *msg, >> uint64_t features) >> { >> device_t dev, child; >> >> dev = sc->vtpci_dev; >> child = sc->vtpci_child_dev; >> >> if (device_is_attached(child) || bootverbose == 0) >> return; >> >> virtio_describe(dev, msg, features, sc->vtpci_child_feat_desc); >> } >> >> static void >> vtpci_probe_and_attach_child(struct vtpci_softc *sc) >> { >> device_t dev, child; >> >> dev = sc->vtpci_dev; >> child = sc->vtpci_child_dev; >> >> if (child == NULL) >> return; >> >> if (device_get_state(child) != DS_NOTPRESENT) >> return; >> >> if (device_probe(child) != 0) >> return; >> >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); >> if (device_attach(child) != 0) { >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); >> vtpci_reset(sc); >> vtpci_release_child_resources(sc); >> /* Reset status for future attempt. */ >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); >> } else { >> vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); >> VIRTIO_ATTACH_COMPLETED(child); >> } >> } >> >> static int >> vtpci_alloc_msix(struct vtpci_softc *sc, int nvectors) >> { >395c777 >< dev = cn->vtpci_dev; >--- >> dev = sc->vtpci_dev; >406c788 >< cn->vtpci_nmsix_resources = required; >--- >> sc->vtpci_nmsix_resources = required; >416c798 >< vtpci_alloc_msi(struct vtpci_common *cn) >--- >> vtpci_alloc_msi(struct vtpci_softc *sc) >421c803 >< dev = cn->vtpci_dev; >--- >> dev = sc->vtpci_dev; >438c820 >< vtpci_alloc_intr_msix_pervq(struct vtpci_common *cn) >--- >> vtpci_alloc_intr_msix_pervq(struct vtpci_softc *sc) >442c824,825 >< if (vtpci_disable_msix != 0 || cn->vtpci_flags & VTPCI_FLAG_NO_MSIX) >--- >> if (vtpci_disable_msix != 0 || >> sc->vtpci_flags & VTPCI_FLAG_NO_MSIX) >445,446c828,829 >< for (nvectors = 0, i = 0; i < cn->vtpci_nvqs; i++) { >< if (cn->vtpci_vqs[i].vtv_no_intr == 0) >--- >> for (nvectors = 0, i = 0; i < sc->vtpci_nvqs; i++) { >> if (sc->vtpci_vqs[i].vtv_no_intr == 0) >450c833 >< error = vtpci_alloc_msix(cn, nvectors); >--- >> error = vtpci_alloc_msix(sc, nvectors); >454c837 >< cn->vtpci_flags |= VTPCI_FLAG_MSIX; >--- >> sc->vtpci_flags |= VTPCI_FLAG_MSIX; >460c843 >< vtpci_alloc_intr_msix_shared(struct vtpci_common *cn) >--- >> vtpci_alloc_intr_msix_shared(struct vtpci_softc *sc) >464c847,848 >< if (vtpci_disable_msix != 0 || cn->vtpci_flags & VTPCI_FLAG_NO_MSIX) >--- >> if (vtpci_disable_msix != 0 || >> sc->vtpci_flags & VTPCI_FLAG_NO_MSIX) >467c851 >< error = vtpci_alloc_msix(cn, 1); >--- >> error = vtpci_alloc_msix(sc, 1); >471c855 >< cn->vtpci_flags |= VTPCI_FLAG_MSIX | VTPCI_FLAG_SHARED_MSIX; >--- >> sc->vtpci_flags |= VTPCI_FLAG_MSIX | VTPCI_FLAG_SHARED_MSIX; >477c861 >< vtpci_alloc_intr_msi(struct vtpci_common *cn) >--- >> vtpci_alloc_intr_msi(struct vtpci_softc *sc) >482c866 >< if (cn->vtpci_flags & VTPCI_FLAG_NO_MSI) >--- >> if (sc->vtpci_flags & VTPCI_FLAG_NO_MSI) >485c869 >< error = vtpci_alloc_msi(cn); >--- >> error = vtpci_alloc_msi(sc); >489c873 >< cn->vtpci_flags |= VTPCI_FLAG_MSI; >--- >> sc->vtpci_flags |= VTPCI_FLAG_MSI; >495c879 >< vtpci_alloc_intr_intx(struct vtpci_common *cn) >--- >> vtpci_alloc_intr_legacy(struct vtpci_softc *sc) >498c882 >< cn->vtpci_flags |= VTPCI_FLAG_INTX; >--- >> sc->vtpci_flags |= VTPCI_FLAG_LEGACY; >504c888 >< vtpci_alloc_interrupt(struct vtpci_common *cn, int rid, int flags, >--- >> vtpci_alloc_interrupt(struct vtpci_softc *sc, int rid, int flags, >509c893 >< irq = bus_alloc_resource_any(cn->vtpci_dev, SYS_RES_IRQ, &rid, flags); >--- >> irq = bus_alloc_resource_any(sc->vtpci_dev, SYS_RES_IRQ, &rid, flags); >519,607d902 >< static void >< vtpci_free_interrupt(struct vtpci_common *cn, struct vtpci_interrupt *intr) >< { >< device_t dev; >< >< dev = cn->vtpci_dev; >< >< if (intr->vti_handler != NULL) { >< bus_teardown_intr(dev, intr->vti_irq, intr->vti_handler); >< intr->vti_handler = NULL; >< } >< >< if (intr->vti_irq != NULL) { >< bus_release_resource(dev, SYS_RES_IRQ, intr->vti_rid, >< intr->vti_irq); >< intr->vti_irq = NULL; >< intr->vti_rid = -1; >< } >< } >< >< static void >< vtpci_free_interrupts(struct vtpci_common *cn) >< { >< struct vtpci_interrupt *intr; >< int i, nvq_intrs; >< >< vtpci_free_interrupt(cn, &cn->vtpci_device_interrupt); >< >< if (cn->vtpci_nmsix_resources != 0) { >< nvq_intrs = cn->vtpci_nmsix_resources - 1; >< cn->vtpci_nmsix_resources = 0; >< >< if ((intr = cn->vtpci_msix_vq_interrupts) != NULL) { >< for (i = 0; i < nvq_intrs; i++, intr++) >< vtpci_free_interrupt(cn, intr); >< >< free(cn->vtpci_msix_vq_interrupts, M_DEVBUF); >< cn->vtpci_msix_vq_interrupts = NULL; >< } >< } >< >< if (cn->vtpci_flags & (VTPCI_FLAG_MSI | VTPCI_FLAG_MSIX)) >< pci_release_msi(cn->vtpci_dev); >< >< cn->vtpci_flags &= ~VTPCI_FLAG_ITYPE_MASK; >< } >< >< static void >< vtpci_free_virtqueues(struct vtpci_common *cn) >< { >< struct vtpci_virtqueue *vqx; >< int idx; >< >< for (idx = 0; idx < cn->vtpci_nvqs; idx++) { >< vtpci_disable_vq(cn, idx); >< >< vqx = &cn->vtpci_vqs[idx]; >< virtqueue_free(vqx->vtv_vq); >< vqx->vtv_vq = NULL; >< } >< >< free(cn->vtpci_vqs, M_DEVBUF); >< cn->vtpci_vqs = NULL; >< cn->vtpci_nvqs = 0; >< } >< >< void >< vtpci_release_child_resources(struct vtpci_common *cn) >< { >< >< vtpci_free_interrupts(cn); >< vtpci_free_virtqueues(cn); >< } >< >< static void >< vtpci_cleanup_setup_intr_attempt(struct vtpci_common *cn) >< { >< int idx; >< >< if (cn->vtpci_flags & VTPCI_FLAG_MSIX) { >< vtpci_register_cfg_msix(cn, NULL); >< >< for (idx = 0; idx < cn->vtpci_nvqs; idx++) >< vtpci_register_vq_msix(cn, idx, NULL); >< } >< >< vtpci_free_interrupts(cn); >< } >< >609c904 >< vtpci_alloc_intr_resources(struct vtpci_common *cn) >--- >> vtpci_alloc_intr_resources(struct vtpci_softc *sc) >613a909 >> rid = 0; >616,617c912 >< if (cn->vtpci_flags & VTPCI_FLAG_INTX) { >< rid = 0; >--- >> if (sc->vtpci_flags & VTPCI_FLAG_LEGACY) >619c914 >< } else >--- >> else >623,625c918,920 >< * When using INTX or MSI interrupts, this resource handles all >< * interrupts. When using MSIX, this resource handles just the >< * configuration changed interrupt. >--- >> * For legacy and MSI interrupts, this single resource handles all >> * interrupts. For MSIX, this resource is used for the configuration >> * changed interrupt. >627,630c922,924 >< intr = &cn->vtpci_device_interrupt; >< >< error = vtpci_alloc_interrupt(cn, rid, flags, intr); >< if (error || cn->vtpci_flags & (VTPCI_FLAG_INTX | VTPCI_FLAG_MSI)) >--- >> intr = &sc->vtpci_device_interrupt; >> error = vtpci_alloc_interrupt(sc, rid, flags, intr); >> if (error || sc->vtpci_flags & (VTPCI_FLAG_LEGACY | VTPCI_FLAG_MSI)) >633,638c927,928 >< /* >< * Now allocate the interrupts for the virtqueues. This may be one >< * for all the virtqueues, or one for each virtqueue. Subtract one >< * below for because of the configuration changed interrupt. >< */ >< nvq_intrs = cn->vtpci_nmsix_resources - 1; >--- >> /* Subtract one for the configuration changed interrupt. */ >> nvq_intrs = sc->vtpci_nmsix_resources - 1; >640c930 >< cn->vtpci_msix_vq_interrupts = malloc(nvq_intrs * >--- >> intr = sc->vtpci_msix_vq_interrupts = malloc(nvq_intrs * >642c932 >< if (cn->vtpci_msix_vq_interrupts == NULL) >--- >> if (sc->vtpci_msix_vq_interrupts == NULL) >645,646d934 >< intr = cn->vtpci_msix_vq_interrupts; >< >648c936 >< error = vtpci_alloc_interrupt(cn, rid, flags, intr); >--- >> error = vtpci_alloc_interrupt(sc, rid, flags, intr); >657c945 >< vtpci_setup_intx_interrupt(struct vtpci_common *cn, enum intr_type type) >--- >> vtpci_setup_legacy_interrupt(struct vtpci_softc *sc, enum intr_type type) >662c950,952 >< intr = &cn->vtpci_device_interrupt; >--- >> intr = &sc->vtpci_device_interrupt; >> error = bus_setup_intr(sc->vtpci_dev, intr->vti_irq, type, NULL, >> vtpci_legacy_intr, sc, &intr->vti_handler); >664,666d953 >< error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, NULL, >< vtpci_intx_intr, cn, &intr->vti_handler); >< >671c958 >< vtpci_setup_pervq_msix_interrupts(struct vtpci_common *cn, enum intr_type type) >--- >> vtpci_setup_pervq_msix_interrupts(struct vtpci_softc *sc, enum intr_type type) >677c964 >< intr = cn->vtpci_msix_vq_interrupts; >--- >> intr = sc->vtpci_msix_vq_interrupts; >679,680c966,967 >< for (i = 0; i < cn->vtpci_nvqs; i++) { >< vqx = &cn->vtpci_vqs[i]; >--- >> for (i = 0; i < sc->vtpci_nvqs; i++) { >> vqx = &sc->vtpci_vqs[i]; >685c972 >< error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, >--- >> error = bus_setup_intr(sc->vtpci_dev, intr->vti_irq, type, >698c985 >< vtpci_set_host_msix_vectors(struct vtpci_common *cn) >--- >> vtpci_setup_msix_interrupts(struct vtpci_softc *sc, enum intr_type type) >699a987,1062 >> device_t dev; >> struct vtpci_interrupt *intr; >> int error; >> >> dev = sc->vtpci_dev; >> intr = &sc->vtpci_device_interrupt; >> >> error = bus_setup_intr(dev, intr->vti_irq, type, NULL, >> vtpci_config_intr, sc, &intr->vti_handler); >> if (error) >> return (error); >> >> if (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) { >> intr = sc->vtpci_msix_vq_interrupts; >> error = bus_setup_intr(dev, intr->vti_irq, type, >> vtpci_vq_shared_intr_filter, vtpci_vq_shared_intr, sc, >> &intr->vti_handler); >> } else >> error = vtpci_setup_pervq_msix_interrupts(sc, type); >> >> return (error ? error : vtpci_set_host_msix_vectors(sc)); >> } >> >> static int >> vtpci_setup_interrupts(struct vtpci_softc *sc, enum intr_type type) >> { >> int error; >> >> type |= INTR_MPSAFE; >> KASSERT(sc->vtpci_flags & VTPCI_FLAG_ITYPE_MASK, >> ("%s: no interrupt type selected %#x", __func__, sc->vtpci_flags)); >> >> error = vtpci_alloc_intr_resources(sc); >> if (error) >> return (error); >> >> if (sc->vtpci_flags & VTPCI_FLAG_LEGACY) >> error = vtpci_setup_legacy_interrupt(sc, type); >> else if (sc->vtpci_flags & VTPCI_FLAG_MSI) >> error = vtpci_setup_msi_interrupt(sc, type); >> else >> error = vtpci_setup_msix_interrupts(sc, type); >> >> return (error); >> } >> >> static int >> vtpci_register_msix_vector(struct vtpci_softc *sc, int offset, >> struct vtpci_interrupt *intr) >> { >> device_t dev; >> uint16_t vector; >> >> dev = sc->vtpci_dev; >> >> if (intr != NULL) { >> /* Map from guest rid to host vector. */ >> vector = intr->vti_rid - 1; >> } else >> vector = VIRTIO_MSI_NO_VECTOR; >> >> vtpci_write_config_2(sc, offset, vector); >> >> /* Read vector to determine if the host had sufficient resources. */ >> if (vtpci_read_config_2(sc, offset) != vector) { >> device_printf(dev, >> "insufficient host resources for MSIX interrupts\n"); >> return (ENODEV); >> } >> >> return (0); >> } >> >> static int >> vtpci_set_host_msix_vectors(struct vtpci_softc *sc) >> { >701c1064 >< int idx, error; >--- >> int idx, offset, error; >703,704c1066,1069 >< intr = &cn->vtpci_device_interrupt; >< error = vtpci_register_cfg_msix(cn, intr); >--- >> intr = &sc->vtpci_device_interrupt; >> offset = VIRTIO_MSI_CONFIG_VECTOR; >> >> error = vtpci_register_msix_vector(sc, offset, intr); >708,710c1073,1079 >< intr = cn->vtpci_msix_vq_interrupts; >< for (idx = 0; idx < cn->vtpci_nvqs; idx++) { >< if (cn->vtpci_vqs[idx].vtv_no_intr) >--- >> intr = sc->vtpci_msix_vq_interrupts; >> offset = VIRTIO_MSI_QUEUE_VECTOR; >> >> for (idx = 0; idx < sc->vtpci_nvqs; idx++) { >> vtpci_select_virtqueue(sc, idx); >> >> if (sc->vtpci_vqs[idx].vtv_no_intr) >715c1084 >< error = vtpci_register_vq_msix(cn, idx, tintr); >--- >> error = vtpci_register_msix_vector(sc, offset, tintr); >723,724c1092,1093 >< if (!cn->vtpci_vqs[idx].vtv_no_intr && >< (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) == 0) >--- >> if (!sc->vtpci_vqs[idx].vtv_no_intr && >> (sc->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) == 0) >732c1101 >< vtpci_setup_msix_interrupts(struct vtpci_common *cn, enum intr_type type) >--- >> vtpci_reinit_virtqueue(struct vtpci_softc *sc, int idx) >734c1103,1104 >< struct vtpci_interrupt *intr; >--- >> struct vtpci_virtqueue *vqx; >> struct virtqueue *vq; >735a1106 >> uint16_t size; >737c1108,1109 >< intr = &cn->vtpci_device_interrupt; >--- >> vqx = &sc->vtpci_vqs[idx]; >> vq = vqx->vtv_vq; >739,740c1111,1116 >< error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, NULL, >< vtpci_config_intr, cn, &intr->vti_handler); >--- >> KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx)); >> >> vtpci_select_virtqueue(sc, idx); >> size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM); >> >> error = virtqueue_reinit(vq, size); >744,745c1120,1121 >< if (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) { >< intr = &cn->vtpci_msix_vq_interrupts[0]; >--- >> vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN, >> virtqueue_paddr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT); >747,753c1123 >< error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, >< vtpci_vq_shared_intr_filter, vtpci_vq_shared_intr, cn, >< &intr->vti_handler); >< } else >< error = vtpci_setup_pervq_msix_interrupts(cn, type); >< >< return (error ? error : vtpci_set_host_msix_vectors(cn)); >--- >> return (0); >756,757c1126,1127 >< static int >< vtpci_setup_intrs(struct vtpci_common *cn, enum intr_type type) >--- >> static void >> vtpci_free_interrupt(struct vtpci_softc *sc, struct vtpci_interrupt *intr) >759c1129 >< int error; >--- >> device_t dev; >761,763c1131 >< type |= INTR_MPSAFE; >< KASSERT(cn->vtpci_flags & VTPCI_FLAG_ITYPE_MASK, >< ("%s: no interrupt type selected %#x", __func__, cn->vtpci_flags)); >--- >> dev = sc->vtpci_dev; >765,767c1133,1136 >< error = vtpci_alloc_intr_resources(cn); >< if (error) >< return (error); >--- >> if (intr->vti_handler != NULL) { >> bus_teardown_intr(dev, intr->vti_irq, intr->vti_handler); >> intr->vti_handler = NULL; >> } >769,776c1138,1143 >< if (cn->vtpci_flags & VTPCI_FLAG_INTX) >< error = vtpci_setup_intx_interrupt(cn, type); >< else if (cn->vtpci_flags & VTPCI_FLAG_MSI) >< error = vtpci_setup_msi_interrupt(cn, type); >< else >< error = vtpci_setup_msix_interrupts(cn, type); >< >< return (error); >--- >> if (intr->vti_irq != NULL) { >> bus_release_resource(dev, SYS_RES_IRQ, intr->vti_rid, >> intr->vti_irq); >> intr->vti_irq = NULL; >> intr->vti_rid = -1; >> } >779,780c1146,1147 >< int >< vtpci_setup_interrupts(struct vtpci_common *cn, enum intr_type type) >--- >> static void >> vtpci_free_interrupts(struct vtpci_softc *sc) >782,783c1149,1150 >< device_t dev; >< int attempt, error; >--- >> struct vtpci_interrupt *intr; >> int i, nvq_intrs; >785c1152 >< dev = cn->vtpci_dev; >--- >> vtpci_free_interrupt(sc, &sc->vtpci_device_interrupt); >787,809c1154,1156 >< for (attempt = 0; attempt < 5; attempt++) { >< /* >< * Start with the most desirable interrupt configuration and >< * fallback towards less desirable ones. >< */ >< switch (attempt) { >< case 0: >< error = vtpci_alloc_intr_msix_pervq(cn); >< break; >< case 1: >< error = vtpci_alloc_intr_msix_shared(cn); >< break; >< case 2: >< error = vtpci_alloc_intr_msi(cn); >< break; >< case 3: >< error = vtpci_alloc_intr_intx(cn); >< break; >< default: >< device_printf(dev, >< "exhausted all interrupt allocation attempts\n"); >< return (ENXIO); >< } >--- >> if (sc->vtpci_nmsix_resources != 0) { >> nvq_intrs = sc->vtpci_nmsix_resources - 1; >> sc->vtpci_nmsix_resources = 0; >811,812c1158,1161 >< if (error == 0 && vtpci_setup_intrs(cn, type) == 0) >< break; >--- >> intr = sc->vtpci_msix_vq_interrupts; >> if (intr != NULL) { >> for (i = 0; i < nvq_intrs; i++, intr++) >> vtpci_free_interrupt(sc, intr); >814c1163,1165 >< vtpci_cleanup_setup_intr_attempt(cn); >--- >> free(sc->vtpci_msix_vq_interrupts, M_DEVBUF); >> sc->vtpci_msix_vq_interrupts = NULL; >> } >817,826c1168,1169 >< if (bootverbose) { >< if (cn->vtpci_flags & VTPCI_FLAG_INTX) >< device_printf(dev, "using legacy interrupt\n"); >< else if (cn->vtpci_flags & VTPCI_FLAG_MSI) >< device_printf(dev, "using MSI interrupt\n"); >< else if (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) >< device_printf(dev, "using shared MSIX interrupts\n"); >< else >< device_printf(dev, "using per VQ MSIX interrupts\n"); >< } >--- >> if (sc->vtpci_flags & (VTPCI_FLAG_MSI | VTPCI_FLAG_MSIX)) >> pci_release_msi(sc->vtpci_dev); >828c1171 >< return (0); >--- >> sc->vtpci_flags &= ~VTPCI_FLAG_ITYPE_MASK; >831,832c1174,1175 >< static int >< vtpci_reinit_virtqueue(struct vtpci_common *cn, int idx) >--- >> static void >> vtpci_free_virtqueues(struct vtpci_softc *sc) >835,836c1178 >< struct virtqueue *vq; >< int error; >--- >> int idx; >838,839c1180,1181 >< vqx = &cn->vtpci_vqs[idx]; >< vq = vqx->vtv_vq; >--- >> for (idx = 0; idx < sc->vtpci_nvqs; idx++) { >> vqx = &sc->vtpci_vqs[idx]; >841c1183,1184 >< KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx)); >--- >> vtpci_select_virtqueue(sc, idx); >> vtpci_write_config_4(sc, VIRTIO_PCI_QUEUE_PFN, 0); >843,845c1186,1188 >< error = virtqueue_reinit(vq, vtpci_get_vq_size(cn, idx)); >< if (error == 0) >< vtpci_set_vq(cn, vq); >--- >> virtqueue_free(vqx->vtv_vq); >> vqx->vtv_vq = NULL; >> } >847c1190,1192 >< return (error); >--- >> free(sc->vtpci_vqs, M_DEVBUF); >> sc->vtpci_vqs = NULL; >> sc->vtpci_nvqs = 0; >851c1196 >< vtpci_intx_intr(void *xcn) >--- >> vtpci_release_child_resources(struct vtpci_softc *sc) >853c1198,1243 >< struct vtpci_common *cn; >--- >> >> vtpci_free_interrupts(sc); >> vtpci_free_virtqueues(sc); >> } >> >> static void >> vtpci_cleanup_setup_intr_attempt(struct vtpci_softc *sc) >> { >> int idx; >> >> if (sc->vtpci_flags & VTPCI_FLAG_MSIX) { >> vtpci_write_config_2(sc, VIRTIO_MSI_CONFIG_VECTOR, >> VIRTIO_MSI_NO_VECTOR); >> >> for (idx = 0; idx < sc->vtpci_nvqs; idx++) { >> vtpci_select_virtqueue(sc, idx); >> vtpci_write_config_2(sc, VIRTIO_MSI_QUEUE_VECTOR, >> VIRTIO_MSI_NO_VECTOR); >> } >> } >> >> vtpci_free_interrupts(sc); >> } >> >> static void >> vtpci_reset(struct vtpci_softc *sc) >> { >> >> /* >> * Setting the status to RESET sets the host device to >> * the original, uninitialized state. >> */ >> vtpci_set_status(sc->vtpci_dev, VIRTIO_CONFIG_STATUS_RESET); >> } >> >> static void >> vtpci_select_virtqueue(struct vtpci_softc *sc, int idx) >> { >> >> vtpci_write_config_2(sc, VIRTIO_PCI_QUEUE_SEL, idx); >> } >> >> static void >> vtpci_legacy_intr(void *xsc) >> { >> struct vtpci_softc *sc; >858,859c1248,1249 >< cn = xcn; >< isr = vtpci_read_isr(cn); >--- >> sc = xsc; >> vqx = &sc->vtpci_vqs[0]; >860a1251,1253 >> /* Reading the ISR also clears it. */ >> isr = vtpci_read_config_1(sc, VIRTIO_PCI_ISR); >> >862c1255 >< vtpci_config_intr(cn); >--- >> vtpci_config_intr(sc); >865,866c1258 >< vqx = &cn->vtpci_vqs[0]; >< for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) { >--- >> for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) { >874c1266 >< vtpci_vq_shared_intr_filter(void *xcn) >--- >> vtpci_vq_shared_intr_filter(void *xsc) >876c1268 >< struct vtpci_common *cn; >--- >> struct vtpci_softc *sc; >880,881d1271 >< cn = xcn; >< vqx = &cn->vtpci_vqs[0]; >882a1273,1274 >> sc = xsc; >> vqx = &sc->vtpci_vqs[0]; >884c1276 >< for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) { >--- >> for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) { >893c1285 >< vtpci_vq_shared_intr(void *xcn) >--- >> vtpci_vq_shared_intr(void *xsc) >895c1287 >< struct vtpci_common *cn; >--- >> struct vtpci_softc *sc; >899,900c1291,1292 >< cn = xcn; >< vqx = &cn->vtpci_vqs[0]; >--- >> sc = xsc; >> vqx = &sc->vtpci_vqs[0]; >902c1294 >< for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) { >--- >> for (i = 0; i < sc->vtpci_nvqs; i++, vqx++) { >930c1322 >< vtpci_config_intr(void *xcn) >--- >> vtpci_config_intr(void *xsc) >932c1324 >< struct vtpci_common *cn; >--- >> struct vtpci_softc *sc; >935,936c1327,1328 >< cn = xcn; >< child = cn->vtpci_child_dev; >--- >> sc = xsc; >> child = sc->vtpci_child_dev; >940,1000d1331 >< } >< >< static int >< vtpci_feature_sysctl(struct sysctl_req *req, struct vtpci_common *cn, >< uint64_t features) >< { >< struct sbuf *sb; >< int error; >< >< sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); >< if (sb == NULL) >< return (ENOMEM); >< >< error = virtio_describe_sbuf(sb, features, cn->vtpci_child_feat_desc); >< sbuf_delete(sb); >< >< return (error); >< } >< >< static int >< vtpci_host_features_sysctl(SYSCTL_HANDLER_ARGS) >< { >< struct vtpci_common *cn; >< >< cn = arg1; >< >< return (vtpci_feature_sysctl(req, cn, cn->vtpci_host_features)); >< } >< >< static int >< vtpci_negotiated_features_sysctl(SYSCTL_HANDLER_ARGS) >< { >< struct vtpci_common *cn; >< >< cn = arg1; >< >< return (vtpci_feature_sysctl(req, cn, cn->vtpci_features)); >< } >< >< static void >< vtpci_setup_sysctl(struct vtpci_common *cn) >< { >< device_t dev; >< struct sysctl_ctx_list *ctx; >< struct sysctl_oid *tree; >< struct sysctl_oid_list *child; >< >< dev = cn->vtpci_dev; >< ctx = device_get_sysctl_ctx(dev); >< tree = device_get_sysctl_tree(dev); >< child = SYSCTL_CHILDREN(tree); >< >< SYSCTL_ADD_INT(ctx, child, OID_AUTO, "nvqs", >< CTLFLAG_RD, &cn->vtpci_nvqs, 0, "Number of virtqueues"); >< >< SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "host_features", >< CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0, >< vtpci_host_features_sysctl, "A", "Features supported by the host"); >< SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "negotiated_features", >< CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, cn, 0, >< vtpci_negotiated_features_sysctl, "A", "Features negotiated"); >diff -r /usr/src/sys/dev/virtio/pci/virtio_pci.h HD12/usr/src/sys/dev/virtio/pci/virtio_pci.h >2c2 >< * SPDX-License-Identifier: BSD-2-Clause-FreeBSD >--- >> * SPDX-License-Identifier: BSD-3-Clause >4,5c4 >< * Copyright (c) 2017, Bryan Venteicher <bryanv@FreeBSD.org> >< * All rights reserved. >--- >> * Copyright IBM Corp. 2007 >6a6,11 >> * Authors: >> * Anthony Liguori <aliguori@us.ibm.com> >> * >> * This header is BSD licensed so anyone can use the definitions to implement >> * compatible drivers/servers. >> * >11,12c16 >< * notice unmodified, this list of conditions, and the following >< * disclaimer. >--- >> * notice, this list of conditions and the following disclaimer. >15a20,33 >> * 3. Neither the name of IBM nor the names of its contributors >> * may be used to endorse or promote products derived from this software >> * without specific prior written permission. >> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 IBM 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. >17,28c35 >< * 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. >< * >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/pci/virtio_pci.h 326022 2017-11-20 19:36:21Z pfg $ >34,38c41,44 >< struct vtpci_interrupt { >< struct resource *vti_irq; >< int vti_rid; >< void *vti_handler; >< }; >--- >> /* VirtIO PCI vendor/device ID. */ >> #define VIRTIO_PCI_VENDORID 0x1AF4 >> #define VIRTIO_PCI_DEVICEID_MIN 0x1000 >> #define VIRTIO_PCI_DEVICEID_MAX 0x103F >40,44c46,47 >< struct vtpci_virtqueue { >< struct virtqueue *vtv_vq; >< int vtv_no_intr; >< int vtv_notify_offset; >< }; >--- >> /* VirtIO ABI version, this must match exactly. */ >> #define VIRTIO_PCI_ABI_VERSION 0 >46,51c49,64 >< struct vtpci_common { >< device_t vtpci_dev; >< uint64_t vtpci_host_features; >< uint64_t vtpci_features; >< struct vtpci_virtqueue *vtpci_vqs; >< int vtpci_nvqs; >--- >> /* >> * VirtIO Header, located in BAR 0. >> */ >> #define VIRTIO_PCI_HOST_FEATURES 0 /* host's supported features (32bit, RO)*/ >> #define VIRTIO_PCI_GUEST_FEATURES 4 /* guest's supported features (32, RW) */ >> #define VIRTIO_PCI_QUEUE_PFN 8 /* physical address of VQ (32, RW) */ >> #define VIRTIO_PCI_QUEUE_NUM 12 /* number of ring entries (16, RO) */ >> #define VIRTIO_PCI_QUEUE_SEL 14 /* current VQ selection (16, RW) */ >> #define VIRTIO_PCI_QUEUE_NOTIFY 16 /* notify host regarding VQ (16, RW) */ >> #define VIRTIO_PCI_STATUS 18 /* device status register (8, RW) */ >> #define VIRTIO_PCI_ISR 19 /* interrupt status register, reading >> * also clears the register (8, RO) */ >> /* Only if MSIX is enabled: */ >> #define VIRTIO_MSI_CONFIG_VECTOR 20 /* configuration change vector (16, RW) */ >> #define VIRTIO_MSI_QUEUE_VECTOR 22 /* vector for selected VQ notifications >> (16, RW) */ >53,61c66,71 >< uint32_t vtpci_flags; >< #define VTPCI_FLAG_NO_MSI 0x0001 >< #define VTPCI_FLAG_NO_MSIX 0x0002 >< #define VTPCI_FLAG_MODERN 0x0004 >< #define VTPCI_FLAG_INTX 0x1000 >< #define VTPCI_FLAG_MSI 0x2000 >< #define VTPCI_FLAG_MSIX 0x4000 >< #define VTPCI_FLAG_SHARED_MSIX 0x8000 >< #define VTPCI_FLAG_ITYPE_MASK 0xF000 >--- >> /* The bit of the ISR which indicates a device has an interrupt. */ >> #define VIRTIO_PCI_ISR_INTR 0x1 >> /* The bit of the ISR which indicates a device configuration change. */ >> #define VIRTIO_PCI_ISR_CONFIG 0x2 >> /* Vector value used to disable MSI for queue. */ >> #define VIRTIO_MSI_NO_VECTOR 0xFFFF >63,65c73,77 >< /* The VirtIO PCI "bus" will only ever have one child. */ >< device_t vtpci_child_dev; >< struct virtio_feature_desc *vtpci_child_feat_desc; >--- >> /* >> * The remaining space is defined by each driver as the per-driver >> * configuration space. >> */ >> #define VIRTIO_PCI_CONFIG_OFF(msix_enabled) ((msix_enabled) ? 24 : 20) >67,80c79,83 >< /* >< * Ideally, each virtqueue that the driver provides a callback for will >< * receive its own MSIX vector. If there are not sufficient vectors >< * available, then attempt to have all the VQs share one vector. For >< * MSIX, the configuration changed notifications must be on their own >< * vector. >< * >< * If MSIX is not available, attempt to have the whole device share >< * one MSI vector, and then, finally, one intx interrupt. >< */ >< struct vtpci_interrupt vtpci_device_interrupt; >< struct vtpci_interrupt *vtpci_msix_vq_interrupts; >< int vtpci_nmsix_resources; >< }; >--- >> /* >> * How many bits to shift physical queue address written to QUEUE_PFN. >> * 12 is historical, and due to x86 page size. >> */ >> #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 >82,130c85,86 >< extern int vtpci_disable_msix; >< >< static inline device_t >< vtpci_child_device(struct vtpci_common *cn) >< { >< return (cn->vtpci_child_dev); >< } >< >< static inline bool >< vtpci_is_msix_available(struct vtpci_common *cn) >< { >< return ((cn->vtpci_flags & VTPCI_FLAG_NO_MSIX) == 0); >< } >< >< static inline bool >< vtpci_is_msix_enabled(struct vtpci_common *cn) >< { >< return ((cn->vtpci_flags & VTPCI_FLAG_MSIX) != 0); >< } >< >< static inline bool >< vtpci_is_modern(struct vtpci_common *cn) >< { >< return ((cn->vtpci_flags & VTPCI_FLAG_MODERN) != 0); >< } >< >< static inline int >< vtpci_virtqueue_count(struct vtpci_common *cn) >< { >< return (cn->vtpci_nvqs); >< } >< >< void vtpci_init(struct vtpci_common *cn, device_t dev, bool modern); >< int vtpci_add_child(struct vtpci_common *cn); >< int vtpci_delete_child(struct vtpci_common *cn); >< void vtpci_child_detached(struct vtpci_common *cn); >< int vtpci_reinit(struct vtpci_common *cn); >< >< uint64_t vtpci_negotiate_features(struct vtpci_common *cn, >< uint64_t child_features, uint64_t host_features); >< int vtpci_with_feature(struct vtpci_common *cn, uint64_t feature); >< >< int vtpci_read_ivar(struct vtpci_common *cn, int index, uintptr_t *result); >< int vtpci_write_ivar(struct vtpci_common *cn, int index, uintptr_t value); >< >< int vtpci_alloc_virtqueues(struct vtpci_common *cn, int flags, int nvqs, >< struct vq_alloc_info *vq_info); >< int vtpci_setup_interrupts(struct vtpci_common *cn, enum intr_type type); >< void vtpci_release_child_resources(struct vtpci_common *cn); >--- >> /* The alignment to use between consumer and producer parts of vring. */ >> #define VIRTIO_PCI_VRING_ALIGN 4096 >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_if.m >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_legacy.c >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_legacy_var.h >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_modern.c >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_modern_var.h >Only in /usr/src/sys/dev/virtio/pci: virtio_pci_var.h >diff -r /usr/src/sys/dev/virtio/random/virtio_random.c HD12/usr/src/sys/dev/virtio/random/virtio_random.c >32c32 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/random/virtio_random.c 338324 2018-08-26 12:51:46Z markm $"); >61,62c61 >< static int vtrnd_negotiate_features(struct vtrnd_softc *); >< static int vtrnd_setup_features(struct vtrnd_softc *); >--- >> static void vtrnd_negotiate_features(struct vtrnd_softc *); >89c88 >< DRIVER_MODULE(virtio_random, vtpcil, vtrnd_driver, vtrnd_devclass, >--- >> DRIVER_MODULE(virtio_random, virtio_pci, vtrnd_driver, vtrnd_devclass, >91,92d89 >< DRIVER_MODULE(virtio_random, vtpcim, vtrnd_driver, vtrnd_devclass, >< vtrnd_modevent, 0); >136d132 >< virtio_set_feature_desc(dev, vtrnd_feature_desc); >140,144c136,137 >< error = vtrnd_setup_features(sc); >< if (error) { >< device_printf(dev, "cannot setup features\n"); >< goto fail; >< } >--- >> virtio_set_feature_desc(dev, vtrnd_feature_desc); >> vtrnd_negotiate_features(sc); >173c166 >< static int >--- >> static void >183d175 >< return (virtio_finalize_features(dev)); >187,198d178 >< vtrnd_setup_features(struct vtrnd_softc *sc) >< { >< int error; >< >< error = vtrnd_negotiate_features(sc); >< if (error) >< return (error); >< >< return (0); >< } >< >< static int >240,241d219 >< // random_harvest_queue(&value, sizeof(value), sizeof(value) * NBBY / 2, >< // RANDOM_PURE_VIRTIO); >diff -r /usr/src/sys/dev/virtio/scsi/virtio_scsi.c HD12/usr/src/sys/dev/virtio/scsi/virtio_scsi.c >32c32 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/scsi/virtio_scsi.c 349691 2019-07-03 19:52:24Z vangyzen $"); >79,80c79 >< static int vtscsi_negotiate_features(struct vtscsi_softc *); >< static int vtscsi_setup_features(struct vtscsi_softc *); >--- >> static void vtscsi_negotiate_features(struct vtscsi_softc *); >139,142c138,141 >< static void vtscsi_init_scsi_cmd_req(struct vtscsi_softc *, >< struct ccb_scsiio *, struct virtio_scsi_cmd_req *); >< static void vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *, struct ccb_hdr *, >< uint32_t, uintptr_t, struct virtio_scsi_ctrl_tmf_req *); >--- >> static void vtscsi_init_scsi_cmd_req(struct ccb_scsiio *, >> struct virtio_scsi_cmd_req *); >> static void vtscsi_init_ctrl_tmf_req(struct ccb_hdr *, uint32_t, >> uintptr_t, struct virtio_scsi_ctrl_tmf_req *); >188c187 >< static void vtscsi_setup_sysctl(struct vtscsi_softc *); >--- >> static void vtscsi_add_sysctl(struct vtscsi_softc *); >193,200d191 >< #define vtscsi_modern(_sc) (((_sc)->vtscsi_features & VIRTIO_F_VERSION_1) != 0) >< #define vtscsi_htog16(_sc, _val) virtio_htog16(vtscsi_modern(_sc), _val) >< #define vtscsi_htog32(_sc, _val) virtio_htog32(vtscsi_modern(_sc), _val) >< #define vtscsi_htog64(_sc, _val) virtio_htog64(vtscsi_modern(_sc), _val) >< #define vtscsi_gtoh16(_sc, _val) virtio_gtoh16(vtscsi_modern(_sc), _val) >< #define vtscsi_gtoh32(_sc, _val) virtio_gtoh32(vtscsi_modern(_sc), _val) >< #define vtscsi_gtoh64(_sc, _val) virtio_gtoh64(vtscsi_modern(_sc), _val) >< >218,219d208 >< { VIRTIO_SCSI_F_CHANGE, "ChangeEvent" }, >< { VIRTIO_SCSI_F_T10_PI, "T10PI" }, >242c231 >< DRIVER_MODULE(virtio_scsi, vtpcil, vtscsi_driver, vtscsi_devclass, >--- >> DRIVER_MODULE(virtio_scsi, virtio_pci, vtscsi_driver, vtscsi_devclass, >244,245d232 >< DRIVER_MODULE(virtio_scsi, vtpcim, vtscsi_driver, vtscsi_devclass, >< vtscsi_modevent, 0); >291d277 >< virtio_set_feature_desc(dev, vtscsi_feature_desc); >297c283 >< vtscsi_setup_sysctl(sc); >--- >> vtscsi_add_sysctl(sc); >299,303c285,286 >< error = vtscsi_setup_features(sc); >< if (error) { >< device_printf(dev, "cannot setup features\n"); >< goto fail; >< } >--- >> virtio_set_feature_desc(dev, vtscsi_feature_desc); >> vtscsi_negotiate_features(sc); >304a288,294 >> if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC)) >> sc->vtscsi_flags |= VTSCSI_FLAG_INDIRECT; >> if (virtio_with_feature(dev, VIRTIO_SCSI_F_INOUT)) >> sc->vtscsi_flags |= VTSCSI_FLAG_BIDIRECTIONAL; >> if (virtio_with_feature(dev, VIRTIO_SCSI_F_HOTPLUG)) >> sc->vtscsi_flags |= VTSCSI_FLAG_HOTPLUG; >> >416c406 >< static int >--- >> static void >423,426c413,414 >< features = VTSCSI_FEATURES; >< >< sc->vtscsi_features = virtio_negotiate_features(dev, features); >< return (virtio_finalize_features(dev)); >--- >> features = virtio_negotiate_features(dev, VTSCSI_FEATURES); >> sc->vtscsi_features = features; >429,450d416 >< static int >< vtscsi_setup_features(struct vtscsi_softc *sc) >< { >< device_t dev; >< int error; >< >< dev = sc->vtscsi_dev; >< >< error = vtscsi_negotiate_features(sc); >< if (error) >< return (error); >< >< if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC)) >< sc->vtscsi_flags |= VTSCSI_FLAG_INDIRECT; >< if (virtio_with_feature(dev, VIRTIO_SCSI_F_INOUT)) >< sc->vtscsi_flags |= VTSCSI_FLAG_BIDIRECTIONAL; >< if (virtio_with_feature(dev, VIRTIO_SCSI_F_HOTPLUG)) >< sc->vtscsi_flags |= VTSCSI_FLAG_HOTPLUG; >< >< return (0); >< } >< >568d533 >< virtio_reinit_complete(dev); >569a535 >> virtio_reinit_complete(dev); >1123c1089 >< vtscsi_init_scsi_cmd_req(sc, csio, cmd_req); >--- >> vtscsi_init_scsi_cmd_req(csio, cmd_req); >1243c1209 >< vtscsi_init_ctrl_tmf_req(sc, to_ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK, >--- >> vtscsi_init_ctrl_tmf_req(to_ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK, >1351d1316 >< uint32_t resp_sense_length; >1355c1320 >< csio->resid = vtscsi_htog32(sc, cmd_resp->resid); >--- >> csio->resid = cmd_resp->resid; >1362,1364c1327 >< resp_sense_length = vtscsi_htog32(sc, cmd_resp->sense_len); >< >< if (resp_sense_length > 0) { >--- >> if (cmd_resp->sense_len > 0) { >1367,1368c1330,1332 >< if (resp_sense_length < csio->sense_len) >< csio->sense_resid = csio->sense_len - resp_sense_length; >--- >> if (cmd_resp->sense_len < csio->sense_len) >> csio->sense_resid = csio->sense_len - >> cmd_resp->sense_len; >1372,1373c1336 >< bzero(&csio->sense_data, sizeof(csio->sense_data)); >< memcpy(cmd_resp->sense, &csio->sense_data, >--- >> memcpy(&csio->sense_data, cmd_resp->sense, >1534c1497 >< vtscsi_init_ctrl_tmf_req(sc, ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK, >--- >> vtscsi_init_ctrl_tmf_req(ccbh, VIRTIO_SCSI_T_TMF_ABORT_TASK, >1603c1566 >< vtscsi_init_ctrl_tmf_req(sc, ccbh, subtype, 0, tmf_req); >--- >> vtscsi_init_ctrl_tmf_req(ccbh, subtype, 0, tmf_req); >1640c1603 >< vtscsi_init_scsi_cmd_req(struct vtscsi_softc *sc, struct ccb_scsiio *csio, >--- >> vtscsi_init_scsi_cmd_req(struct ccb_scsiio *csio, >1661c1624 >< cmd_req->tag = vtscsi_gtoh64(sc, (uintptr_t) csio); >--- >> cmd_req->tag = (uintptr_t) csio; >1671,1672c1634,1635 >< vtscsi_init_ctrl_tmf_req(struct vtscsi_softc *sc, struct ccb_hdr *ccbh, >< uint32_t subtype, uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req) >--- >> vtscsi_init_ctrl_tmf_req(struct ccb_hdr *ccbh, uint32_t subtype, >> uintptr_t tag, struct virtio_scsi_ctrl_tmf_req *tmf_req) >1677,1679c1640,1642 >< tmf_req->type = vtscsi_gtoh32(sc, VIRTIO_SCSI_T_TMF); >< tmf_req->subtype = vtscsi_gtoh32(sc, subtype); >< tmf_req->tag = vtscsi_gtoh64(sc, tag); >--- >> tmf_req->type = VIRTIO_SCSI_T_TMF; >> tmf_req->subtype = subtype; >> tmf_req->tag = tag; >2313c2276 >< vtscsi_setup_sysctl(struct vtscsi_softc *sc) >--- >> vtscsi_add_sysctl(struct vtscsi_softc *sc) >Only in /usr/src/sys/dev/virtio/scsi: virtio_scsi.c.orig >diff -r /usr/src/sys/dev/virtio/scsi/virtio_scsi.h HD12/usr/src/sys/dev/virtio/scsi/virtio_scsi.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/scsi/virtio_scsi.h 326255 2017-11-27 14:52:40Z pfg $ >34c34,40 >< /* Default values of the CDB and sense data size configuration fields */ >--- >> /* Feature bits */ >> #define VIRTIO_SCSI_F_INOUT 0x0001 /* Single request can contain both >> * read and write buffers */ >> #define VIRTIO_SCSI_F_HOTPLUG 0x0002 /* Host should enable hot plug/unplug >> * of new LUNs and targets. >> */ >> >43c49 >< uint8_t prio; /* SAM command priority field */ >--- >> uint8_t prio; >48,59d53 >< /* SCSI command request, followed by protection information */ >< struct virtio_scsi_cmd_req_pi { >< uint8_t lun[8]; /* Logical Unit Number */ >< uint64_t tag; /* Command identifier */ >< uint8_t task_attr; /* Task attribute */ >< uint8_t prio; /* SAM command priority field */ >< uint8_t crn; >< uint32_t pi_bytesout; /* DataOUT PI Number of bytes */ >< uint32_t pi_bytesin; /* DataIN PI Number of bytes */ >< uint8_t cdb[VIRTIO_SCSI_CDB_SIZE]; >< } __packed; >< >113,128d106 >< /* Feature bits */ >< #define VIRTIO_SCSI_F_INOUT 0x0001 /* Single request can contain both >< * read and write buffers. >< */ >< #define VIRTIO_SCSI_F_HOTPLUG 0x0002 /* Host should enable hot plug/unplug >< * of new LUNs and targets. >< */ >< #define VIRTIO_SCSI_F_CHANGE 0x0004 /* Host will report changes to LUN >< * parameters via a >< * VIRTIO_SCSI_T_PARAM_CHANGE event. >< */ >< #define VIRTIO_SCSI_F_T10_PI 0x0008 /* Extended fields for T10 protection >< * information (DIF/DIX) are included >< * in the SCSI request header. >< */ >< >165d142 >< #define VIRTIO_SCSI_T_PARAM_CHANGE 3 >diff -r /usr/src/sys/dev/virtio/scsi/virtio_scsivar.h HD12/usr/src/sys/dev/virtio/scsi/virtio_scsivar.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/scsi/virtio_scsivar.h 326255 2017-11-27 14:52:40Z pfg $ >diff -r /usr/src/sys/dev/virtio/virtio.c HD12/usr/src/sys/dev/virtio/virtio.c >30c30 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/virtio.c 329601 2018-02-19 19:28:24Z bryanv $"); >63c63 >< { VIRTIO_ID_RPMSG, "Remote Processor Messaging" }, >--- >> { VIRTIO_ID_RPMSG, "Remote Processor Messaging" }, >69,71c69,71 >< { VIRTIO_ID_INPUT, "Input" }, >< { VIRTIO_ID_VSOCK, "VSOCK Transport" }, >< { VIRTIO_ID_CRYPTO, "Crypto" }, >--- >> { VIRTIO_ID_INPUT, "Input" }, >> { VIRTIO_ID_VSOCK, "VSOCK Transport" }, >> { VIRTIO_ID_CRYPTO, "Crypto" }, >78,84c78,81 >< { VIRTIO_F_NOTIFY_ON_EMPTY, "NotifyOnEmpty" }, /* Legacy */ >< { VIRTIO_F_ANY_LAYOUT, "AnyLayout" }, /* Legacy */ >< { VIRTIO_RING_F_INDIRECT_DESC, "RingIndirectDesc" }, >< { VIRTIO_RING_F_EVENT_IDX, "RingEventIdx" }, >< { VIRTIO_F_BAD_FEATURE, "BadFeature" }, /* Legacy */ >< { VIRTIO_F_VERSION_1, "Version1" }, >< { VIRTIO_F_IOMMU_PLATFORM, "IOMMUPlatform" }, >--- >> { VIRTIO_F_NOTIFY_ON_EMPTY, "NotifyOnEmpty" }, >> { VIRTIO_RING_F_INDIRECT_DESC, "RingIndirect" }, >> { VIRTIO_RING_F_EVENT_IDX, "EventIdx" }, >> { VIRTIO_F_BAD_FEATURE, "BadFeature" }, >122,124c119,121 >< int >< virtio_describe_sbuf(struct sbuf *sb, uint64_t features, >< struct virtio_feature_desc *desc) >--- >> void >> virtio_describe(device_t dev, const char *msg, >> uint64_t features, struct virtio_feature_desc *desc) >126c123 >< const char *name; >--- >> struct sbuf sb; >127a125,126 >> char *buf; >> const char *name; >130c129,132 >< sbuf_printf(sb, "%#jx", (uintmax_t) features); >--- >> if ((buf = malloc(512, M_TEMP, M_NOWAIT)) == NULL) { >> device_printf(dev, "%s features: %#jx\n", msg, (uintmax_t) features); >> return; >> } >131a134,136 >> sbuf_new(&sb, buf, 512, SBUF_FIXEDLEN); >> sbuf_printf(&sb, "%s features: %#jx", msg, (uintmax_t) features); >> >141c146 >< sbuf_cat(sb, " <"); >--- >> sbuf_cat(&sb, " <"); >143c148 >< sbuf_cat(sb, ","); >--- >> sbuf_cat(&sb, ","); >147c152 >< sbuf_printf(sb, "%#jx", (uintmax_t) val); >--- >> sbuf_printf(&sb, "%#jx", (uintmax_t) val); >149c154 >< sbuf_cat(sb, name); >--- >> sbuf_cat(&sb, name); >153c158 >< sbuf_cat(sb, ">"); >--- >> sbuf_cat(&sb, ">"); >155,175c160,165 >< return (sbuf_finish(sb)); >< } >< >< void >< virtio_describe(device_t dev, const char *msg, uint64_t features, >< struct virtio_feature_desc *desc) >< { >< struct sbuf sb; >< char *buf; >< int error; >< >< if ((buf = malloc(1024, M_TEMP, M_NOWAIT)) == NULL) { >< error = ENOMEM; >< goto out; >< } >< >< sbuf_new(&sb, buf, 1024, SBUF_FIXEDLEN); >< sbuf_printf(&sb, "%s features: ", msg); >< >< error = virtio_describe_sbuf(&sb, features, desc); >< if (error == 0) >--- >> #if __FreeBSD_version < 900020 >> sbuf_finish(&sb); >> if (sbuf_overflowed(&sb) == 0) >> #else >> if (sbuf_finish(&sb) == 0) >> #endif >180,185d169 >< >< out: >< if (error != 0) { >< device_printf(dev, "%s features: %#jx\n", msg, >< (uintmax_t) features); >< } >188,229d171 >< uint64_t >< virtio_filter_transport_features(uint64_t features) >< { >< uint64_t transport, mask; >< >< transport = (1ULL << >< (VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START)) - 1; >< transport <<= VIRTIO_TRANSPORT_F_START; >< >< mask = -1ULL & ~transport; >< mask |= VIRTIO_RING_F_INDIRECT_DESC; >< mask |= VIRTIO_RING_F_EVENT_IDX; >< mask |= VIRTIO_F_VERSION_1; >< >< return (features & mask); >< } >< >< int >< virtio_bus_is_modern(device_t dev) >< { >< uintptr_t modern; >< >< virtio_read_ivar(dev, VIRTIO_IVAR_MODERN, &modern); >< return (modern != 0); >< } >< >< void >< virtio_read_device_config_array(device_t dev, bus_size_t offset, void *dst, >< int size, int count) >< { >< int i, gen; >< >< do { >< gen = virtio_config_generation(dev); >< >< for (i = 0; i < count; i++) { >< virtio_read_device_config(dev, offset + i * size, >< (uint8_t *) dst + i * size, size); >< } >< } while (gen != virtio_config_generation(dev)); >< } >< >255,261d196 >< } >< >< int >< virtio_finalize_features(device_t dev) >< { >< >< return (VIRTIO_BUS_FINALIZE_FEATURES(device_get_parent(dev))); >diff -r /usr/src/sys/dev/virtio/virtio.h HD12/usr/src/sys/dev/virtio/virtio.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/virtio.h 329601 2018-02-19 19:28:24Z bryanv $ >34d33 >< #include <dev/virtio/virtio_endian.h> >38d36 >< struct sbuf; >62d59 >< #define VIRTIO_IVAR_MODERN 7 >71,77c68 >< uint64_t features, struct virtio_feature_desc *desc); >< int virtio_describe_sbuf(struct sbuf *sb, uint64_t features, >< struct virtio_feature_desc *desc); >< uint64_t virtio_filter_transport_features(uint64_t features); >< int virtio_bus_is_modern(device_t dev); >< void virtio_read_device_config_array(device_t dev, bus_size_t offset, >< void *dst, int size, int count); >--- >> uint64_t features, struct virtio_feature_desc *feature_desc); >85d75 >< int virtio_finalize_features(device_t dev); >143d132 >< VIRTIO_READ_IVAR(modern, VIRTIO_IVAR_MODERN); >diff -r /usr/src/sys/dev/virtio/virtio_bus_if.m HD12/usr/src/sys/dev/virtio/virtio_bus_if.m >26c26 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/dev/virtio/virtio_bus_if.m 329601 2018-02-19 19:28:24Z bryanv $ >39,44d38 >< virtio_bus_default_finalize_features(device_t dev) >< { >< return (0); >< } >< >< static int >56,59d49 >< METHOD int finalize_features { >< device_t dev; >< } DEFAULT virtio_bus_default_finalize_features; >< >93d82 >< bus_size_t offset; >diff -r /usr/src/sys/dev/virtio/virtio_config.h HD12/usr/src/sys/dev/virtio/virtio_config.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/virtio_config.h 335305 2018-06-17 20:45:48Z bryanv $ >Only in /usr/src/sys/dev/virtio: virtio_endian.h >diff -r /usr/src/sys/dev/virtio/virtio_ids.h HD12/usr/src/sys/dev/virtio/virtio_ids.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/virtio_ids.h 327958 2018-01-14 06:03:40Z bryanv $ >diff -r /usr/src/sys/dev/virtio/virtio_if.m HD12/usr/src/sys/dev/virtio/virtio_if.m >26c26 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/dev/virtio/virtio_if.m 255110 2013-09-01 04:20:23Z bryanv $ >diff -r /usr/src/sys/dev/virtio/virtio_ring.h HD12/usr/src/sys/dev/virtio/virtio_ring.h >32c32 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/virtio_ring.h 335305 2018-06-17 20:45:48Z bryanv $ >diff -r /usr/src/sys/dev/virtio/virtqueue.c HD12/usr/src/sys/dev/virtio/virtqueue.c >35c35 >< __FBSDID("$FreeBSD$"); >--- >> __FBSDID("$FreeBSD: releng/12.1/sys/dev/virtio/virtqueue.c 329602 2018-02-19 19:31:18Z bryanv $"); >59a60 >> char vq_name[VIRTQUEUE_MAX_NAME_SZ]; >63,65c64,65 >< #define VIRTQUEUE_FLAG_MODERN 0x0001 >< #define VIRTQUEUE_FLAG_INDIRECT 0x0002 >< #define VIRTQUEUE_FLAG_EVENT_IDX 0x0004 >--- >> #define VIRTQUEUE_FLAG_INDIRECT 0x0001 >> #define VIRTQUEUE_FLAG_EVENT_IDX 0x0002 >66a67,69 >> int vq_alignment; >> int vq_ring_size; >> void *vq_ring_mem; >68c71 >< bus_size_t vq_notify_offset; >--- >> int vq_indirect_mem_size; >87,92d89 >< void *vq_ring_mem; >< int vq_indirect_mem_size; >< int vq_alignment; >< int vq_ring_size; >< char vq_name[VIRTQUEUE_MAX_NAME_SZ]; >< >140,147d136 >< #define vq_modern(_vq) (((_vq)->vq_flags & VIRTQUEUE_FLAG_MODERN) != 0) >< #define vq_htog16(_vq, _val) virtio_htog16(vq_modern(_vq), _val) >< #define vq_htog32(_vq, _val) virtio_htog32(vq_modern(_vq), _val) >< #define vq_htog64(_vq, _val) virtio_htog64(vq_modern(_vq), _val) >< #define vq_gtoh16(_vq, _val) virtio_gtoh16(vq_modern(_vq), _val) >< #define vq_gtoh32(_vq, _val) virtio_gtoh32(vq_modern(_vq), _val) >< #define vq_gtoh64(_vq, _val) virtio_gtoh64(vq_modern(_vq), _val) >< >161,163c150,151 >< virtqueue_alloc(device_t dev, uint16_t queue, uint16_t size, >< bus_size_t notify_offset, int align, vm_paddr_t highaddr, >< struct vq_alloc_info *info, struct virtqueue **vqp) >--- >> virtqueue_alloc(device_t dev, uint16_t queue, uint16_t size, int align, >> vm_paddr_t highaddr, struct vq_alloc_info *info, struct virtqueue **vqp) >199d186 >< vq->vq_notify_offset = notify_offset; >206,207d192 >< if (VIRTIO_BUS_WITH_FEATURE(dev, VIRTIO_F_VERSION_1) != 0) >< vq->vq_flags |= VIRTQUEUE_FLAG_MODERN; >312,313c297,298 >< indirect[i].next = vq_gtoh16(vq, i + 1); >< indirect[i].next = vq_gtoh16(vq, VQ_RING_DESC_CHAIN_END); >--- >> indirect[i].next = i + 1; >> indirect[i].next = VQ_RING_DESC_CHAIN_END; >411d395 >< >460c444 >< used_idx = vq_htog16(vq, vq->vq_ring.used->idx); >--- >> used_idx = vq->vq_ring.used->idx; >472c456 >< if (vq->vq_used_cons_idx == vq_htog16(vq, vq->vq_ring.used->idx)) >--- >> if (vq->vq_used_cons_idx == vq->vq_ring.used->idx) >499c483 >< avail_idx = vq_htog16(vq, vq->vq_ring.avail->idx); >--- >> avail_idx = vq->vq_ring.avail->idx; >524,529c508,511 >< vring_used_event(&vq->vq_ring) = vq_gtoh16(vq, >< vq->vq_used_cons_idx - vq->vq_nentries - 1); >< return; >< } >< >< vq->vq_ring.avail->flags |= vq_gtoh16(vq, VRING_AVAIL_F_NO_INTERRUPT); >--- >> vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx - >> vq->vq_nentries - 1; >> } else >> vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; >592c574 >< if (vq->vq_used_cons_idx == vq_htog16(vq, vq->vq_ring.used->idx)) >--- >> if (vq->vq_used_cons_idx == vq->vq_ring.used->idx) >599c581 >< desc_idx = (uint16_t) vq_htog32(vq, uep->id); >--- >> desc_idx = (uint16_t) uep->id; >601c583 >< *len = vq_htog32(vq, uep->len); >--- >> *len = uep->len; >659,665c641,647 >< vq->vq_name, vq->vq_nentries, vq->vq_free_cnt, virtqueue_nused(vq), >< vq->vq_queued_cnt, vq->vq_desc_head_idx, >< vq_htog16(vq, vq->vq_ring.avail->idx), vq->vq_used_cons_idx, >< vq_htog16(vq, vq->vq_ring.used->idx), >< vq_htog16(vq, vring_used_event(&vq->vq_ring)), >< vq_htog16(vq, vq->vq_ring.avail->flags), >< vq_htog16(vq, vq->vq_ring.used->flags)); >--- >> vq->vq_name, vq->vq_nentries, vq->vq_free_cnt, >> virtqueue_nused(vq), vq->vq_queued_cnt, vq->vq_desc_head_idx, >> vq->vq_ring.avail->idx, vq->vq_used_cons_idx, >> vq->vq_ring.used->idx, >> vring_used_event(&vq->vq_ring), >> vq->vq_ring.avail->flags, >> vq->vq_ring.used->flags); >682,683c664,665 >< vr->desc[i].next = vq_gtoh16(vq, i + 1); >< vr->desc[i].next = vq_gtoh16(vq, VQ_RING_DESC_CHAIN_END); >--- >> vr->desc[i].next = i + 1; >> vr->desc[i].next = VQ_RING_DESC_CHAIN_END; >689c671 >< uint16_t avail_idx, avail_ring_idx; >--- >> uint16_t avail_idx; >698,700c680,681 >< avail_idx = vq_htog16(vq, vq->vq_ring.avail->idx); >< avail_ring_idx = avail_idx & (vq->vq_nentries - 1); >< vq->vq_ring.avail->ring[avail_ring_idx] = vq_gtoh16(vq, desc_idx); >--- >> avail_idx = vq->vq_ring.avail->idx & (vq->vq_nentries - 1); >> vq->vq_ring.avail->ring[avail_idx] = desc_idx; >703c684 >< vq->vq_ring.avail->idx = vq_gtoh16(vq, avail_idx + 1); >--- >> vq->vq_ring.avail->idx++; >722c703 >< i++, idx = vq_htog16(vq, dp->next), seg++) { >--- >> i++, idx = dp->next, seg++) { >727,728c708,709 >< dp->addr = vq_gtoh64(vq, seg->ss_paddr); >< dp->len = vq_gtoh32(vq, seg->ss_len); >--- >> dp->addr = seg->ss_paddr; >> dp->len = seg->ss_len; >732c713 >< dp->flags |= vq_gtoh16(vq, VRING_DESC_F_NEXT); >--- >> dp->flags |= VRING_DESC_F_NEXT; >734c715 >< dp->flags |= vq_gtoh16(vq, VRING_DESC_F_WRITE); >--- >> dp->flags |= VRING_DESC_F_WRITE; >779,781c760,762 >< dp->addr = vq_gtoh64(vq, dxp->indirect_paddr); >< dp->len = vq_gtoh32(vq, needed * sizeof(struct vring_desc)); >< dp->flags = vq_gtoh16(vq, VRING_DESC_F_INDIRECT); >--- >> dp->addr = dxp->indirect_paddr; >> dp->len = needed * sizeof(struct vring_desc); >> dp->flags = VRING_DESC_F_INDIRECT; >786c767 >< vq->vq_desc_head_idx = vq_htog16(vq, dp->next); >--- >> vq->vq_desc_head_idx = dp->next; >804,810c785,788 >< if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) { >< vring_used_event(&vq->vq_ring) = >< vq_gtoh16(vq, vq->vq_used_cons_idx + ndesc); >< } else { >< vq->vq_ring.avail->flags &= >< vq_gtoh16(vq, ~VRING_AVAIL_F_NO_INTERRUPT); >< } >--- >> if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) >> vring_used_event(&vq->vq_ring) = vq->vq_used_cons_idx + ndesc; >> else >> vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; >828c806 >< uint16_t new_idx, prev_idx, event_idx, flags; >--- >> uint16_t new_idx, prev_idx, event_idx; >831c809 >< new_idx = vq_htog16(vq, vq->vq_ring.avail->idx); >--- >> new_idx = vq->vq_ring.avail->idx; >833c811 >< event_idx = vq_htog16(vq, vring_avail_event(&vq->vq_ring)); >--- >> event_idx = vring_avail_event(&vq->vq_ring); >838,839c816 >< flags = vq->vq_ring.used->flags; >< return ((flags & vq_gtoh16(vq, VRING_USED_F_NO_NOTIFY)) == 0); >--- >> return ((vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY) == 0); >846,847c823 >< VIRTIO_BUS_NOTIFY_VQ(vq->vq_dev, vq->vq_queue_index, >< vq->vq_notify_offset); >--- >> VIRTIO_BUS_NOTIFY_VQ(vq->vq_dev, vq->vq_queue_index); >866,870c842,845 >< if ((dp->flags & vq_gtoh16(vq, VRING_DESC_F_INDIRECT)) == 0) { >< while (dp->flags & vq_gtoh16(vq, VRING_DESC_F_NEXT)) { >< uint16_t next_idx = vq_htog16(vq, dp->next); >< VQ_RING_ASSERT_VALID_IDX(vq, next_idx); >< dp = &vq->vq_ring.desc[next_idx]; >--- >> if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) { >> while (dp->flags & VRING_DESC_F_NEXT) { >> VQ_RING_ASSERT_VALID_IDX(vq, dp->next); >> dp = &vq->vq_ring.desc[dp->next]; >883c858 >< dp->next = vq_gtoh16(vq, vq->vq_desc_head_idx); >--- >> dp->next = vq->vq_desc_head_idx; >Only in /usr/src/sys/dev/virtio: virtqueue.c.ori >diff -r /usr/src/sys/dev/virtio/virtqueue.h HD12/usr/src/sys/dev/virtio/virtqueue.h >28c28 >< * $FreeBSD$ >--- >> * $FreeBSD: releng/12.1/sys/dev/virtio/virtqueue.h 329602 2018-02-19 19:31:18Z bryanv $ >73,74c73,74 >< bus_size_t notify_offset, int align, vm_paddr_t highaddr, >< struct vq_alloc_info *info, struct virtqueue **vqp); >--- >> int align, vm_paddr_t highaddr, struct vq_alloc_info *info, >> struct virtqueue **vqp); >diff -r /usr/src/sys/modules/virtio/Makefile HD12/usr/src/sys/modules/virtio/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/Makefile 273515 2014-10-23 04:47:32Z bryanv $ >diff -r /usr/src/sys/modules/virtio/balloon/Makefile HD12/usr/src/sys/modules/virtio/balloon/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/balloon/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/block/Makefile HD12/usr/src/sys/modules/virtio/block/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/block/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/console/Makefile HD12/usr/src/sys/modules/virtio/console/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/console/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/network/Makefile HD12/usr/src/sys/modules/virtio/network/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/network/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/pci/Makefile HD12/usr/src/sys/modules/virtio/pci/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/pci/Makefile 314651 2017-03-04 10:10:17Z ngie $ >29,31c29,30 >< SRCS= virtio_pci.c virtio_pci_legacy.c virtio_pci_modern.c >< SRCS+= virtio_pci_if.c virtio_pci_if.h >< SRCS+= virtio_bus_if.h virtio_if.h >--- >> SRCS= virtio_pci.c >> SRCS+= virtio_bus_if.h virtio_if.h >diff -r /usr/src/sys/modules/virtio/random/Makefile HD12/usr/src/sys/modules/virtio/random/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/random/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/scsi/Makefile HD12/usr/src/sys/modules/virtio/scsi/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/scsi/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/modules/virtio/virtio/Makefile HD12/usr/src/sys/modules/virtio/virtio/Makefile >2c2 >< # $FreeBSD$ >--- >> # $FreeBSD: releng/12.1/sys/modules/virtio/virtio/Makefile 314651 2017-03-04 10:10:17Z ngie $ >diff -r /usr/src/sys/net/netmap_virt.h HD12/usr/src/sys/net/netmap_virt.h >47,48c47,48 >< #define PTNETMAP_PCI_DEVICE_ID 0xcccc /* memory device */ >< #define PTNETMAP_PCI_NETIF_ID 0xcccd /* ptnet network interface */ >--- >> #define PTNETMAP_PCI_DEVICE_ID 0x000c /* memory device */ >> #define PTNETMAP_PCI_NETIF_ID 0x000d /* ptnet network interface */ >diff -r /usr/src/sys/x86/include/specialreg.h HD12/usr/src/sys/x86/include/specialreg.h >450d449 >< #define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO 0x00000040
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 236922
:
203279
|
203281
|
206894
|
210551
|
210556
|
210660
|
210713
|
210723
|
210728
|
210734
|
210737
|
210783
| 210808 |
211258
|
212556
|
212558
|
212559
|
212560