dm: refine ivshmem creation and destruction

add create_ivshmem_from_dm and destroy_ivshmem_from_dm for
ivshmem device creation and destruction in dm-land

Tracked-On: #4853

Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Yuan Liu 2020-08-26 10:52:49 +08:00 committed by wenlingz
parent a977d35e0c
commit 1d084073d6
1 changed files with 25 additions and 19 deletions

View File

@ -71,13 +71,15 @@ struct pci_ivshmem_vdev {
};
static int
create_shared_memory(struct vmctx *ctx, struct pci_ivshmem_vdev *vdev,
const char *name, uint32_t size, uint64_t bar_addr)
create_ivshmem_from_dm(struct vmctx *ctx, struct pci_vdev *vdev,
const char *name, uint32_t size)
{
struct stat st;
int fd = -1;
void *addr = NULL;
bool is_shm_creator = false;
struct pci_ivshmem_vdev *ivshmem_vdev = (struct pci_ivshmem_vdev *) vdev->arg;
uint64_t bar_addr;
fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd > 0)
@ -105,6 +107,9 @@ create_shared_memory(struct vmctx *ctx, struct pci_ivshmem_vdev *vdev,
addr = (void *)mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
bar_addr = pci_get_cfgdata32(vdev, PCIR_BAR(IVSHMEM_MEM_BAR));
bar_addr |= ((uint64_t)pci_get_cfgdata32(vdev, PCIR_BAR(IVSHMEM_MEM_BAR + 1)) << 32);
bar_addr &= PCIM_BAR_MEM_BASE;
pr_dbg("shm configuration, vma 0x%lx, ivshmem bar 0x%lx, size 0x%x\n",
(uint64_t)addr, bar_addr, size);
if (!addr || vm_map_memseg_vma(ctx, size, bar_addr,
@ -113,14 +118,14 @@ create_shared_memory(struct vmctx *ctx, struct pci_ivshmem_vdev *vdev,
goto err;
}
vdev->name = strdup(name);
if (!vdev->name) {
ivshmem_vdev->name = strdup(name);
if (!ivshmem_vdev->name) {
pr_warn("No memory for shm_name\n");
goto err;
}
vdev->fd = fd;
vdev->addr = addr;
vdev->size = size;
ivshmem_vdev->fd = fd;
ivshmem_vdev->addr = addr;
ivshmem_vdev->size = size;
return 0;
err:
if (addr)
@ -210,7 +215,6 @@ static int
pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
{
uint32_t size;
uint64_t addr;
char *tmp, *name, *orig;
struct pci_ivshmem_vdev *ivshmem_vdev = NULL;
@ -229,9 +233,9 @@ pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
pr_warn("the shared memory size is incorrect, %s\n", tmp);
goto err;
}
if (size < 4096 || size > 128 * 1024 * 1024 ||
if (size < 0x200000 || size >= 0x40000000 ||
(size & (size - 1)) != 0) {
pr_warn("invalid shared memory size %u, the size range is [4K,128M] bytes and value must be a power of 2\n",
pr_warn("invalid shared memory size %u, the size range is [2M,1G) bytes and value must be a power of 2\n",
size);
goto err;
}
@ -254,16 +258,12 @@ pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
pci_emul_alloc_bar(dev, IVSHMEM_MMIO_BAR, PCIBAR_MEM32, IVSHMEM_REG_SIZE);
pci_emul_alloc_bar(dev, IVSHMEM_MEM_BAR, PCIBAR_MEM64, size);
addr = pci_get_cfgdata32(dev, PCIR_BAR(IVSHMEM_MEM_BAR));
addr |= ((uint64_t)pci_get_cfgdata32(dev, PCIR_BAR(IVSHMEM_MEM_BAR + 1)) << 32);
addr &= PCIM_BAR_MEM_BASE;
/*
* TODO: If UOS reprograms ivshmem BAR2, the shared memory will be
* unavailable for UOS, so we need to remap GPA and HPA of shared
* memory in this case.
*/
if (create_shared_memory(ctx, ivshmem_vdev, name, size, addr) < 0)
if (create_ivshmem_from_dm(ctx, dev, name, size) < 0)
goto err;
free(orig);
@ -278,6 +278,15 @@ err:
return -1;
}
static void
destroy_ivshmem_from_dm(struct pci_ivshmem_vdev *vdev)
{
if (vdev->addr && vdev->size)
munmap(vdev->addr, vdev->size);
if (vdev->fd > 0)
close(vdev->fd);
}
static void
pci_ivshmem_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
{
@ -288,10 +297,7 @@ pci_ivshmem_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
pr_warn("%s, invalid ivshmem instance\n", __func__);
return;
}
if (vdev->addr && vdev->size)
munmap(vdev->addr, vdev->size);
if (vdev->fd > 0)
close(vdev->fd);
destroy_ivshmem_from_dm(vdev);
if (vdev->name) {
/*
* shm_unlink will only remove the shared memory file object,