Merge git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool
Pull in the latest commits from upstream.
BUG=None
TEST=precq passes
Change-Id: I04a0fc1cc251c917ea7439ea79d32f42a48ba64a
diff --git a/Makefile b/Makefile
index 030ff4e..75d83b6 100644
--- a/Makefile
+++ b/Makefile
@@ -248,26 +248,33 @@
endif
endif
-ifeq ($(call try-build,$(SOURCE_ZLIB),$(CFLAGS),$(LDFLAGS) -lz),y)
- CFLAGS_DYNOPT += -DCONFIG_HAS_ZLIB
- LIBS_DYNOPT += -lz
-else
- NOTFOUND += zlib
-endif
-ifeq ($(call try-build,$(SOURCE_ZLIB),$(CFLAGS),$(LDFLAGS) -lz -static),y)
- CFLAGS_STATOPT += -DCONFIG_HAS_ZLIB
- LIBS_STATOPT += -lz
+# Define USE_ZLIB=no to disable zlib.
+ifneq ($(USE_ZLIB),no)
+ ifeq ($(call try-build,$(SOURCE_ZLIB),$(CFLAGS),$(LDFLAGS) -lz),y)
+ CFLAGS_DYNOPT += -DCONFIG_HAS_ZLIB
+ LIBS_DYNOPT += -lz
+ else
+ NOTFOUND += zlib
+ endif
+
+ ifeq ($(call try-build,$(SOURCE_ZLIB),$(CFLAGS),$(LDFLAGS) -lz -static),y)
+ CFLAGS_STATOPT += -DCONFIG_HAS_ZLIB
+ LIBS_STATOPT += -lz
+ endif
endif
-ifeq ($(call try-build,$(SOURCE_AIO),$(CFLAGS),$(LDFLAGS) -laio),y)
- CFLAGS_DYNOPT += -DCONFIG_HAS_AIO
- LIBS_DYNOPT += -laio
-else
- NOTFOUND += aio
-endif
-ifeq ($(call try-build,$(SOURCE_AIO),$(CFLAGS),$(LDFLAGS) -laio -static),y)
- CFLAGS_STATOPT += -DCONFIG_HAS_AIO
- LIBS_STATOPT += -laio
+# Define USE_AIO=no to disable libaio.
+ifneq ($(USE_AIO),no)
+ ifeq ($(call try-build,$(SOURCE_AIO),$(CFLAGS),$(LDFLAGS) -laio),y)
+ CFLAGS_DYNOPT += -DCONFIG_HAS_AIO
+ LIBS_DYNOPT += -laio
+ else
+ NOTFOUND += aio
+ endif
+ ifeq ($(call try-build,$(SOURCE_AIO),$(CFLAGS),$(LDFLAGS) -laio -static),y)
+ CFLAGS_STATOPT += -DCONFIG_HAS_AIO
+ LIBS_STATOPT += -laio
+ endif
endif
ifeq ($(LTO),1)
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
new file mode 100644
index 0000000..9b0d5a4
--- /dev/null
+++ b/PRESUBMIT.cfg
@@ -0,0 +1,3 @@
+[Hook Overrides]
+cros_license_check: false
+tab_check: false
diff --git a/builtin-run.c b/builtin-run.c
index b56aea7..999b0f8 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -100,7 +100,8 @@
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 " \
diff --git a/hw/pci-shmem.c b/hw/pci-shmem.c
index 512b5b0..6e3d70f 100644
--- a/hw/pci-shmem.c
+++ b/hw/pci-shmem.c
@@ -42,6 +42,10 @@
INTRSTATUS = 4,
IVPOSITION = 8,
DOORBELL = 12,
+ MEGARAM = 16,
+ MEGARAMH = 20,
+ MEGASIZE = 24,
+ MEGASIZEH = 28,
};
static struct shmem_info *shmem_region;
@@ -77,6 +81,18 @@
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 @@
break;
case DOORBELL:
break;
+ case MEGARAM:
+ break;
+ case MEGARAMH:
+ break;
+ case MEGASIZE:
+ break;
+ case MEGASIZEH:
+ break;
};
return true;
@@ -197,17 +221,21 @@
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;
@@ -218,8 +246,12 @@
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;
@@ -243,6 +275,8 @@
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)
@@ -327,6 +361,35 @@
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;
@@ -342,13 +405,19 @@
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;
@@ -372,24 +441,24 @@
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;
diff --git a/include/kvm/pci-shmem.h b/include/kvm/pci-shmem.h
index 6cff2b8..7c2643a 100644
--- a/include/kvm/pci-shmem.h
+++ b/include/kvm/pci-shmem.h
@@ -18,6 +18,8 @@
u64 size;
char *handle;
int create;
+ int private;
+ int file;
};
int pci_shmem__init(struct kvm *kvm);
diff --git a/x86/cpuid.c b/x86/cpuid.c
index c3b67d9..d9f4fc3 100644
--- a/x86/cpuid.c
+++ b/x86/cpuid.c
@@ -8,7 +8,7 @@
#define MAX_KVM_CPUID_ENTRIES 100
-static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid)
+static void filter_cpuid(struct kvm_cpu *vcpu, struct kvm_cpuid2 *kvm_cpuid)
{
unsigned int signature[3];
unsigned int i;
@@ -31,6 +31,11 @@
/* Set X86_FEATURE_HYPERVISOR */
if (entry->index == 0)
entry->ecx |= (1 << 31);
+ entry->ebx = (vcpu->cpu_id << 24) | (8 << 8);
+ if (vcpu->kvm->nrcpus > 1) {
+ entry->ebx |= vcpu->kvm->nrcpus << 16;
+ entry->edx |= (1 << 28);
+ }
break;
case 6:
/* Clear X86_FEATURE_EPB */
@@ -80,7 +85,7 @@
if (ioctl(vcpu->kvm->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0)
die_perror("KVM_GET_SUPPORTED_CPUID failed");
- filter_cpuid(kvm_cpuid);
+ filter_cpuid(vcpu, kvm_cpuid);
if (ioctl(vcpu->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0)
die_perror("KVM_SET_CPUID2 failed");