mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-06-15 18:05:49 +00:00
tools/kvm: Add support for DAX and for large mapped objects
This commit is contained in:
committed by
Dimitri John Ledkov
parent
93454e8983
commit
781e35bf93
+2
-1
@@ -103,7 +103,8 @@ void kvm_run_set_wrapper_sandbox(void)
|
||||
OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory" \
|
||||
" size in MiB."), \
|
||||
OPT_CALLBACK('\0', "shmem", NULL, \
|
||||
"[pci:]<addr>:<size>[:handle=<handle>][:create]", \
|
||||
"[pci:]<addr>:<size>[:handle=<handle>|:file=path]" \
|
||||
"[:private][:create]", \
|
||||
"Share host shmem with guest via pci device", \
|
||||
shmem_parser, NULL), \
|
||||
OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk " \
|
||||
|
||||
+79
-10
@@ -42,6 +42,10 @@ enum ivshmem_registers {
|
||||
INTRSTATUS = 4,
|
||||
IVPOSITION = 8,
|
||||
DOORBELL = 12,
|
||||
MEGARAM = 16,
|
||||
MEGARAMH = 20,
|
||||
MEGASIZE = 24,
|
||||
MEGASIZEH = 28,
|
||||
};
|
||||
|
||||
static struct shmem_info *shmem_region;
|
||||
@@ -77,6 +81,18 @@ static bool shmem_pci__io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 po
|
||||
break;
|
||||
case DOORBELL:
|
||||
break;
|
||||
case MEGARAM:
|
||||
ioport__write32(data, shmem_region->phys_addr);
|
||||
break;
|
||||
case MEGARAMH:
|
||||
ioport__write32(data, shmem_region->phys_addr >> 32);
|
||||
break;
|
||||
case MEGASIZE:
|
||||
ioport__write32(data, shmem_region->size);
|
||||
break;
|
||||
case MEGASIZEH:
|
||||
ioport__write32(data, shmem_region->size >> 32);
|
||||
break;
|
||||
};
|
||||
|
||||
return true;
|
||||
@@ -95,6 +111,14 @@ static bool shmem_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 p
|
||||
break;
|
||||
case DOORBELL:
|
||||
break;
|
||||
case MEGARAM:
|
||||
break;
|
||||
case MEGARAMH:
|
||||
break;
|
||||
case MEGASIZE:
|
||||
break;
|
||||
case MEGASIZEH:
|
||||
break;
|
||||
};
|
||||
|
||||
return true;
|
||||
@@ -194,17 +218,21 @@ int pci_shmem__remove_client(struct kvm *kvm, u32 id)
|
||||
return ioctl(kvm->vm_fd, KVM_IOEVENTFD, &ioevent);
|
||||
}
|
||||
|
||||
static void *setup_shmem(const char *key, size_t len, int creating)
|
||||
static void *setup_shmem(const char *key, size_t len, int creating, int file, int private)
|
||||
{
|
||||
int fd;
|
||||
int rtn;
|
||||
void *mem;
|
||||
int flag = O_RDWR;
|
||||
int mflag = MAP_SHARED;
|
||||
|
||||
if (creating)
|
||||
flag |= O_CREAT;
|
||||
|
||||
fd = shm_open(key, flag, S_IRUSR | S_IWUSR);
|
||||
if (file)
|
||||
fd = open(key, flag, S_IRUSR | S_IWUSR);
|
||||
else
|
||||
fd = shm_open(key, flag, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
pr_warning("Failed to open shared memory file %s\n", key);
|
||||
return NULL;
|
||||
@@ -215,8 +243,12 @@ static void *setup_shmem(const char *key, size_t len, int creating)
|
||||
if (rtn < 0)
|
||||
pr_warning("Can't ftruncate(fd,%zu)\n", len);
|
||||
}
|
||||
|
||||
if (private)
|
||||
mflag = MAP_PRIVATE;
|
||||
|
||||
mem = mmap(NULL, len,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE, fd, 0);
|
||||
PROT_READ | PROT_WRITE, mflag | MAP_NORESERVE, fd, 0);
|
||||
if (mem == MAP_FAILED) {
|
||||
pr_warning("Failed to mmap shared memory file");
|
||||
mem = NULL;
|
||||
@@ -240,6 +272,8 @@ int shmem_parser(const struct option *opt, const char *arg, int unset)
|
||||
char *next;
|
||||
int base = 10;
|
||||
int verbose = 0;
|
||||
int private = 0; /* Default is not copy on write */
|
||||
int file = 0;
|
||||
|
||||
const int skip_pci = strlen("pci:");
|
||||
if (verbose)
|
||||
@@ -324,6 +358,35 @@ int shmem_parser(const struct option *opt, const char *arg, int unset)
|
||||
else
|
||||
p = next + 1;
|
||||
}
|
||||
const int skip_file = strlen("file=");
|
||||
next = strcasestr(p, "file=");
|
||||
if (*p && next) {
|
||||
if (p != next)
|
||||
die("unexpected chars before filename\n");
|
||||
if (handle)
|
||||
die("cannot specify handle and filename\n");
|
||||
p += skip_file;
|
||||
next = strchrnul(p, ':');
|
||||
if (next - p) {
|
||||
handle = malloc(next - p + 1);
|
||||
strncpy(handle, p, next - p);
|
||||
handle[next - p] = '\0'; /* just in case. */
|
||||
}
|
||||
if (*next == '\0')
|
||||
p = next;
|
||||
else
|
||||
p = next + 1;
|
||||
file = 1;
|
||||
}
|
||||
next = strcasestr(p, "private");
|
||||
if (*p && next) {
|
||||
private = 1;
|
||||
next = strchrnul(next, ':');
|
||||
if (*next == '\0')
|
||||
p = next;
|
||||
else
|
||||
p = next + 1;
|
||||
}
|
||||
/* parse optional create flag to see if we should create shm seg. */
|
||||
if (*p && strcasestr(p, "create")) {
|
||||
create = 1;
|
||||
@@ -339,13 +402,19 @@ int shmem_parser(const struct option *opt, const char *arg, int unset)
|
||||
pr_info("shmem: phys_addr = %llx",
|
||||
(unsigned long long)phys_addr);
|
||||
pr_info("shmem: size = %llx", (unsigned long long)size);
|
||||
pr_info("shmem: handle = %s", handle);
|
||||
if (!file)
|
||||
pr_info("shmem: handle = %s", handle);
|
||||
else
|
||||
pr_info("shmem: file = %s", handle);
|
||||
pr_info("shmem: private = %d", private);
|
||||
pr_info("shmem: create = %d", create);
|
||||
}
|
||||
|
||||
si->phys_addr = phys_addr;
|
||||
si->size = size;
|
||||
si->handle = handle;
|
||||
si->file = file;
|
||||
si->private = private;
|
||||
si->create = create;
|
||||
pci_shmem__register_mem(si); /* ownership of si, etc. passed on. */
|
||||
return 0;
|
||||
@@ -369,24 +438,24 @@ int pci_shmem__init(struct kvm *kvm)
|
||||
kvm__register_mmio(kvm, msix_block, 0x1010, false, callback_mmio_msix, NULL);
|
||||
|
||||
/*
|
||||
* This registers 3 BARs:
|
||||
* This registers 2 BARs:
|
||||
*
|
||||
* 0 - ivshmem registers
|
||||
* 1 - MSI-X MMIO space
|
||||
* 2 - Shared memory block
|
||||
*
|
||||
* The memory isn't really in PCI space so keep it out of the BARs
|
||||
* and avoid giving the kernel hiccups.
|
||||
*/
|
||||
pci_shmem_pci_device.bar[0] = cpu_to_le32(ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO);
|
||||
pci_shmem_pci_device.bar_size[0] = shmem_region->size;
|
||||
pci_shmem_pci_device.bar_size[0] = 0x100; //shmem_region->size;
|
||||
pci_shmem_pci_device.bar[1] = cpu_to_le32(msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY);
|
||||
pci_shmem_pci_device.bar_size[1] = 0x1010;
|
||||
pci_shmem_pci_device.bar[2] = cpu_to_le32(shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY);
|
||||
pci_shmem_pci_device.bar_size[2] = shmem_region->size;
|
||||
|
||||
device__register(&pci_shmem_device);
|
||||
|
||||
/* Open shared memory and plug it into the guest */
|
||||
mem = setup_shmem(shmem_region->handle, shmem_region->size,
|
||||
shmem_region->create);
|
||||
shmem_region->create, shmem_region->file, shmem_region->private);
|
||||
if (mem == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ struct shmem_info {
|
||||
u64 size;
|
||||
char *handle;
|
||||
int create;
|
||||
int private;
|
||||
int file;
|
||||
};
|
||||
|
||||
int pci_shmem__init(struct kvm *kvm);
|
||||
|
||||
Reference in New Issue
Block a user