### 概述

虚拟机间共享内存设备ivshmem (Inter-VM shared memory device)设计用于共享运行不同客户机的多个QEMU进程以及与宿主机之间的内存区域。为了让所有的Guest虚拟机都能访问共享内存区域，QEMU将该设备建模为一个PCI设备，将共享内存作为PCI的BAR空间

ivshmem设备可以直接使用宿主机上的共享内存对象（内存映射的文件、内存设备、内存大页等），也可以从一个ivshmem server获取共享内存。当使用ivshmem server时，该设备可以与共享内存对象的多个对端建立中断通信机制

---
### 功能特点

此次设计共享内存通信中间件为用户提供五块独立的共享内存块，通过不同 topic 加以区分，并提供较为简单的通讯接口如 send、recv、pub、sub接口，独立提供跨域同步功能接口 Wlock、Rlockfree 使得在不同机器上读写共享内存数据保证同步，单次同步时间约为 10 微妙。

---
### 原理说明

通过虚拟的 PCI 设备，在不同 qemu 进程间共享由主机创建的内存区域。通过将共享内存映射进 pci 设备中的 BAR 区域，使得 guest 机器在访问或操作 pci 内部 BAR 内存区域以达到操作共享内存的目的，并且将系统事件映射进 pci 设备中的 MSI-X 中断作为跨域信号的通知方式以提高效率

优点：

- 通用内存共享框架
- 适合虚拟机之间共享

缺点：

- 缺少使用案例。目前主要在DPDK中使用，但也有应用于HPC场景的论文
- 缺少维护。原作者最后更新时间是2012年9月，2014年由新的维护者加入qemu主干

Ivshmem PCI设备有2个或3个BAR寄存器

| PCI BARX | 描述                             |
| -------- | -------------------------------- |
| BAR0     | 设备寄存器（256B的MMIO）         |
| BAR1     | MSI-X表和PBA（ivshmem-doorbell） |
| BAR2     | 用作映射的共享内存对象           |


{{< callout type="warning" >}}
  **Warning**注意：该场景必须有一个宿主机上的 ivshmem server，ivshmem 设备会连接到 unix socket 字符设备的该 server 上。ivshmem server 会为每一个 ivshmem 设备分配一个唯一的 ID（0-65535）。中断使用 MSI-X（message-signaled）机制，vector=N 用于配置 MSI-X 使用的 vectors 数量
{{< /callout >}}

### 具体实施

基于 ivshmem-doorbell 重新设计跨域共享内存通信中间件

去除了对虚拟网卡依赖，采用了 ivshmem-doorbell 的驱动方式进行事件通知

默认提供五块共享内存（size : 8M）为用户使用，具体大小可根据用户选择进行具体配置