diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 01:43:43 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-13 01:45:52 -0500 |
commit | d39a6785f40af658224bc3ff3d4c4a5a2f7c9eda (patch) | |
tree | 8882a1116659a2efcd512f226cafe77eab9b7fe4 /tools | |
parent | 55c2d7884e9a97c2f2d46d5818f783bf3dcc5314 (diff) |
tools/lguest: more documentation and checking of virtio 1.0 compliance.
This is from all the non-PCI parts of the spec.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lguest/lguest.c | 307 |
1 files changed, 293 insertions, 14 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 4c7c2aa66c89..bc444aff2333 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c | |||
@@ -170,6 +170,9 @@ struct device { | |||
170 | /* Is it operational */ | 170 | /* Is it operational */ |
171 | bool running; | 171 | bool running; |
172 | 172 | ||
173 | /* Has it written FEATURES_OK but not re-checked it? */ | ||
174 | bool wrote_features_ok; | ||
175 | |||
173 | /* PCI configuration */ | 176 | /* PCI configuration */ |
174 | union { | 177 | union { |
175 | struct pci_config config; | 178 | struct pci_config config; |
@@ -668,7 +671,26 @@ static void trigger_irq(struct virtqueue *vq) | |||
668 | return; | 671 | return; |
669 | vq->pending_used = 0; | 672 | vq->pending_used = 0; |
670 | 673 | ||
671 | /* If they don't want an interrupt, don't send one... */ | 674 | /* |
675 | * 2.4.7.1: | ||
676 | * | ||
677 | * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: | ||
678 | * The driver MUST set flags to 0 or 1. | ||
679 | */ | ||
680 | if (vq->vring.avail->flags > 1) | ||
681 | errx(1, "%s: avail->flags = %u\n", | ||
682 | vq->dev->name, vq->vring.avail->flags); | ||
683 | |||
684 | /* | ||
685 | * 2.4.7.2: | ||
686 | * | ||
687 | * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: | ||
688 | * | ||
689 | * - The device MUST ignore the used_event value. | ||
690 | * - After the device writes a descriptor index into the used ring: | ||
691 | * - If flags is 1, the device SHOULD NOT send an interrupt. | ||
692 | * - If flags is 0, the device MUST send an interrupt. | ||
693 | */ | ||
672 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { | 694 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { |
673 | return; | 695 | return; |
674 | } | 696 | } |
@@ -703,6 +725,14 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq, | |||
703 | struct vring_desc *desc; | 725 | struct vring_desc *desc; |
704 | u16 last_avail = lg_last_avail(vq); | 726 | u16 last_avail = lg_last_avail(vq); |
705 | 727 | ||
728 | /* | ||
729 | * 2.4.7.1: | ||
730 | * | ||
731 | * The driver MUST handle spurious interrupts from the device. | ||
732 | * | ||
733 | * That's why this is a while loop. | ||
734 | */ | ||
735 | |||
706 | /* There's nothing available? */ | 736 | /* There's nothing available? */ |
707 | while (last_avail == vq->vring.avail->idx) { | 737 | while (last_avail == vq->vring.avail->idx) { |
708 | u64 event; | 738 | u64 event; |
@@ -776,12 +806,62 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq, | |||
776 | * descriptor chain. | 806 | * descriptor chain. |
777 | */ | 807 | */ |
778 | if (desc[i].flags & VRING_DESC_F_INDIRECT) { | 808 | if (desc[i].flags & VRING_DESC_F_INDIRECT) { |
809 | /* 2.4.5.3.1: | ||
810 | * | ||
811 | * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT | ||
812 | * flag unless the VIRTIO_F_INDIRECT_DESC feature was | ||
813 | * negotiated. | ||
814 | */ | ||
815 | if (!(vq->dev->features_accepted & | ||
816 | (1<<VIRTIO_RING_F_INDIRECT_DESC))) | ||
817 | errx(1, "%s: vq indirect not negotiated", | ||
818 | vq->dev->name); | ||
819 | |||
820 | /* | ||
821 | * 2.4.5.3.1: | ||
822 | * | ||
823 | * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT | ||
824 | * flag within an indirect descriptor (ie. only one | ||
825 | * table per descriptor). | ||
826 | */ | ||
827 | if (desc != vq->vring.desc) | ||
828 | errx(1, "%s: Indirect within indirect", | ||
829 | vq->dev->name); | ||
830 | |||
831 | /* | ||
832 | * Proposed update VIRTIO-134 spells this out: | ||
833 | * | ||
834 | * A driver MUST NOT set both VIRTQ_DESC_F_INDIRECT | ||
835 | * and VIRTQ_DESC_F_NEXT in flags. | ||
836 | */ | ||
837 | if (desc[i].flags & VRING_DESC_F_NEXT) | ||
838 | errx(1, "%s: indirect and next together", | ||
839 | vq->dev->name); | ||
840 | |||
779 | if (desc[i].len % sizeof(struct vring_desc)) | 841 | if (desc[i].len % sizeof(struct vring_desc)) |
780 | errx(1, "Invalid size for indirect buffer table"); | 842 | errx(1, "Invalid size for indirect buffer table"); |
843 | /* | ||
844 | * 2.4.5.3.2: | ||
845 | * | ||
846 | * The device MUST ignore the write-only flag | ||
847 | * (flags&VIRTQ_DESC_F_WRITE) in the descriptor that | ||
848 | * refers to an indirect table. | ||
849 | * | ||
850 | * We ignore it here: :) | ||
851 | */ | ||
781 | 852 | ||
782 | max = desc[i].len / sizeof(struct vring_desc); | 853 | max = desc[i].len / sizeof(struct vring_desc); |
783 | desc = check_pointer(desc[i].addr, desc[i].len); | 854 | desc = check_pointer(desc[i].addr, desc[i].len); |
784 | i = 0; | 855 | i = 0; |
856 | |||
857 | /* 2.4.5.3.1: | ||
858 | * | ||
859 | * A driver MUST NOT create a descriptor chain longer | ||
860 | * than the Queue Size of the device. | ||
861 | */ | ||
862 | if (max > vq->pci_config.queue_size) | ||
863 | errx(1, "%s: indirect has too many entries", | ||
864 | vq->dev->name); | ||
785 | } | 865 | } |
786 | 866 | ||
787 | /* Grab the first descriptor, and check it's OK. */ | 867 | /* Grab the first descriptor, and check it's OK. */ |
@@ -1082,6 +1162,7 @@ static void reset_device(struct device *dev) | |||
1082 | } | 1162 | } |
1083 | } | 1163 | } |
1084 | dev->running = false; | 1164 | dev->running = false; |
1165 | dev->wrote_features_ok = false; | ||
1085 | 1166 | ||
1086 | /* Now we care if threads die. */ | 1167 | /* Now we care if threads die. */ |
1087 | signal(SIGCHLD, (void *)kill_launcher); | 1168 | signal(SIGCHLD, (void *)kill_launcher); |
@@ -1703,6 +1784,18 @@ static void check_virtqueue(struct device *d, struct virtqueue *vq) | |||
1703 | || vq->pci_config.queue_used_hi) | 1784 | || vq->pci_config.queue_used_hi) |
1704 | errx(1, "%s: invalid 64-bit queue address", d->name); | 1785 | errx(1, "%s: invalid 64-bit queue address", d->name); |
1705 | 1786 | ||
1787 | /* | ||
1788 | * 2.4.1: | ||
1789 | * | ||
1790 | * The driver MUST ensure that the physical address of the first byte | ||
1791 | * of each virtqueue part is a multiple of the specified alignment | ||
1792 | * value in the above table. | ||
1793 | */ | ||
1794 | if (vq->pci_config.queue_desc_lo % 16 | ||
1795 | || vq->pci_config.queue_avail_lo % 2 | ||
1796 | || vq->pci_config.queue_used_lo % 4) | ||
1797 | errx(1, "%s: invalid alignment in queue addresses", d->name); | ||
1798 | |||
1706 | /* Initialize the virtqueue and check they're all in range. */ | 1799 | /* Initialize the virtqueue and check they're all in range. */ |
1707 | vq->vring.num = vq->pci_config.queue_size; | 1800 | vq->vring.num = vq->pci_config.queue_size; |
1708 | vq->vring.desc = check_pointer(vq->pci_config.queue_desc_lo, | 1801 | vq->vring.desc = check_pointer(vq->pci_config.queue_desc_lo, |
@@ -1715,6 +1808,16 @@ static void check_virtqueue(struct device *d, struct virtqueue *vq) | |||
1715 | sizeof(*vq->vring.used) | 1808 | sizeof(*vq->vring.used) |
1716 | + (sizeof(vq->vring.used->ring[0]) | 1809 | + (sizeof(vq->vring.used->ring[0]) |
1717 | * vq->vring.num)); | 1810 | * vq->vring.num)); |
1811 | |||
1812 | /* | ||
1813 | * 2.4.9.1: | ||
1814 | * | ||
1815 | * The driver MUST initialize flags in the used ring to 0 | ||
1816 | * when allocating the used ring. | ||
1817 | */ | ||
1818 | if (vq->vring.used->flags != 0) | ||
1819 | errx(1, "%s: invalid initial used.flags %#x", | ||
1820 | d->name, vq->vring.used->flags); | ||
1718 | } | 1821 | } |
1719 | 1822 | ||
1720 | static void start_virtqueue(struct virtqueue *vq) | 1823 | static void start_virtqueue(struct virtqueue *vq) |
@@ -1768,12 +1871,12 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1768 | d->mmio->cfg.device_feature = (d->features >> 32); | 1871 | d->mmio->cfg.device_feature = (d->features >> 32); |
1769 | else | 1872 | else |
1770 | d->mmio->cfg.device_feature = 0; | 1873 | d->mmio->cfg.device_feature = 0; |
1771 | goto write_through32; | 1874 | goto feature_write_through32; |
1772 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): | 1875 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): |
1773 | if (val > 1) | 1876 | if (val > 1) |
1774 | errx(1, "%s: Unexpected driver select %u", | 1877 | errx(1, "%s: Unexpected driver select %u", |
1775 | d->name, val); | 1878 | d->name, val); |
1776 | goto write_through32; | 1879 | goto feature_write_through32; |
1777 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature): | 1880 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature): |
1778 | if (d->mmio->cfg.guest_feature_select == 0) { | 1881 | if (d->mmio->cfg.guest_feature_select == 0) { |
1779 | d->features_accepted &= ~((u64)0xFFFFFFFF); | 1882 | d->features_accepted &= ~((u64)0xFFFFFFFF); |
@@ -1783,11 +1886,19 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1783 | d->features_accepted &= 0xFFFFFFFF; | 1886 | d->features_accepted &= 0xFFFFFFFF; |
1784 | d->features_accepted |= ((u64)val) << 32; | 1887 | d->features_accepted |= ((u64)val) << 32; |
1785 | } | 1888 | } |
1889 | /* | ||
1890 | * 2.2.1: | ||
1891 | * | ||
1892 | * The driver MUST NOT accept a feature which the device did | ||
1893 | * not offer | ||
1894 | */ | ||
1786 | if (d->features_accepted & ~d->features) | 1895 | if (d->features_accepted & ~d->features) |
1787 | errx(1, "%s: over-accepted features %#llx of %#llx", | 1896 | errx(1, "%s: over-accepted features %#llx of %#llx", |
1788 | d->name, d->features_accepted, d->features); | 1897 | d->name, d->features_accepted, d->features); |
1789 | goto write_through32; | 1898 | goto feature_write_through32; |
1790 | case offsetof(struct virtio_pci_mmio, cfg.device_status): | 1899 | case offsetof(struct virtio_pci_mmio, cfg.device_status): { |
1900 | u8 prev; | ||
1901 | |||
1791 | verbose("%s: device status -> %#x\n", d->name, val); | 1902 | verbose("%s: device status -> %#x\n", d->name, val); |
1792 | /* | 1903 | /* |
1793 | * 4.1.4.3.1: | 1904 | * 4.1.4.3.1: |
@@ -1795,8 +1906,15 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1795 | * The device MUST reset when 0 is written to device_status, | 1906 | * The device MUST reset when 0 is written to device_status, |
1796 | * and present a 0 in device_status once that is done. | 1907 | * and present a 0 in device_status once that is done. |
1797 | */ | 1908 | */ |
1798 | if (val == 0) | 1909 | if (val == 0) { |
1799 | reset_device(d); | 1910 | reset_device(d); |
1911 | goto write_through8; | ||
1912 | } | ||
1913 | |||
1914 | /* 2.1.1: The driver MUST NOT clear a device status bit. */ | ||
1915 | if (d->mmio->cfg.device_status & ~val) | ||
1916 | errx(1, "%s: unset of device status bit %#x -> %#x", | ||
1917 | d->name, d->mmio->cfg.device_status, val); | ||
1800 | 1918 | ||
1801 | /* | 1919 | /* |
1802 | * 2.1.2: | 1920 | * 2.1.2: |
@@ -1808,7 +1926,67 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1808 | && !(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) | 1926 | && !(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) |
1809 | start_virtqueues(d); | 1927 | start_virtqueues(d); |
1810 | 1928 | ||
1929 | /* | ||
1930 | * 3.1.1: | ||
1931 | * | ||
1932 | * The driver MUST follow this sequence to initialize a device: | ||
1933 | * - Reset the device. | ||
1934 | * - Set the ACKNOWLEDGE status bit: the guest OS has | ||
1935 | * notice the device. | ||
1936 | * - Set the DRIVER status bit: the guest OS knows how | ||
1937 | * to drive the device. | ||
1938 | * - Read device feature bits, and write the subset | ||
1939 | * of feature bits understood by the OS and driver | ||
1940 | * to the device. During this step the driver MAY | ||
1941 | * read (but MUST NOT write) the device-specific | ||
1942 | * configuration fields to check that it can | ||
1943 | * support the device before accepting it. | ||
1944 | * - Set the FEATURES_OK status bit. The driver | ||
1945 | * MUST not accept new feature bits after this | ||
1946 | * step. | ||
1947 | * - Re-read device status to ensure the FEATURES_OK | ||
1948 | * bit is still set: otherwise, the device does | ||
1949 | * not support our subset of features and the | ||
1950 | * device is unusable. | ||
1951 | * - Perform device-specific setup, including | ||
1952 | * discovery of virtqueues for the device, | ||
1953 | * optional per-bus setup, reading and possibly | ||
1954 | * writing the device’s virtio configuration | ||
1955 | * space, and population of virtqueues. | ||
1956 | * - Set the DRIVER_OK status bit. At this point the | ||
1957 | * device is “live”. | ||
1958 | */ | ||
1959 | prev = 0; | ||
1960 | switch (val & ~d->mmio->cfg.device_status) { | ||
1961 | case VIRTIO_CONFIG_S_DRIVER_OK: | ||
1962 | prev |= VIRTIO_CONFIG_S_FEATURES_OK; /* fall thru */ | ||
1963 | case VIRTIO_CONFIG_S_FEATURES_OK: | ||
1964 | prev |= VIRTIO_CONFIG_S_DRIVER; /* fall thru */ | ||
1965 | case VIRTIO_CONFIG_S_DRIVER: | ||
1966 | prev |= VIRTIO_CONFIG_S_ACKNOWLEDGE; /* fall thru */ | ||
1967 | case VIRTIO_CONFIG_S_ACKNOWLEDGE: | ||
1968 | break; | ||
1969 | default: | ||
1970 | errx(1, "%s: unknown device status bit %#x -> %#x", | ||
1971 | d->name, d->mmio->cfg.device_status, val); | ||
1972 | } | ||
1973 | if (d->mmio->cfg.device_status != prev) | ||
1974 | errx(1, "%s: unexpected status transition %#x -> %#x", | ||
1975 | d->name, d->mmio->cfg.device_status, val); | ||
1976 | |||
1977 | /* If they just wrote FEATURES_OK, we make sure they read */ | ||
1978 | switch (val & ~d->mmio->cfg.device_status) { | ||
1979 | case VIRTIO_CONFIG_S_FEATURES_OK: | ||
1980 | d->wrote_features_ok = true; | ||
1981 | break; | ||
1982 | case VIRTIO_CONFIG_S_DRIVER_OK: | ||
1983 | if (d->wrote_features_ok) | ||
1984 | errx(1, "%s: did not re-read FEATURES_OK", | ||
1985 | d->name); | ||
1986 | break; | ||
1987 | } | ||
1811 | goto write_through8; | 1988 | goto write_through8; |
1989 | } | ||
1812 | case offsetof(struct virtio_pci_mmio, cfg.queue_select): | 1990 | case offsetof(struct virtio_pci_mmio, cfg.queue_select): |
1813 | vq = vq_by_num(d, val); | 1991 | vq = vq_by_num(d, val); |
1814 | /* | 1992 | /* |
@@ -1844,7 +2022,9 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1844 | case offsetof(struct virtio_pci_mmio, cfg.queue_msix_vector): | 2022 | case offsetof(struct virtio_pci_mmio, cfg.queue_msix_vector): |
1845 | errx(1, "%s: attempt to set MSIX vector to %u", | 2023 | errx(1, "%s: attempt to set MSIX vector to %u", |
1846 | d->name, val); | 2024 | d->name, val); |
1847 | case offsetof(struct virtio_pci_mmio, cfg.queue_enable): | 2025 | case offsetof(struct virtio_pci_mmio, cfg.queue_enable): { |
2026 | struct virtqueue *vq = vq_by_num(d, d->mmio->cfg.queue_select); | ||
2027 | |||
1848 | /* | 2028 | /* |
1849 | * 4.1.4.3.2: | 2029 | * 4.1.4.3.2: |
1850 | * | 2030 | * |
@@ -1852,17 +2032,27 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1852 | */ | 2032 | */ |
1853 | if (val != 1) | 2033 | if (val != 1) |
1854 | errx(1, "%s: setting queue_enable to %u", d->name, val); | 2034 | errx(1, "%s: setting queue_enable to %u", d->name, val); |
1855 | d->mmio->cfg.queue_enable = val; | 2035 | |
1856 | save_vq_config(&d->mmio->cfg, | ||
1857 | vq_by_num(d, d->mmio->cfg.queue_select)); | ||
1858 | /* | 2036 | /* |
1859 | * 4.1.4.3.2: | 2037 | * 3.1.1: |
1860 | * | 2038 | * |
1861 | * The driver MUST configure the other virtqueue fields before | 2039 | * 7. Perform device-specific setup, including discovery of |
1862 | * enabling the virtqueue with queue_enable. | 2040 | * virtqueues for the device, optional per-bus setup, |
2041 | * reading and possibly writing the device’s virtio | ||
2042 | * configuration space, and population of virtqueues. | ||
2043 | * 8. Set the DRIVER_OK status bit. | ||
2044 | * | ||
2045 | * All our devices require all virtqueues to be enabled, so | ||
2046 | * they should have done that before setting DRIVER_OK. | ||
1863 | */ | 2047 | */ |
1864 | check_virtqueue(d, vq_by_num(d, d->mmio->cfg.queue_select)); | 2048 | if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK) |
2049 | errx(1, "%s: enabling vs after DRIVER_OK", d->name); | ||
2050 | |||
2051 | d->mmio->cfg.queue_enable = val; | ||
2052 | save_vq_config(&d->mmio->cfg, vq); | ||
2053 | check_virtqueue(d, vq); | ||
1865 | goto write_through16; | 2054 | goto write_through16; |
2055 | } | ||
1866 | case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): | 2056 | case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): |
1867 | errx(1, "%s: attempt to write to queue_notify_off", d->name); | 2057 | errx(1, "%s: attempt to write to queue_notify_off", d->name); |
1868 | case offsetof(struct virtio_pci_mmio, cfg.queue_desc_lo): | 2058 | case offsetof(struct virtio_pci_mmio, cfg.queue_desc_lo): |
@@ -1880,6 +2070,26 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1880 | if (d->mmio->cfg.queue_enable) | 2070 | if (d->mmio->cfg.queue_enable) |
1881 | errx(1, "%s: changing queue on live device", | 2071 | errx(1, "%s: changing queue on live device", |
1882 | d->name); | 2072 | d->name); |
2073 | |||
2074 | /* | ||
2075 | * 3.1.1: | ||
2076 | * | ||
2077 | * The driver MUST follow this sequence to initialize a device: | ||
2078 | *... | ||
2079 | * 5. Set the FEATURES_OK status bit. The driver MUST not | ||
2080 | * accept new feature bits after this step. | ||
2081 | */ | ||
2082 | if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK)) | ||
2083 | errx(1, "%s: enabling vs before FEATURES_OK", d->name); | ||
2084 | |||
2085 | /* | ||
2086 | * 6. Re-read device status to ensure the FEATURES_OK bit is | ||
2087 | * still set... | ||
2088 | */ | ||
2089 | if (d->wrote_features_ok) | ||
2090 | errx(1, "%s: didn't re-read FEATURES_OK before setup", | ||
2091 | d->name); | ||
2092 | |||
1883 | goto write_through32; | 2093 | goto write_through32; |
1884 | case offsetof(struct virtio_pci_mmio, notify): | 2094 | case offsetof(struct virtio_pci_mmio, notify): |
1885 | vq = vq_by_num(d, val); | 2095 | vq = vq_by_num(d, val); |
@@ -1909,6 +2119,27 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
1909 | errx(1, "%s: Unexpected write to offset %u", d->name, off); | 2119 | errx(1, "%s: Unexpected write to offset %u", d->name, off); |
1910 | } | 2120 | } |
1911 | 2121 | ||
2122 | feature_write_through32: | ||
2123 | /* | ||
2124 | * 3.1.1: | ||
2125 | * | ||
2126 | * The driver MUST follow this sequence to initialize a device: | ||
2127 | *... | ||
2128 | * - Set the DRIVER status bit: the guest OS knows how | ||
2129 | * to drive the device. | ||
2130 | * - Read device feature bits, and write the subset | ||
2131 | * of feature bits understood by the OS and driver | ||
2132 | * to the device. | ||
2133 | *... | ||
2134 | * - Set the FEATURES_OK status bit. The driver MUST not | ||
2135 | * accept new feature bits after this step. | ||
2136 | */ | ||
2137 | if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) | ||
2138 | errx(1, "%s: feature write before VIRTIO_CONFIG_S_DRIVER", | ||
2139 | d->name); | ||
2140 | if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK) | ||
2141 | errx(1, "%s: feature write after VIRTIO_CONFIG_S_FEATURES_OK", | ||
2142 | d->name); | ||
1912 | 2143 | ||
1913 | /* | 2144 | /* |
1914 | * 4.1.3.1: | 2145 | * 4.1.3.1: |
@@ -1951,12 +2182,29 @@ static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) | |||
1951 | case offsetof(struct virtio_pci_mmio, cfg.device_feature): | 2182 | case offsetof(struct virtio_pci_mmio, cfg.device_feature): |
1952 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): | 2183 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): |
1953 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature): | 2184 | case offsetof(struct virtio_pci_mmio, cfg.guest_feature): |
2185 | /* | ||
2186 | * 3.1.1: | ||
2187 | * | ||
2188 | * The driver MUST follow this sequence to initialize a device: | ||
2189 | *... | ||
2190 | * - Set the DRIVER status bit: the guest OS knows how | ||
2191 | * to drive the device. | ||
2192 | * - Read device feature bits, and write the subset | ||
2193 | * of feature bits understood by the OS and driver | ||
2194 | * to the device. | ||
2195 | */ | ||
2196 | if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) | ||
2197 | errx(1, "%s: feature read before VIRTIO_CONFIG_S_DRIVER", | ||
2198 | d->name); | ||
1954 | goto read_through32; | 2199 | goto read_through32; |
1955 | case offsetof(struct virtio_pci_mmio, cfg.msix_config): | 2200 | case offsetof(struct virtio_pci_mmio, cfg.msix_config): |
1956 | errx(1, "%s: read of msix_config", d->name); | 2201 | errx(1, "%s: read of msix_config", d->name); |
1957 | case offsetof(struct virtio_pci_mmio, cfg.num_queues): | 2202 | case offsetof(struct virtio_pci_mmio, cfg.num_queues): |
1958 | goto read_through16; | 2203 | goto read_through16; |
1959 | case offsetof(struct virtio_pci_mmio, cfg.device_status): | 2204 | case offsetof(struct virtio_pci_mmio, cfg.device_status): |
2205 | /* As they did read, any write of FEATURES_OK is now fine. */ | ||
2206 | d->wrote_features_ok = false; | ||
2207 | goto read_through8; | ||
1960 | case offsetof(struct virtio_pci_mmio, cfg.config_generation): | 2208 | case offsetof(struct virtio_pci_mmio, cfg.config_generation): |
1961 | /* | 2209 | /* |
1962 | * 4.1.4.3.1: | 2210 | * 4.1.4.3.1: |
@@ -1971,6 +2219,15 @@ static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) | |||
1971 | */ | 2219 | */ |
1972 | goto read_through8; | 2220 | goto read_through8; |
1973 | case offsetof(struct virtio_pci_mmio, notify): | 2221 | case offsetof(struct virtio_pci_mmio, notify): |
2222 | /* | ||
2223 | * 3.1.1: | ||
2224 | * | ||
2225 | * The driver MUST NOT notify the device before setting | ||
2226 | * DRIVER_OK. | ||
2227 | */ | ||
2228 | if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) | ||
2229 | errx(1, "%s: notify before VIRTIO_CONFIG_S_DRIVER_OK", | ||
2230 | d->name); | ||
1974 | goto read_through16; | 2231 | goto read_through16; |
1975 | case offsetof(struct virtio_pci_mmio, isr): | 2232 | case offsetof(struct virtio_pci_mmio, isr): |
1976 | if (mask != 0xFF) | 2233 | if (mask != 0xFF) |
@@ -1992,6 +2249,23 @@ static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) | |||
1992 | if (off > d->mmio_size - 4) | 2249 | if (off > d->mmio_size - 4) |
1993 | errx(1, "%s: read past end (%#x)", | 2250 | errx(1, "%s: read past end (%#x)", |
1994 | d->name, getreg(eip)); | 2251 | d->name, getreg(eip)); |
2252 | |||
2253 | /* | ||
2254 | * 3.1.1: | ||
2255 | * The driver MUST follow this sequence to initialize a device: | ||
2256 | *... | ||
2257 | * 3. Set the DRIVER status bit: the guest OS knows how to | ||
2258 | * drive the device. | ||
2259 | * 4. Read device feature bits, and write the subset of | ||
2260 | * feature bits understood by the OS and driver to the | ||
2261 | * device. During this step the driver MAY read (but MUST NOT | ||
2262 | * write) the device-specific configuration fields to check | ||
2263 | * that it can support the device before accepting it. | ||
2264 | */ | ||
2265 | if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) | ||
2266 | errx(1, "%s: config read before VIRTIO_CONFIG_S_DRIVER", | ||
2267 | d->name); | ||
2268 | |||
1995 | if (mask == 0xFFFFFFFF) | 2269 | if (mask == 0xFFFFFFFF) |
1996 | goto read_through32; | 2270 | goto read_through32; |
1997 | else if (mask == 0xFFFF) | 2271 | else if (mask == 0xFFFF) |
@@ -2200,6 +2474,10 @@ static void init_pci_config(struct pci_config *pci, u16 type, | |||
2200 | * | 2474 | * |
2201 | * The device MUST either present notify_off_multiplier as an even | 2475 | * The device MUST either present notify_off_multiplier as an even |
2202 | * power of 2, or present notify_off_multiplier as 0. | 2476 | * power of 2, or present notify_off_multiplier as 0. |
2477 | * | ||
2478 | * 2.1.2: | ||
2479 | * | ||
2480 | * The device MUST initialize device status to 0 upon reset. | ||
2203 | */ | 2481 | */ |
2204 | memset(pci, 0, sizeof(*pci)); | 2482 | memset(pci, 0, sizeof(*pci)); |
2205 | 2483 | ||
@@ -2340,6 +2618,7 @@ static struct device *new_pci_device(const char *name, u16 type, | |||
2340 | dev->name = name; | 2618 | dev->name = name; |
2341 | dev->vq = NULL; | 2619 | dev->vq = NULL; |
2342 | dev->running = false; | 2620 | dev->running = false; |
2621 | dev->wrote_features_ok = false; | ||
2343 | dev->mmio_size = sizeof(struct virtio_pci_mmio); | 2622 | dev->mmio_size = sizeof(struct virtio_pci_mmio); |
2344 | dev->mmio = calloc(1, dev->mmio_size); | 2623 | dev->mmio = calloc(1, dev->mmio_size); |
2345 | dev->features = (u64)1 << VIRTIO_F_VERSION_1; | 2624 | dev->features = (u64)1 << VIRTIO_F_VERSION_1; |