diff options
| -rw-r--r-- | tools/lguest/lguest.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c index 10a72b810127..80dc6346030e 100644 --- a/tools/lguest/lguest.c +++ b/tools/lguest/lguest.c | |||
| @@ -1211,7 +1211,12 @@ static bool valid_bar_access(struct device *d, | |||
| 1211 | && cfg_access->cap.length != 4) | 1211 | && cfg_access->cap.length != 4) |
| 1212 | return false; | 1212 | return false; |
| 1213 | 1213 | ||
| 1214 | /* Offset must be multiple of length */ | 1214 | /* |
| 1215 | * 4.1.4.7.2: | ||
| 1216 | * | ||
| 1217 | * The driver MUST NOT write a cap.offset which is not a multiple of | ||
| 1218 | * cap.length (ie. all accesses MUST be aligned). | ||
| 1219 | */ | ||
| 1215 | if (cfg_access->cap.offset % cfg_access->cap.length != 0) | 1220 | if (cfg_access->cap.offset % cfg_access->cap.length != 0) |
| 1216 | return false; | 1221 | return false; |
| 1217 | 1222 | ||
| @@ -1342,7 +1347,13 @@ static bool pci_data_iowrite(u16 port, u32 mask, u32 val) | |||
| 1342 | return true; | 1347 | return true; |
| 1343 | } | 1348 | } |
| 1344 | 1349 | ||
| 1345 | /* Complain about other writes. */ | 1350 | /* |
| 1351 | * 4.1.4.1: | ||
| 1352 | * | ||
| 1353 | * The driver MUST NOT write into any field of the capability | ||
| 1354 | * structure, with the exception of those with cap_type | ||
| 1355 | * VIRTIO_PCI_CAP_PCI_CFG... | ||
| 1356 | */ | ||
| 1346 | return false; | 1357 | return false; |
| 1347 | } | 1358 | } |
| 1348 | 1359 | ||
| @@ -1789,6 +1800,12 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
| 1789 | restore_vq_config(&d->mmio->cfg, vq); | 1800 | restore_vq_config(&d->mmio->cfg, vq); |
| 1790 | goto write_through16; | 1801 | goto write_through16; |
| 1791 | case offsetof(struct virtio_pci_mmio, cfg.queue_size): | 1802 | case offsetof(struct virtio_pci_mmio, cfg.queue_size): |
| 1803 | /* | ||
| 1804 | * 4.1.4.3.2: | ||
| 1805 | * | ||
| 1806 | * The driver MUST NOT write a value which is not a power of 2 | ||
| 1807 | * to queue_size. | ||
| 1808 | */ | ||
| 1792 | if (val & (val-1)) | 1809 | if (val & (val-1)) |
| 1793 | errx(1, "%s: invalid queue size %u\n", d->name, val); | 1810 | errx(1, "%s: invalid queue size %u\n", d->name, val); |
| 1794 | if (d->mmio->cfg.queue_enable) | 1811 | if (d->mmio->cfg.queue_enable) |
| @@ -1799,11 +1816,22 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
| 1799 | errx(1, "%s: attempt to set MSIX vector to %u", | 1816 | errx(1, "%s: attempt to set MSIX vector to %u", |
| 1800 | d->name, val); | 1817 | d->name, val); |
| 1801 | case offsetof(struct virtio_pci_mmio, cfg.queue_enable): | 1818 | case offsetof(struct virtio_pci_mmio, cfg.queue_enable): |
| 1819 | /* | ||
| 1820 | * 4.1.4.3.2: | ||
| 1821 | * | ||
| 1822 | * The driver MUST NOT write a 0 to queue_enable. | ||
| 1823 | */ | ||
| 1802 | if (val != 1) | 1824 | if (val != 1) |
| 1803 | errx(1, "%s: setting queue_enable to %u", d->name, val); | 1825 | errx(1, "%s: setting queue_enable to %u", d->name, val); |
| 1804 | d->mmio->cfg.queue_enable = val; | 1826 | d->mmio->cfg.queue_enable = val; |
| 1805 | save_vq_config(&d->mmio->cfg, | 1827 | save_vq_config(&d->mmio->cfg, |
| 1806 | vq_by_num(d, d->mmio->cfg.queue_select)); | 1828 | vq_by_num(d, d->mmio->cfg.queue_select)); |
| 1829 | /* | ||
| 1830 | * 4.1.4.3.2: | ||
| 1831 | * | ||
| 1832 | * The driver MUST configure the other virtqueue fields before | ||
| 1833 | * enabling the virtqueue with queue_enable. | ||
| 1834 | */ | ||
| 1807 | enable_virtqueue(d, vq_by_num(d, d->mmio->cfg.queue_select)); | 1835 | enable_virtqueue(d, vq_by_num(d, d->mmio->cfg.queue_select)); |
| 1808 | goto write_through16; | 1836 | goto write_through16; |
| 1809 | case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): | 1837 | case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): |
| @@ -1814,6 +1842,12 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
| 1814 | case offsetof(struct virtio_pci_mmio, cfg.queue_avail_hi): | 1842 | case offsetof(struct virtio_pci_mmio, cfg.queue_avail_hi): |
| 1815 | case offsetof(struct virtio_pci_mmio, cfg.queue_used_lo): | 1843 | case offsetof(struct virtio_pci_mmio, cfg.queue_used_lo): |
| 1816 | case offsetof(struct virtio_pci_mmio, cfg.queue_used_hi): | 1844 | case offsetof(struct virtio_pci_mmio, cfg.queue_used_hi): |
| 1845 | /* | ||
| 1846 | * 4.1.4.3.2: | ||
| 1847 | * | ||
| 1848 | * The driver MUST configure the other virtqueue fields before | ||
| 1849 | * enabling the virtqueue with queue_enable. | ||
| 1850 | */ | ||
| 1817 | if (d->mmio->cfg.queue_enable) | 1851 | if (d->mmio->cfg.queue_enable) |
| 1818 | errx(1, "%s: changing queue on live device", | 1852 | errx(1, "%s: changing queue on live device", |
| 1819 | d->name); | 1853 | d->name); |
| @@ -1837,9 +1871,23 @@ static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) | |||
| 1837 | } | 1871 | } |
| 1838 | /* Fall through... */ | 1872 | /* Fall through... */ |
| 1839 | default: | 1873 | default: |
| 1874 | /* | ||
| 1875 | * 4.1.4.3.2: | ||
| 1876 | * | ||
| 1877 | * The driver MUST NOT write to device_feature, num_queues, | ||
| 1878 | * config_generation or queue_notify_off. | ||
| 1879 | */ | ||
| 1840 | errx(1, "%s: Unexpected write to offset %u", d->name, off); | 1880 | errx(1, "%s: Unexpected write to offset %u", d->name, off); |
| 1841 | } | 1881 | } |
| 1842 | 1882 | ||
| 1883 | |||
| 1884 | /* | ||
| 1885 | * 4.1.3.1: | ||
| 1886 | * | ||
| 1887 | * The driver MUST access each field using the “natural” access | ||
| 1888 | * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for | ||
| 1889 | * 16-bit fields and 8-bit accesses for 8-bit fields. | ||
| 1890 | */ | ||
| 1843 | write_through32: | 1891 | write_through32: |
| 1844 | if (mask != 0xFFFFFFFF) { | 1892 | if (mask != 0xFFFFFFFF) { |
| 1845 | errx(1, "%s: non-32-bit write to offset %u (%#x)", | 1893 | errx(1, "%s: non-32-bit write to offset %u (%#x)", |
| @@ -1923,6 +1971,13 @@ static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) | |||
| 1923 | goto read_through8; | 1971 | goto read_through8; |
| 1924 | } | 1972 | } |
| 1925 | 1973 | ||
| 1974 | /* | ||
| 1975 | * 4.1.3.1: | ||
| 1976 | * | ||
| 1977 | * The driver MUST access each field using the “natural” access | ||
| 1978 | * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for | ||
| 1979 | * 16-bit fields and 8-bit accesses for 8-bit fields. | ||
| 1980 | */ | ||
| 1926 | read_through32: | 1981 | read_through32: |
| 1927 | if (mask != 0xFFFFFFFF) | 1982 | if (mask != 0xFFFFFFFF) |
| 1928 | errx(1, "%s: non-32-bit read to offset %u (%#x)", | 1983 | errx(1, "%s: non-32-bit read to offset %u (%#x)", |
