qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

virtio-mmio.c (27946B)


      1 /*
      2  * Virtio MMIO bindings
      3  *
      4  * Copyright (c) 2011 Linaro Limited
      5  *
      6  * Author:
      7  *  Peter Maydell <peter.maydell@linaro.org>
      8  *
      9  * This program is free software; you can redistribute it and/or modify
     10  * it under the terms of the GNU General Public License; either version 2
     11  * of the License, or (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License along
     19  * with this program; if not, see <http://www.gnu.org/licenses/>.
     20  */
     21 
     22 #include "qemu/osdep.h"
     23 #include "standard-headers/linux/virtio_mmio.h"
     24 #include "hw/irq.h"
     25 #include "hw/qdev-properties.h"
     26 #include "hw/sysbus.h"
     27 #include "hw/virtio/virtio.h"
     28 #include "migration/qemu-file-types.h"
     29 #include "qemu/host-utils.h"
     30 #include "qemu/module.h"
     31 #include "sysemu/kvm.h"
     32 #include "sysemu/replay.h"
     33 #include "hw/virtio/virtio-mmio.h"
     34 #include "qemu/error-report.h"
     35 #include "qemu/log.h"
     36 #include "trace.h"
     37 
     38 static bool virtio_mmio_ioeventfd_enabled(DeviceState *d)
     39 {
     40     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
     41 
     42     return (proxy->flags & VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD) != 0;
     43 }
     44 
     45 static int virtio_mmio_ioeventfd_assign(DeviceState *d,
     46                                         EventNotifier *notifier,
     47                                         int n, bool assign)
     48 {
     49     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
     50 
     51     if (assign) {
     52         memory_region_add_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUE_NOTIFY, 4,
     53                                   true, n, notifier);
     54     } else {
     55         memory_region_del_eventfd(&proxy->iomem, VIRTIO_MMIO_QUEUE_NOTIFY, 4,
     56                                   true, n, notifier);
     57     }
     58     return 0;
     59 }
     60 
     61 static void virtio_mmio_start_ioeventfd(VirtIOMMIOProxy *proxy)
     62 {
     63     virtio_bus_start_ioeventfd(&proxy->bus);
     64 }
     65 
     66 static void virtio_mmio_stop_ioeventfd(VirtIOMMIOProxy *proxy)
     67 {
     68     virtio_bus_stop_ioeventfd(&proxy->bus);
     69 }
     70 
     71 static void virtio_mmio_soft_reset(VirtIOMMIOProxy *proxy)
     72 {
     73     int i;
     74 
     75     virtio_bus_reset(&proxy->bus);
     76 
     77     if (!proxy->legacy) {
     78         for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
     79             proxy->vqs[i].enabled = 0;
     80         }
     81     }
     82 }
     83 
     84 static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
     85 {
     86     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
     87     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
     88 
     89     trace_virtio_mmio_read(offset);
     90 
     91     if (!vdev) {
     92         /* If no backend is present, we treat most registers as
     93          * read-as-zero, except for the magic number, version and
     94          * vendor ID. This is not strictly sanctioned by the virtio
     95          * spec, but it allows us to provide transports with no backend
     96          * plugged in which don't confuse Linux's virtio code: the
     97          * probe won't complain about the bad magic number, but the
     98          * device ID of zero means no backend will claim it.
     99          */
    100         switch (offset) {
    101         case VIRTIO_MMIO_MAGIC_VALUE:
    102             return VIRT_MAGIC;
    103         case VIRTIO_MMIO_VERSION:
    104             if (proxy->legacy) {
    105                 return VIRT_VERSION_LEGACY;
    106             } else {
    107                 return VIRT_VERSION;
    108             }
    109         case VIRTIO_MMIO_VENDOR_ID:
    110             return VIRT_VENDOR;
    111         default:
    112             return 0;
    113         }
    114     }
    115 
    116     if (offset >= VIRTIO_MMIO_CONFIG) {
    117         offset -= VIRTIO_MMIO_CONFIG;
    118         if (proxy->legacy) {
    119             switch (size) {
    120             case 1:
    121                 return virtio_config_readb(vdev, offset);
    122             case 2:
    123                 return virtio_config_readw(vdev, offset);
    124             case 4:
    125                 return virtio_config_readl(vdev, offset);
    126             default:
    127                 abort();
    128             }
    129         } else {
    130             switch (size) {
    131             case 1:
    132                 return virtio_config_modern_readb(vdev, offset);
    133             case 2:
    134                 return virtio_config_modern_readw(vdev, offset);
    135             case 4:
    136                 return virtio_config_modern_readl(vdev, offset);
    137             default:
    138                 abort();
    139             }
    140         }
    141     }
    142     if (size != 4) {
    143         qemu_log_mask(LOG_GUEST_ERROR,
    144                       "%s: wrong size access to register!\n",
    145                       __func__);
    146         return 0;
    147     }
    148     switch (offset) {
    149     case VIRTIO_MMIO_MAGIC_VALUE:
    150         return VIRT_MAGIC;
    151     case VIRTIO_MMIO_VERSION:
    152         if (proxy->legacy) {
    153             return VIRT_VERSION_LEGACY;
    154         } else {
    155             return VIRT_VERSION;
    156         }
    157     case VIRTIO_MMIO_DEVICE_ID:
    158         return vdev->device_id;
    159     case VIRTIO_MMIO_VENDOR_ID:
    160         return VIRT_VENDOR;
    161     case VIRTIO_MMIO_DEVICE_FEATURES:
    162         if (proxy->legacy) {
    163             if (proxy->host_features_sel) {
    164                 return 0;
    165             } else {
    166                 return vdev->host_features;
    167             }
    168         } else {
    169             VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
    170             return (vdev->host_features & ~vdc->legacy_features)
    171                 >> (32 * proxy->host_features_sel);
    172         }
    173     case VIRTIO_MMIO_QUEUE_NUM_MAX:
    174         if (!virtio_queue_get_num(vdev, vdev->queue_sel)) {
    175             return 0;
    176         }
    177         return VIRTQUEUE_MAX_SIZE;
    178     case VIRTIO_MMIO_QUEUE_PFN:
    179         if (!proxy->legacy) {
    180             qemu_log_mask(LOG_GUEST_ERROR,
    181                           "%s: read from legacy register (0x%"
    182                           HWADDR_PRIx ") in non-legacy mode\n",
    183                           __func__, offset);
    184             return 0;
    185         }
    186         return virtio_queue_get_addr(vdev, vdev->queue_sel)
    187             >> proxy->guest_page_shift;
    188     case VIRTIO_MMIO_QUEUE_READY:
    189         if (proxy->legacy) {
    190             qemu_log_mask(LOG_GUEST_ERROR,
    191                           "%s: read from non-legacy register (0x%"
    192                           HWADDR_PRIx ") in legacy mode\n",
    193                           __func__, offset);
    194             return 0;
    195         }
    196         return proxy->vqs[vdev->queue_sel].enabled;
    197     case VIRTIO_MMIO_INTERRUPT_STATUS:
    198         return qatomic_read(&vdev->isr);
    199     case VIRTIO_MMIO_STATUS:
    200         return vdev->status;
    201     case VIRTIO_MMIO_CONFIG_GENERATION:
    202         if (proxy->legacy) {
    203             qemu_log_mask(LOG_GUEST_ERROR,
    204                           "%s: read from non-legacy register (0x%"
    205                           HWADDR_PRIx ") in legacy mode\n",
    206                           __func__, offset);
    207             return 0;
    208         }
    209         return vdev->generation;
    210    case VIRTIO_MMIO_SHM_LEN_LOW:
    211    case VIRTIO_MMIO_SHM_LEN_HIGH:
    212         /*
    213          * VIRTIO_MMIO_SHM_SEL is unimplemented
    214          * according to the linux driver, if region length is -1
    215          * the shared memory doesn't exist
    216          */
    217         return -1;
    218     case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
    219     case VIRTIO_MMIO_DRIVER_FEATURES:
    220     case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
    221     case VIRTIO_MMIO_GUEST_PAGE_SIZE:
    222     case VIRTIO_MMIO_QUEUE_SEL:
    223     case VIRTIO_MMIO_QUEUE_NUM:
    224     case VIRTIO_MMIO_QUEUE_ALIGN:
    225     case VIRTIO_MMIO_QUEUE_NOTIFY:
    226     case VIRTIO_MMIO_INTERRUPT_ACK:
    227     case VIRTIO_MMIO_QUEUE_DESC_LOW:
    228     case VIRTIO_MMIO_QUEUE_DESC_HIGH:
    229     case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
    230     case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
    231     case VIRTIO_MMIO_QUEUE_USED_LOW:
    232     case VIRTIO_MMIO_QUEUE_USED_HIGH:
    233         qemu_log_mask(LOG_GUEST_ERROR,
    234                       "%s: read of write-only register (0x%" HWADDR_PRIx ")\n",
    235                       __func__, offset);
    236         return 0;
    237     default:
    238         qemu_log_mask(LOG_GUEST_ERROR,
    239                       "%s: bad register offset (0x%" HWADDR_PRIx ")\n",
    240                       __func__, offset);
    241         return 0;
    242     }
    243     return 0;
    244 }
    245 
    246 static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
    247                               unsigned size)
    248 {
    249     VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
    250     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    251 
    252     trace_virtio_mmio_write_offset(offset, value);
    253 
    254     if (!vdev) {
    255         /* If no backend is present, we just make all registers
    256          * write-ignored. This allows us to provide transports with
    257          * no backend plugged in.
    258          */
    259         return;
    260     }
    261 
    262     if (offset >= VIRTIO_MMIO_CONFIG) {
    263         offset -= VIRTIO_MMIO_CONFIG;
    264         if (proxy->legacy) {
    265             switch (size) {
    266             case 1:
    267                 virtio_config_writeb(vdev, offset, value);
    268                 break;
    269             case 2:
    270                 virtio_config_writew(vdev, offset, value);
    271                 break;
    272             case 4:
    273                 virtio_config_writel(vdev, offset, value);
    274                 break;
    275             default:
    276                 abort();
    277             }
    278             return;
    279         } else {
    280             switch (size) {
    281             case 1:
    282                 virtio_config_modern_writeb(vdev, offset, value);
    283                 break;
    284             case 2:
    285                 virtio_config_modern_writew(vdev, offset, value);
    286                 break;
    287             case 4:
    288                 virtio_config_modern_writel(vdev, offset, value);
    289                 break;
    290             default:
    291                 abort();
    292             }
    293             return;
    294         }
    295     }
    296     if (size != 4) {
    297         qemu_log_mask(LOG_GUEST_ERROR,
    298                       "%s: wrong size access to register!\n",
    299                       __func__);
    300         return;
    301     }
    302     switch (offset) {
    303     case VIRTIO_MMIO_DEVICE_FEATURES_SEL:
    304         if (value) {
    305             proxy->host_features_sel = 1;
    306         } else {
    307             proxy->host_features_sel = 0;
    308         }
    309         break;
    310     case VIRTIO_MMIO_DRIVER_FEATURES:
    311         if (proxy->legacy) {
    312             if (proxy->guest_features_sel) {
    313                 qemu_log_mask(LOG_GUEST_ERROR,
    314                               "%s: attempt to write guest features with "
    315                               "guest_features_sel > 0 in legacy mode\n",
    316                               __func__);
    317             } else {
    318                 virtio_set_features(vdev, value);
    319             }
    320         } else {
    321             proxy->guest_features[proxy->guest_features_sel] = value;
    322         }
    323         break;
    324     case VIRTIO_MMIO_DRIVER_FEATURES_SEL:
    325         if (value) {
    326             proxy->guest_features_sel = 1;
    327         } else {
    328             proxy->guest_features_sel = 0;
    329         }
    330         break;
    331     case VIRTIO_MMIO_GUEST_PAGE_SIZE:
    332         if (!proxy->legacy) {
    333             qemu_log_mask(LOG_GUEST_ERROR,
    334                           "%s: write to legacy register (0x%"
    335                           HWADDR_PRIx ") in non-legacy mode\n",
    336                           __func__, offset);
    337             return;
    338         }
    339         proxy->guest_page_shift = ctz32(value);
    340         if (proxy->guest_page_shift > 31) {
    341             proxy->guest_page_shift = 0;
    342         }
    343         trace_virtio_mmio_guest_page(value, proxy->guest_page_shift);
    344         break;
    345     case VIRTIO_MMIO_QUEUE_SEL:
    346         if (value < VIRTIO_QUEUE_MAX) {
    347             vdev->queue_sel = value;
    348         }
    349         break;
    350     case VIRTIO_MMIO_QUEUE_NUM:
    351         trace_virtio_mmio_queue_write(value, VIRTQUEUE_MAX_SIZE);
    352         virtio_queue_set_num(vdev, vdev->queue_sel, value);
    353 
    354         if (proxy->legacy) {
    355             virtio_queue_update_rings(vdev, vdev->queue_sel);
    356         } else {
    357             proxy->vqs[vdev->queue_sel].num = value;
    358         }
    359         break;
    360     case VIRTIO_MMIO_QUEUE_ALIGN:
    361         if (!proxy->legacy) {
    362             qemu_log_mask(LOG_GUEST_ERROR,
    363                           "%s: write to legacy register (0x%"
    364                           HWADDR_PRIx ") in non-legacy mode\n",
    365                           __func__, offset);
    366             return;
    367         }
    368         virtio_queue_set_align(vdev, vdev->queue_sel, value);
    369         break;
    370     case VIRTIO_MMIO_QUEUE_PFN:
    371         if (!proxy->legacy) {
    372             qemu_log_mask(LOG_GUEST_ERROR,
    373                           "%s: write to legacy register (0x%"
    374                           HWADDR_PRIx ") in non-legacy mode\n",
    375                           __func__, offset);
    376             return;
    377         }
    378         if (value == 0) {
    379             virtio_mmio_soft_reset(proxy);
    380         } else {
    381             virtio_queue_set_addr(vdev, vdev->queue_sel,
    382                                   value << proxy->guest_page_shift);
    383         }
    384         break;
    385     case VIRTIO_MMIO_QUEUE_READY:
    386         if (proxy->legacy) {
    387             qemu_log_mask(LOG_GUEST_ERROR,
    388                           "%s: write to non-legacy register (0x%"
    389                           HWADDR_PRIx ") in legacy mode\n",
    390                           __func__, offset);
    391             return;
    392         }
    393         if (value) {
    394             virtio_queue_set_num(vdev, vdev->queue_sel,
    395                                  proxy->vqs[vdev->queue_sel].num);
    396             virtio_queue_set_rings(vdev, vdev->queue_sel,
    397                 ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |
    398                 proxy->vqs[vdev->queue_sel].desc[0],
    399                 ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |
    400                 proxy->vqs[vdev->queue_sel].avail[0],
    401                 ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
    402                 proxy->vqs[vdev->queue_sel].used[0]);
    403             proxy->vqs[vdev->queue_sel].enabled = 1;
    404         } else {
    405             proxy->vqs[vdev->queue_sel].enabled = 0;
    406         }
    407         break;
    408     case VIRTIO_MMIO_QUEUE_NOTIFY:
    409         if (value < VIRTIO_QUEUE_MAX) {
    410             virtio_queue_notify(vdev, value);
    411         }
    412         break;
    413     case VIRTIO_MMIO_INTERRUPT_ACK:
    414         qatomic_and(&vdev->isr, ~value);
    415         virtio_update_irq(vdev);
    416         break;
    417     case VIRTIO_MMIO_STATUS:
    418         if (!(value & VIRTIO_CONFIG_S_DRIVER_OK)) {
    419             virtio_mmio_stop_ioeventfd(proxy);
    420         }
    421 
    422         if (!proxy->legacy && (value & VIRTIO_CONFIG_S_FEATURES_OK)) {
    423             virtio_set_features(vdev,
    424                                 ((uint64_t)proxy->guest_features[1]) << 32 |
    425                                 proxy->guest_features[0]);
    426         }
    427 
    428         virtio_set_status(vdev, value & 0xff);
    429 
    430         if (value & VIRTIO_CONFIG_S_DRIVER_OK) {
    431             virtio_mmio_start_ioeventfd(proxy);
    432         }
    433 
    434         if (vdev->status == 0) {
    435             virtio_mmio_soft_reset(proxy);
    436         }
    437         break;
    438     case VIRTIO_MMIO_QUEUE_DESC_LOW:
    439         if (proxy->legacy) {
    440             qemu_log_mask(LOG_GUEST_ERROR,
    441                           "%s: write to non-legacy register (0x%"
    442                           HWADDR_PRIx ") in legacy mode\n",
    443                           __func__, offset);
    444             return;
    445         }
    446         proxy->vqs[vdev->queue_sel].desc[0] = value;
    447         break;
    448     case VIRTIO_MMIO_QUEUE_DESC_HIGH:
    449         if (proxy->legacy) {
    450             qemu_log_mask(LOG_GUEST_ERROR,
    451                           "%s: write to non-legacy register (0x%"
    452                           HWADDR_PRIx ") in legacy mode\n",
    453                           __func__, offset);
    454             return;
    455         }
    456         proxy->vqs[vdev->queue_sel].desc[1] = value;
    457         break;
    458     case VIRTIO_MMIO_QUEUE_AVAIL_LOW:
    459         if (proxy->legacy) {
    460             qemu_log_mask(LOG_GUEST_ERROR,
    461                           "%s: write to non-legacy register (0x%"
    462                           HWADDR_PRIx ") in legacy mode\n",
    463                           __func__, offset);
    464             return;
    465         }
    466         proxy->vqs[vdev->queue_sel].avail[0] = value;
    467         break;
    468     case VIRTIO_MMIO_QUEUE_AVAIL_HIGH:
    469         if (proxy->legacy) {
    470             qemu_log_mask(LOG_GUEST_ERROR,
    471                           "%s: write to non-legacy register (0x%"
    472                           HWADDR_PRIx ") in legacy mode\n",
    473                           __func__, offset);
    474             return;
    475         }
    476         proxy->vqs[vdev->queue_sel].avail[1] = value;
    477         break;
    478     case VIRTIO_MMIO_QUEUE_USED_LOW:
    479         if (proxy->legacy) {
    480             qemu_log_mask(LOG_GUEST_ERROR,
    481                           "%s: write to non-legacy register (0x%"
    482                           HWADDR_PRIx ") in legacy mode\n",
    483                           __func__, offset);
    484             return;
    485         }
    486         proxy->vqs[vdev->queue_sel].used[0] = value;
    487         break;
    488     case VIRTIO_MMIO_QUEUE_USED_HIGH:
    489         if (proxy->legacy) {
    490             qemu_log_mask(LOG_GUEST_ERROR,
    491                           "%s: write to non-legacy register (0x%"
    492                           HWADDR_PRIx ") in legacy mode\n",
    493                           __func__, offset);
    494             return;
    495         }
    496         proxy->vqs[vdev->queue_sel].used[1] = value;
    497         break;
    498     case VIRTIO_MMIO_MAGIC_VALUE:
    499     case VIRTIO_MMIO_VERSION:
    500     case VIRTIO_MMIO_DEVICE_ID:
    501     case VIRTIO_MMIO_VENDOR_ID:
    502     case VIRTIO_MMIO_DEVICE_FEATURES:
    503     case VIRTIO_MMIO_QUEUE_NUM_MAX:
    504     case VIRTIO_MMIO_INTERRUPT_STATUS:
    505     case VIRTIO_MMIO_CONFIG_GENERATION:
    506         qemu_log_mask(LOG_GUEST_ERROR,
    507                       "%s: write to read-only register (0x%" HWADDR_PRIx ")\n",
    508                       __func__, offset);
    509         break;
    510 
    511     default:
    512         qemu_log_mask(LOG_GUEST_ERROR,
    513                       "%s: bad register offset (0x%" HWADDR_PRIx ")\n",
    514                       __func__, offset);
    515     }
    516 }
    517 
    518 static const MemoryRegionOps virtio_legacy_mem_ops = {
    519     .read = virtio_mmio_read,
    520     .write = virtio_mmio_write,
    521     .endianness = DEVICE_NATIVE_ENDIAN,
    522 };
    523 
    524 static const MemoryRegionOps virtio_mem_ops = {
    525     .read = virtio_mmio_read,
    526     .write = virtio_mmio_write,
    527     .endianness = DEVICE_LITTLE_ENDIAN,
    528 };
    529 
    530 static void virtio_mmio_update_irq(DeviceState *opaque, uint16_t vector)
    531 {
    532     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    533     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    534     int level;
    535 
    536     if (!vdev) {
    537         return;
    538     }
    539     level = (qatomic_read(&vdev->isr) != 0);
    540     trace_virtio_mmio_setting_irq(level);
    541     qemu_set_irq(proxy->irq, level);
    542 }
    543 
    544 static int virtio_mmio_load_config(DeviceState *opaque, QEMUFile *f)
    545 {
    546     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    547 
    548     proxy->host_features_sel = qemu_get_be32(f);
    549     proxy->guest_features_sel = qemu_get_be32(f);
    550     proxy->guest_page_shift = qemu_get_be32(f);
    551     return 0;
    552 }
    553 
    554 static void virtio_mmio_save_config(DeviceState *opaque, QEMUFile *f)
    555 {
    556     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    557 
    558     qemu_put_be32(f, proxy->host_features_sel);
    559     qemu_put_be32(f, proxy->guest_features_sel);
    560     qemu_put_be32(f, proxy->guest_page_shift);
    561 }
    562 
    563 static const VMStateDescription vmstate_virtio_mmio_queue_state = {
    564     .name = "virtio_mmio/queue_state",
    565     .version_id = 1,
    566     .minimum_version_id = 1,
    567     .fields = (VMStateField[]) {
    568         VMSTATE_UINT16(num, VirtIOMMIOQueue),
    569         VMSTATE_BOOL(enabled, VirtIOMMIOQueue),
    570         VMSTATE_UINT32_ARRAY(desc, VirtIOMMIOQueue, 2),
    571         VMSTATE_UINT32_ARRAY(avail, VirtIOMMIOQueue, 2),
    572         VMSTATE_UINT32_ARRAY(used, VirtIOMMIOQueue, 2),
    573         VMSTATE_END_OF_LIST()
    574     }
    575 };
    576 
    577 static const VMStateDescription vmstate_virtio_mmio_state_sub = {
    578     .name = "virtio_mmio/state",
    579     .version_id = 1,
    580     .minimum_version_id = 1,
    581     .fields = (VMStateField[]) {
    582         VMSTATE_UINT32_ARRAY(guest_features, VirtIOMMIOProxy, 2),
    583         VMSTATE_STRUCT_ARRAY(vqs, VirtIOMMIOProxy, VIRTIO_QUEUE_MAX, 0,
    584                              vmstate_virtio_mmio_queue_state,
    585                              VirtIOMMIOQueue),
    586         VMSTATE_END_OF_LIST()
    587     }
    588 };
    589 
    590 static const VMStateDescription vmstate_virtio_mmio = {
    591     .name = "virtio_mmio",
    592     .version_id = 1,
    593     .minimum_version_id = 1,
    594     .fields = (VMStateField[]) {
    595         VMSTATE_END_OF_LIST()
    596     },
    597     .subsections = (const VMStateDescription * []) {
    598         &vmstate_virtio_mmio_state_sub,
    599         NULL
    600     }
    601 };
    602 
    603 static void virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f)
    604 {
    605     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    606 
    607     vmstate_save_state(f, &vmstate_virtio_mmio, proxy, NULL);
    608 }
    609 
    610 static int virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f)
    611 {
    612     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    613 
    614     return vmstate_load_state(f, &vmstate_virtio_mmio, proxy, 1);
    615 }
    616 
    617 static bool virtio_mmio_has_extra_state(DeviceState *opaque)
    618 {
    619     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
    620 
    621     return !proxy->legacy;
    622 }
    623 
    624 static void virtio_mmio_reset(DeviceState *d)
    625 {
    626     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    627     int i;
    628 
    629     virtio_mmio_soft_reset(proxy);
    630 
    631     proxy->host_features_sel = 0;
    632     proxy->guest_features_sel = 0;
    633     proxy->guest_page_shift = 0;
    634 
    635     if (!proxy->legacy) {
    636         proxy->guest_features[0] = proxy->guest_features[1] = 0;
    637 
    638         for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
    639             proxy->vqs[i].num = 0;
    640             proxy->vqs[i].desc[0] = proxy->vqs[i].desc[1] = 0;
    641             proxy->vqs[i].avail[0] = proxy->vqs[i].avail[1] = 0;
    642             proxy->vqs[i].used[0] = proxy->vqs[i].used[1] = 0;
    643         }
    644     }
    645 }
    646 
    647 static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign,
    648                                           bool with_irqfd)
    649 {
    650     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    651     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    652     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
    653     VirtQueue *vq = virtio_get_queue(vdev, n);
    654     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
    655 
    656     if (assign) {
    657         int r = event_notifier_init(notifier, 0);
    658         if (r < 0) {
    659             return r;
    660         }
    661         virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
    662     } else {
    663         virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
    664         event_notifier_cleanup(notifier);
    665     }
    666 
    667     if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
    668         vdc->guest_notifier_mask(vdev, n, !assign);
    669     }
    670 
    671     return 0;
    672 }
    673 
    674 static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
    675                                            bool assign)
    676 {
    677     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    678     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    679     /* TODO: need to check if kvm-arm supports irqfd */
    680     bool with_irqfd = false;
    681     int r, n;
    682 
    683     nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
    684 
    685     for (n = 0; n < nvqs; n++) {
    686         if (!virtio_queue_get_num(vdev, n)) {
    687             break;
    688         }
    689 
    690         r = virtio_mmio_set_guest_notifier(d, n, assign, with_irqfd);
    691         if (r < 0) {
    692             goto assign_error;
    693         }
    694     }
    695 
    696     return 0;
    697 
    698 assign_error:
    699     /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
    700     assert(assign);
    701     while (--n >= 0) {
    702         virtio_mmio_set_guest_notifier(d, n, !assign, false);
    703     }
    704     return r;
    705 }
    706 
    707 static void virtio_mmio_pre_plugged(DeviceState *d, Error **errp)
    708 {
    709     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    710     VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    711 
    712     if (!proxy->legacy) {
    713         virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1);
    714     }
    715 }
    716 
    717 /* virtio-mmio device */
    718 
    719 static Property virtio_mmio_properties[] = {
    720     DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy,
    721                      format_transport_address, true),
    722     DEFINE_PROP_BOOL("force-legacy", VirtIOMMIOProxy, legacy, true),
    723     DEFINE_PROP_BIT("ioeventfd", VirtIOMMIOProxy, flags,
    724                     VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD_BIT, true),
    725     DEFINE_PROP_END_OF_LIST(),
    726 };
    727 
    728 static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
    729 {
    730     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    731     SysBusDevice *sbd = SYS_BUS_DEVICE(d);
    732 
    733     qbus_init(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS, d, NULL);
    734     sysbus_init_irq(sbd, &proxy->irq);
    735 
    736     if (!kvm_eventfds_enabled()) {
    737         proxy->flags &= ~VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD;
    738     }
    739 
    740     /* fd-based ioevents can't be synchronized in record/replay */
    741     if (replay_mode != REPLAY_MODE_NONE) {
    742         proxy->flags &= ~VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD;
    743     }
    744 
    745     if (proxy->legacy) {
    746         memory_region_init_io(&proxy->iomem, OBJECT(d),
    747                               &virtio_legacy_mem_ops, proxy,
    748                               TYPE_VIRTIO_MMIO, 0x200);
    749     } else {
    750         memory_region_init_io(&proxy->iomem, OBJECT(d),
    751                               &virtio_mem_ops, proxy,
    752                               TYPE_VIRTIO_MMIO, 0x200);
    753     }
    754     sysbus_init_mmio(sbd, &proxy->iomem);
    755 }
    756 
    757 static void virtio_mmio_class_init(ObjectClass *klass, void *data)
    758 {
    759     DeviceClass *dc = DEVICE_CLASS(klass);
    760 
    761     dc->realize = virtio_mmio_realizefn;
    762     dc->reset = virtio_mmio_reset;
    763     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    764     device_class_set_props(dc, virtio_mmio_properties);
    765 }
    766 
    767 static const TypeInfo virtio_mmio_info = {
    768     .name          = TYPE_VIRTIO_MMIO,
    769     .parent        = TYPE_SYS_BUS_DEVICE,
    770     .instance_size = sizeof(VirtIOMMIOProxy),
    771     .class_init    = virtio_mmio_class_init,
    772 };
    773 
    774 /* virtio-mmio-bus. */
    775 
    776 static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
    777 {
    778     BusState *virtio_mmio_bus;
    779     VirtIOMMIOProxy *virtio_mmio_proxy;
    780     char *proxy_path;
    781     char *path;
    782     MemoryRegionSection section;
    783 
    784     virtio_mmio_bus = qdev_get_parent_bus(dev);
    785     virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
    786     proxy_path = qdev_get_dev_path(DEVICE(virtio_mmio_proxy));
    787 
    788     /*
    789      * If @format_transport_address is false, then we just perform the same as
    790      * virtio_bus_get_dev_path(): we delegate the address formatting for the
    791      * device on the virtio-mmio bus to the bus that the virtio-mmio proxy
    792      * (i.e., the device that implements the virtio-mmio bus) resides on. In
    793      * this case the base address of the virtio-mmio transport will be
    794      * invisible.
    795      */
    796     if (!virtio_mmio_proxy->format_transport_address) {
    797         return proxy_path;
    798     }
    799 
    800     /* Otherwise, we append the base address of the transport. */
    801     section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
    802     assert(section.mr);
    803 
    804     if (proxy_path) {
    805         path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
    806                                section.offset_within_address_space);
    807     } else {
    808         path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
    809                                section.offset_within_address_space);
    810     }
    811     memory_region_unref(section.mr);
    812 
    813     g_free(proxy_path);
    814     return path;
    815 }
    816 
    817 static void virtio_mmio_vmstate_change(DeviceState *d, bool running)
    818 {
    819     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
    820 
    821     if (running) {
    822         virtio_mmio_start_ioeventfd(proxy);
    823     } else {
    824         virtio_mmio_stop_ioeventfd(proxy);
    825     }
    826 }
    827 
    828 static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
    829 {
    830     BusClass *bus_class = BUS_CLASS(klass);
    831     VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
    832 
    833     k->notify = virtio_mmio_update_irq;
    834     k->save_config = virtio_mmio_save_config;
    835     k->load_config = virtio_mmio_load_config;
    836     k->save_extra_state = virtio_mmio_save_extra_state;
    837     k->load_extra_state = virtio_mmio_load_extra_state;
    838     k->has_extra_state = virtio_mmio_has_extra_state;
    839     k->set_guest_notifiers = virtio_mmio_set_guest_notifiers;
    840     k->ioeventfd_enabled = virtio_mmio_ioeventfd_enabled;
    841     k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
    842     k->pre_plugged = virtio_mmio_pre_plugged;
    843     k->vmstate_change = virtio_mmio_vmstate_change;
    844     k->has_variable_vring_alignment = true;
    845     bus_class->max_dev = 1;
    846     bus_class->get_dev_path = virtio_mmio_bus_get_dev_path;
    847 }
    848 
    849 static const TypeInfo virtio_mmio_bus_info = {
    850     .name          = TYPE_VIRTIO_MMIO_BUS,
    851     .parent        = TYPE_VIRTIO_BUS,
    852     .instance_size = sizeof(VirtioBusState),
    853     .class_init    = virtio_mmio_bus_class_init,
    854 };
    855 
    856 static void virtio_mmio_register_types(void)
    857 {
    858     type_register_static(&virtio_mmio_bus_info);
    859     type_register_static(&virtio_mmio_info);
    860 }
    861 
    862 type_init(virtio_mmio_register_types)