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");