summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c37
-rw-r--r--block/vvfat.c7
-rw-r--r--block_int.h2
-rw-r--r--docs/usb2.txt15
-rw-r--r--hw/acpi_piix4.c1
-rw-r--r--hw/multiboot.c12
-rw-r--r--hw/pci.c1
-rw-r--r--hw/vga.c7
-rw-r--r--hw/vga_int.h1
-rw-r--r--target-i386/cpu.c22
-rw-r--r--target-i386/cpu.h2
-rw-r--r--ui/vnc.c4
12 files changed, 84 insertions, 27 deletions
diff --git a/block.c b/block.c
index af2ab4f3ea..7547051ec2 100644
--- a/block.c
+++ b/block.c
@@ -409,28 +409,36 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
return bdrv_create(drv, filename, options);
}
-#ifdef _WIN32
-void get_tmp_filename(char *filename, int size)
+/*
+ * Create a uniquely-named empty temporary file.
+ * Return 0 upon success, otherwise a negative errno value.
+ */
+int get_tmp_filename(char *filename, int size)
{
+#ifdef _WIN32
char temp_dir[MAX_PATH];
-
- GetTempPath(MAX_PATH, temp_dir);
- GetTempFileName(temp_dir, "qem", 0, filename);
-}
+ /* GetTempFileName requires that its output buffer (4th param)
+ have length MAX_PATH or greater. */
+ assert(size >= MAX_PATH);
+ return (GetTempPath(MAX_PATH, temp_dir)
+ && GetTempFileName(temp_dir, "qem", 0, filename)
+ ? 0 : -GetLastError());
#else
-void get_tmp_filename(char *filename, int size)
-{
int fd;
const char *tmpdir;
- /* XXX: race condition possible */
tmpdir = getenv("TMPDIR");
if (!tmpdir)
tmpdir = "/tmp";
- snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
+ if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) {
+ return -EOVERFLOW;
+ }
fd = mkstemp(filename);
- close(fd);
-}
+ if (fd < 0 || close(fd)) {
+ return -errno;
+ }
+ return 0;
#endif
+}
/*
* Detect host devices. By convention, /dev/cdrom[N] is always
@@ -753,7 +761,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
bdrv_delete(bs1);
- get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+ ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+ if (ret < 0) {
+ return ret;
+ }
/* Real path is meaningless for protocols */
if (is_protocol)
diff --git a/block/vvfat.c b/block/vvfat.c
index 2dc9d50888..0fd3367d82 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2808,7 +2808,12 @@ static int enable_write_target(BDRVVVFATState *s)
array_init(&(s->commits), sizeof(commit_t));
s->qcow_filename = g_malloc(1024);
- get_tmp_filename(s->qcow_filename, 1024);
+ ret = get_tmp_filename(s->qcow_filename, 1024);
+ if (ret < 0) {
+ g_free(s->qcow_filename);
+ s->qcow_filename = NULL;
+ return ret;
+ }
bdrv_qcow = bdrv_find_format("qcow");
options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
diff --git a/block_int.h b/block_int.h
index b80e66db6e..3d4abc6575 100644
--- a/block_int.h
+++ b/block_int.h
@@ -335,7 +335,7 @@ struct BlockDriverState {
BlockJob *job;
};
-void get_tmp_filename(char *filename, int size);
+int get_tmp_filename(char *filename, int size);
void bdrv_set_io_limits(BlockDriverState *bs,
BlockIOLimit *io_limits);
diff --git a/docs/usb2.txt b/docs/usb2.txt
index 228aa33ceb..d17e3c0044 100644
--- a/docs/usb2.txt
+++ b/docs/usb2.txt
@@ -55,6 +55,21 @@ try ...
... then use "bus=ehci.0" to assign your usb devices to that bus.
+xhci controller support
+-----------------------
+
+There also is xhci host controller support available. It got alot
+less testing than ehci and there are a bunch of known limitations, so
+ehci may work better for you. On the other hand the xhci hardware
+design is much more virtualization-friendly, thus xhci emulation uses
+less ressources (especially cpu). If you wanna give xhci a try
+use this to add the host controller ...
+
+ qemu -device nec-usb-xhci,id=xhci
+
+... then use "bus=xhci.0" when assigning usb devices.
+
+
More USB tips & tricks
======================
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 585da4e3eb..0345490ee0 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -299,6 +299,7 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
if (pc->no_hotplug) {
slot_free = false;
} else {
+ object_unparent(OBJECT(dev));
qdev_free(qdev);
}
}
diff --git a/hw/multiboot.c b/hw/multiboot.c
index b4484a3262..b1e04c5718 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -202,10 +202,16 @@ int load_multiboot(void *fw_cfg,
uint32_t mh_bss_end_addr = ldl_p(header+i+24);
mh_load_addr = ldl_p(header+i+16);
uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
- uint32_t mb_load_size = mh_load_end_addr - mh_load_addr;
-
+ uint32_t mb_load_size = 0;
mh_entry_addr = ldl_p(header+i+28);
- mb_kernel_size = mh_bss_end_addr - mh_load_addr;
+
+ if (mh_load_end_addr) {
+ mb_kernel_size = mh_bss_end_addr - mh_load_addr;
+ mb_load_size = mh_load_end_addr - mh_load_addr;
+ } else {
+ mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
+ mb_load_size = mb_kernel_size;
+ }
/* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE.
uint32_t mh_mode_type = ldl_p(header+i+32);
diff --git a/hw/pci.c b/hw/pci.c
index b706e6980a..c1ebdde91e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1527,7 +1527,6 @@ static int pci_unplug_device(DeviceState *qdev)
qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
return -1;
}
- object_unparent(OBJECT(dev));
return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
PCI_HOTPLUG_DISABLED);
}
diff --git a/hw/vga.c b/hw/vga.c
index 5824f85d04..d784df7df4 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2357,10 +2357,15 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space,
void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
{
#ifdef CONFIG_BOCHS_VBE
+ /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
+ * so use an alias to avoid double-mapping the same region.
+ */
+ memory_region_init_alias(&s->vram_vbe, "vram.vbe",
+ &s->vram, 0, memory_region_size(&s->vram));
/* XXX: use optimized standard vga accesses */
memory_region_add_subregion(system_memory,
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- &s->vram);
+ &s->vram_vbe);
s->vbe_mapped = 1;
#endif
}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 7685b2b167..d244d8ff99 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -105,6 +105,7 @@ typedef struct VGACommonState {
MemoryRegion *legacy_address_space;
uint8_t *vram_ptr;
MemoryRegion vram;
+ MemoryRegion vram_vbe;
uint32_t vram_size;
uint32_t latch;
MemoryRegion *chain4_alias;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 89b4ac7ec5..388bc5c527 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -238,6 +238,8 @@ typedef struct x86_def_t {
/* Store the results of Centaur's CPUID instructions */
uint32_t ext4_features;
uint32_t xlevel2;
+ /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
+ uint32_t cpuid_7_0_ebx_features;
} x86_def_t;
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
@@ -521,6 +523,12 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
x86_cpu_def->ext_features = ecx;
x86_cpu_def->features = edx;
+ if (kvm_enabled() && x86_cpu_def->level >= 7) {
+ x86_cpu_def->cpuid_7_0_ebx_features = kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX);
+ } else {
+ x86_cpu_def->cpuid_7_0_ebx_features = 0;
+ }
+
host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
x86_cpu_def->xlevel = eax;
@@ -1185,6 +1193,7 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
env->cpuid_kvm_features = def->kvm_features;
env->cpuid_svm_features = def->svm_features;
env->cpuid_ext4_features = def->ext4_features;
+ env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
env->cpuid_xlevel2 = def->xlevel2;
object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
"tsc-frequency", &error);
@@ -1451,13 +1460,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*edx = 0;
break;
case 7:
- if (kvm_enabled()) {
- KVMState *s = env->kvm_state;
-
- *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
- *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
- *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
- *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
+ /* Structured Extended Feature Flags Enumeration Leaf */
+ if (count == 0) {
+ *eax = 0; /* Maximum ECX value for sub-leaves */
+ *ebx = env->cpuid_7_0_ebx; /* Feature flags */
+ *ecx = 0; /* Reserved */
+ *edx = 0; /* Reserved */
} else {
*eax = 0;
*ebx = 0;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b5b9a50695..2460f6348b 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -741,6 +741,8 @@ typedef struct CPUX86State {
/* Store the results of Centaur's CPUID instructions */
uint32_t cpuid_xlevel2;
uint32_t cpuid_ext4_features;
+ /* Flags from CPUID[EAX=7,ECX=0].EBX */
+ uint32_t cpuid_7_0_ebx;
/* MTRRs */
uint64_t mtrr_fixed[11];
diff --git a/ui/vnc.c b/ui/vnc.c
index be384a5315..54bc5adab6 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2849,6 +2849,10 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ if (!vs) {
+ return -EINVAL;
+ }
+
vs->expires = expires;
return 0;
}