aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-01-17 15:39:57 +0200
committerAvi Kivity <avi@redhat.com>2010-01-17 15:39:57 +0200
commitb874ce1db7d8654850c8a6606b95ffb1c7d22ce2 (patch)
tree0e031a914e520fdc6e86cd49c7b0156dd0decd92
parentMerge branch 'stable-0.12-upstream' into stable-0.12 (diff)
parentUpdate version and changelog for release (diff)
downloadqemu-kvm-b874ce1db7d8654850c8a6606b95ffb1c7d22ce2.tar.gz
qemu-kvm-b874ce1db7d8654850c8a6606b95ffb1c7d22ce2.tar.bz2
qemu-kvm-b874ce1db7d8654850c8a6606b95ffb1c7d22ce2.zip
Merge remote branch 'upstream/stable-0.12' into stable-0.12
* upstream/stable-0.12: (27 commits) Update version and changelog for release Update SeaBIOS to 0.5.1 Qemu's internal TFTP server breaks lock-step-iness of TFTP osdep.c: Fix accept4 fallback pc: add rombar to compat properties for pc-0.10 and pc-0.11 pci: allow loading roms via fw_cfg. roms: rework rom loading via fw fw_cfg: rom loader tweaks. roms: minor fixes and cleanups. pc: add machine type for 0.12 loader: more ignores for rom intended to be loaded by the bios vnc_refresh: return if vd->timer is NULL QMP: Don't free async event's 'data' Handle TFTP ERROR from client dmg: fix ->open failure virtio-pci: thinko fix pc-bios: Update README (SeaBIOS) vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow remove pending exception on vcpu reset. Fix CPU topology initialization ... Conflicts: hw/pc.c hw/pci.h qemu-options.hx Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--Changelog36
-rw-r--r--VERSION2
-rw-r--r--block/dmg.c28
-rw-r--r--hw/fw_cfg.c18
-rw-r--r--hw/loader.c55
-rw-r--r--hw/loader.h7
-rw-r--r--hw/pc.c29
-rw-r--r--hw/pci.c15
-rw-r--r--hw/pci.h1
-rw-r--r--hw/virtio-pci.c2
-rw-r--r--hw/vmware_vga.c7
-rw-r--r--monitor.c5
-rw-r--r--osdep.c2
-rw-r--r--pc-bios/README3
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--qemu-options.hx2
m---------roms/seabios0
-rw-r--r--slirp/tftp.c24
-rw-r--r--target-i386/helper.c2
-rw-r--r--target-i386/kvm.c1
-rw-r--r--target-i386/translate.c2
-rw-r--r--vl.c8
-rw-r--r--vnc.c4
-rw-r--r--vnchextile.h2
24 files changed, 193 insertions, 62 deletions
diff --git a/Changelog b/Changelog
index ee2af7303..dede703d3 100644
--- a/Changelog
+++ b/Changelog
@@ -1,7 +1,41 @@
+version 0.12.2:
+ - Qemu's internal TFTP server breaks lock-step-iness of TFTP (Milan Plzik)
+ - osdep.c: Fix accept4 fallback (Kevin Wolf)
+ - pc: add rombar to compat properties for pc-0.10 and pc-0.11 (Gerd Hoffmann)
+ - pci: allow loading roms via fw_cfg. (Gerd Hoffmann)
+ - roms: rework rom loading via fw (Gerd Hoffmann)
+ - fw_cfg: rom loader tweaks. (Gerd Hoffmann)
+ - roms: minor fixes and cleanups. (Gerd Hoffmann)
+ - pc: add machine type for 0.12 (Gerd Hoffmann)
+ - loader: more ignores for rom intended to be loaded by the bios (Aurelien Jarno)
+ - vnc_refresh: return if vd->timer is NULL (Stefano Stabellini)
+ - QMP: Don't free async event's 'data' (Luiz Capitulino)
+ - Handle TFTP ERROR from client (Thomas Horsten)
+ - dmg: fix ->open failure (Christoph Hellwig)
+ - virtio-pci: thinko fix (Michael S. Tsirkin)
+ - pc-bios: Update README (SeaBIOS) (Stefan Weil)
+ - vmware_vga: Check cursor dimensions passed from guest to avoid buffer overflow (Roland Dreier)
+ - remove pending exception on vcpu reset. (Gleb Natapov)
+ - Fix CPU topology initialization (Jiri Denemark)
+ - MCE: Fix bug of IA32_MCG_STATUS after system reset (Huang Ying)
+ - linuxboot: fix gdt address calculation (Avi Kivity)
+ - QMP: Drop wrong assert() (Luiz Capitulino)
+ - vnc: Fix artifacts in hextile decoding (Anthony Liguori)
+ - target-i386: Fix "call im" on x86_64 when executing 32-bit code (Aurelien Jarno)
+ - Add missing newline at the end of options list (Michael Tokarev)
+ - Don't load options roms intended to be loaded by the bios in qemu (Avi Kivity)
+ - USB: Improve usbdevice error messages (Scott Tsai)
+ - cpu-all.h: fix cpu_get_real_ticks() #ifdef (Aurelien Jarno)
+ - alpha: fix compile (Blue Swirl)
+ - user_only: compile everything with -fpie (Kirill A. Shutemov)
+ - fdc/sparc32: don't hang on detection under OBP (Artyom Tarasenko)
+ - scsi-disk: Inquiry with allocation length of CDB < 36 (v4) (Artyom Tarasenko)
+ - e1000: fix init values for command register (Michael S. Tsirkin)
+
version 0.12.1:
- loader: fix rom loading at address 0 (fixes target-arm) (Aurelien Jarno)
- loader: fix rom_copy (fixes multiboot) (Kevin Wolf)
-
+
version 0.12.0:
- Update to SeaBIOS 0.5.0
diff --git a/VERSION b/VERSION
index 34a83616b..26acbf080 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.12.1
+0.12.2
diff --git a/block/dmg.c b/block/dmg.c
index 262560ffd..f4c01c76b 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -90,24 +90,21 @@ static int dmg_open(BlockDriverState *bs, const char *filename, int flags)
/* read offset of info blocks */
if(lseek(s->fd,-0x1d8,SEEK_END)<0) {
-dmg_close:
- close(s->fd);
- /* open raw instead */
- bs->drv=bdrv_find_format("raw");
- return bs->drv->bdrv_open(bs, filename, flags);
+ goto fail;
}
+
info_begin=read_off(s->fd);
if(info_begin==0)
- goto dmg_close;
+ goto fail;
if(lseek(s->fd,info_begin,SEEK_SET)<0)
- goto dmg_close;
+ goto fail;
if(read_uint32(s->fd)!=0x100)
- goto dmg_close;
+ goto fail;
if((count = read_uint32(s->fd))==0)
- goto dmg_close;
+ goto fail;
info_end = info_begin+count;
if(lseek(s->fd,0xf8,SEEK_CUR)<0)
- goto dmg_close;
+ goto fail;
/* read offsets */
last_in_offset = last_out_offset = 0;
@@ -116,14 +113,14 @@ dmg_close:
count = read_uint32(s->fd);
if(count==0)
- goto dmg_close;
+ goto fail;
type = read_uint32(s->fd);
if(type!=0x6d697368 || count<244)
lseek(s->fd,count-4,SEEK_CUR);
else {
int new_size, chunk_count;
if(lseek(s->fd,200,SEEK_CUR)<0)
- goto dmg_close;
+ goto fail;
chunk_count = (count-204)/40;
new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
s->types = qemu_realloc(s->types, new_size/2);
@@ -142,7 +139,7 @@ dmg_close:
chunk_count--;
i--;
if(lseek(s->fd,36,SEEK_CUR)<0)
- goto dmg_close;
+ goto fail;
continue;
}
read_uint32(s->fd);
@@ -163,11 +160,14 @@ dmg_close:
s->compressed_chunk = qemu_malloc(max_compressed_size+1);
s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
if(inflateInit(&s->zstream) != Z_OK)
- goto dmg_close;
+ goto fail;
s->current_chunk = s->n_chunks;
return 0;
+fail:
+ close(s->fd);
+ return -1;
}
static inline int is_sector_in_chunk(BDRVDMGState* s,
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index fe9c52758..ea120ba55 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -278,7 +278,7 @@ int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
uint8_t *data, uint32_t len)
{
const char *basename;
- int index;
+ int i, index;
if (!s->files) {
int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
@@ -300,13 +300,17 @@ int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
} else {
basename = filename;
}
- if (dir) {
- snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
- "%s/%s", dir, basename);
- } else {
- snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
- "%s", basename);
+
+ snprintf(s->files->f[index].name, sizeof(s->files->f[index].name),
+ "%s/%s", dir, basename);
+ for (i = 0; i < index; i++) {
+ if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
+ FW_CFG_DPRINTF("%s: skip duplicate: %s\n", __FUNCTION__,
+ s->files->f[index].name);
+ return 1;
+ }
}
+
s->files->f[index].size = cpu_to_be32(len);
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__,
diff --git a/hw/loader.c b/hw/loader.c
index eef385eb5..b3bbd77d1 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -535,6 +535,7 @@ struct Rom {
QTAILQ_ENTRY(Rom) next;
};
+static FWCfgState *fw_cfg;
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
int rom_enable_driver_roms;
@@ -556,7 +557,7 @@ static void rom_insert(Rom *rom)
QTAILQ_INSERT_TAIL(&roms, rom, next);
}
-int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
+int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr)
{
Rom *rom;
@@ -576,8 +577,10 @@ int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
goto err;
}
- rom->fw_dir = fw_dir ? qemu_strdup(fw_dir) : NULL;
- rom->fw_file = fw_file ? qemu_strdup(fw_file) : NULL;
+ if (fw_dir) {
+ rom->fw_dir = qemu_strdup(fw_dir);
+ rom->fw_file = qemu_strdup(file);
+ }
rom->addr = addr;
rom->romsize = lseek(fd, 0, SEEK_END);
rom->data = qemu_mallocz(rom->romsize);
@@ -590,6 +593,8 @@ int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
}
close(fd);
rom_insert(rom);
+ if (rom->fw_file && fw_cfg)
+ fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
return 0;
err:
@@ -621,14 +626,14 @@ int rom_add_vga(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
- return rom_add_file(file, "vgaroms", file, 0);
+ return rom_add_file(file, "vgaroms", 0);
}
int rom_add_option(const char *file)
{
if (!rom_enable_driver_roms)
return 0;
- return rom_add_file(file, "genroms", file, 0);
+ return rom_add_file(file, "genroms", 0);
}
static void rom_reset(void *unused)
@@ -639,8 +644,9 @@ static void rom_reset(void *unused)
if (rom->fw_file) {
continue;
}
- if (rom->data == NULL)
+ if (rom->data == NULL) {
continue;
+ }
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
if (rom->isrom) {
/* rom needs to be written only once */
@@ -678,16 +684,9 @@ int rom_load_all(void)
return 0;
}
-int rom_load_fw(void *fw_cfg)
+void rom_set_fw(void *f)
{
- Rom *rom;
-
- QTAILQ_FOREACH(rom, &roms, next) {
- if (!rom->fw_file)
- continue;
- fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
- }
- return 0;
+ fw_cfg = f;
}
static Rom *find_rom(target_phys_addr_t addr)
@@ -695,10 +694,15 @@ static Rom *find_rom(target_phys_addr_t addr)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
- if (rom->addr > addr)
+ if (rom->fw_file) {
continue;
- if (rom->addr + rom->romsize < addr)
+ }
+ if (rom->addr > addr) {
+ continue;
+ }
+ if (rom->addr + rom->romsize < addr) {
continue;
+ }
return rom;
}
return NULL;
@@ -717,12 +721,18 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
Rom *rom;
QTAILQ_FOREACH(rom, &roms, next) {
- if (rom->addr + rom->romsize < addr)
+ if (rom->fw_file) {
continue;
- if (rom->addr > end)
+ }
+ if (rom->addr + rom->romsize < addr) {
+ continue;
+ }
+ if (rom->addr > end) {
break;
- if (!rom->data)
+ }
+ if (!rom->data) {
continue;
+ }
d = dest + (rom->addr - addr);
s = rom->data;
@@ -765,10 +775,9 @@ void do_info_roms(Monitor *mon)
rom->isrom ? "rom" : "ram",
rom->name);
} else {
- monitor_printf(mon, "fw=%s%s%s"
+ monitor_printf(mon, "fw=%s/%s"
" size=0x%06zx name=\"%s\" \n",
- rom->fw_dir ? rom->fw_dir : "",
- rom->fw_dir ? "/" : "",
+ rom->fw_dir,
rom->fw_file,
rom->romsize,
rom->name);
diff --git a/hw/loader.h b/hw/loader.h
index 77beb0e93..8ff3c9445 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -19,18 +19,19 @@ void pstrcpy_targphys(const char *name,
target_phys_addr_t dest, int buf_size,
const char *source);
-int rom_add_file(const char *file, const char *fw_dir, const char *fw_file,
+
+int rom_add_file(const char *file, const char *fw_dir,
target_phys_addr_t addr);
int rom_add_blob(const char *name, const void *blob, size_t len,
target_phys_addr_t addr);
int rom_load_all(void);
-int rom_load_fw(void *fw_cfg);
+void rom_set_fw(void *f);
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size);
void *rom_ptr(target_phys_addr_t addr);
void do_info_roms(Monitor *mon);
#define rom_add_file_fixed(_f, _a) \
- rom_add_file(_f, NULL, NULL, _a)
+ rom_add_file(_f, NULL, _a)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _a)
diff --git a/hw/pc.c b/hw/pc.c
index 51603f8cf..78a07c2fd 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1105,6 +1105,7 @@ static void pc_init1(ram_addr_t ram_size,
bios_size, bios_offset | IO_MEM_ROM);
fw_cfg = bochs_bios_init();
+ rom_set_fw(fw_cfg);
if (linux_boot) {
load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
@@ -1292,8 +1293,6 @@ static void pc_init1(ram_addr_t ram_size,
}
}
- rom_load_fw(fw_cfg);
-
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
if (kvm_enabled()) {
add_assigned_devices(pci_bus, assigned_devices, assigned_devices_index);
@@ -1336,7 +1335,7 @@ void cmos_set_s3_resume(void)
}
static QEMUMachine pc_machine = {
- .name = "pc-0.11",
+ .name = "pc-0.12",
.alias = "pc",
.desc = "Standard PC",
.init = pc_init_pci,
@@ -1344,6 +1343,25 @@ static QEMUMachine pc_machine = {
.is_default = 1,
};
+static QEMUMachine pc_machine_v0_11 = {
+ .name = "pc-0.11",
+ .desc = "Standard PC, qemu 0.11",
+ .init = pc_init_pci,
+ .max_cpus = 255,
+ .compat_props = (GlobalProperty[]) {
+ {
+ .driver = "virtio-blk-pci",
+ .property = "vectors",
+ .value = stringify(0),
+ },{
+ .driver = "PCI",
+ .property = "rombar",
+ .value = stringify(0),
+ },
+ { /* end of list */ }
+ }
+};
+
static QEMUMachine pc_machine_v0_10 = {
.name = "pc-0.10",
.desc = "Standard PC, qemu 0.10",
@@ -1366,6 +1384,10 @@ static QEMUMachine pc_machine_v0_10 = {
.driver = "virtio-blk-pci",
.property = "vectors",
.value = stringify(0),
+ },{
+ .driver = "PCI",
+ .property = "rombar",
+ .value = stringify(0),
},
{ /* end of list */ }
},
@@ -1381,6 +1403,7 @@ static QEMUMachine isapc_machine = {
static void pc_machine_init(void)
{
qemu_register_machine(&pc_machine);
+ qemu_register_machine(&pc_machine_v0_11);
qemu_register_machine(&pc_machine_v0_10);
qemu_register_machine(&isapc_machine);
}
diff --git a/hw/pci.c b/hw/pci.c
index 637289b9b..861d42784 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -67,6 +67,7 @@ static struct BusInfo pci_bus_info = {
.props = (Property[]) {
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
+ DEFINE_PROP_UINT32("rombar", PCIDevice, rom_bar, 1),
DEFINE_PROP_END_OF_LIST()
}
};
@@ -1612,6 +1613,20 @@ static int pci_add_option_rom(PCIDevice *pdev)
if (strlen(pdev->romfile) == 0)
return 0;
+ if (!pdev->rom_bar) {
+ /*
+ * Load rom via fw_cfg instead of creating a rom bar,
+ * for 0.11 compatibility.
+ */
+ int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
+ if (class == 0x0300) {
+ rom_add_vga(pdev->romfile);
+ } else {
+ rom_add_option(pdev->romfile);
+ }
+ return 0;
+ }
+
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
if (path == NULL) {
path = qemu_strdup(pdev->romfile);
diff --git a/hw/pci.h b/hw/pci.h
index 5d82cce4e..a225a6a2a 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -271,6 +271,7 @@ struct PCIDevice {
/* Location of option rom */
char *romfile;
ram_addr_t rom_offset;
+ uint32_t rom_bar;
/* How much space does an MSIX table need. */
/* The spec requires giving the table structure
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 62b46bd48..359415226 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -372,7 +372,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
if (PCI_COMMAND == address) {
if (!(val & PCI_COMMAND_MASTER)) {
- proxy->vdev->status &= !VIRTIO_CONFIG_S_DRIVER_OK;
+ proxy->vdev->status &= ~VIRTIO_CONFIG_S_DRIVER_OK;
}
}
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 7ab1c7910..5e969aedb 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -562,6 +562,13 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
cursor.height = y = vmsvga_fifo_read(s);
vmsvga_fifo_read(s);
cursor.bpp = vmsvga_fifo_read(s);
+
+ if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
+ SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
+ args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
+ goto badcmd;
+ }
+
for (args = 0; args < SVGA_BITMAP_SIZE(x, y); args ++)
cursor.mask[args] = vmsvga_fifo_read_raw(s);
for (args = 0; args < SVGA_PIXMAP_SIZE(x, y, cursor.bpp); args ++)
diff --git a/monitor.c b/monitor.c
index 6ff6e1f2a..8c36b1089 100644
--- a/monitor.c
+++ b/monitor.c
@@ -286,7 +286,6 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data)
if (!monitor_has_error(mon)) {
/* success response */
if (data) {
- assert(qobject_type(data) == QTYPE_QDICT);
qobject_incref(data);
qdict_put_obj(qmp, "return", data);
} else {
@@ -369,8 +368,10 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
qmp = qdict_new();
timestamp_put(qmp);
qdict_put(qmp, "event", qstring_from_str(event_name));
- if (data)
+ if (data) {
+ qobject_incref(data);
qdict_put_obj(qmp, "data", data);
+ }
monitor_json_emitter(mon, QOBJECT(qmp));
QDECREF(qmp);
diff --git a/osdep.c b/osdep.c
index b7b441107..d8efd0e74 100644
--- a/osdep.c
+++ b/osdep.c
@@ -310,7 +310,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
#ifdef CONFIG_ACCEPT4
ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
- if (ret != -1 || errno != EINVAL) {
+ if (ret != -1 || errno != ENOSYS) {
return ret;
}
#endif
diff --git a/pc-bios/README b/pc-bios/README
index 9eaa52262..5be01f829 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -1,4 +1,5 @@
-- The PC BIOS comes from the Bochs project (http://bochs.sourceforge.net/).
+- SeaBIOS (bios.bin) is the successor of pc bios.
+ See http://www.seabios.org/ for more information.
- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
project (http://www.nongnu.org/vgabios/).
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index 827327db9..1741eeced 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/qemu-options.hx b/qemu-options.hx
index 812d0670a..ca73ba5db 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1937,7 +1937,7 @@ DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
"-readconfig <file>\n")
DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig,
"-writeconfig <file>\n"
- " read/write config file")
+ " read/write config file\n")
DEF("no-kvm", 0, QEMU_OPTION_no_kvm,
"-no-kvm disable KVM hardware virtualization\n")
diff --git a/roms/seabios b/roms/seabios
-Subproject 494302fe196f7016d56814f0adc83ba1d54c051
+Subproject 5da68339ecf44677b8f4f115cdf3cb1da46a9f6
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 082f5d040..96c0e0c67 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -264,6 +264,12 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
size_t prefix_len;
char *req_fname;
+ /* check if a session already exists and if so terminate it */
+ s = tftp_session_find(slirp, tp);
+ if (s >= 0) {
+ tftp_session_terminate(&slirp->tftp_sessions[s]);
+ }
+
s = tftp_session_allocate(slirp, tp);
if (s < 0) {
@@ -362,6 +368,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
tftp_send_oack(spt, "tsize", tsize, tp);
+ return;
}
}
@@ -385,6 +392,19 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
}
}
+static void tftp_handle_error(Slirp *slirp, struct tftp_t *tp, int pktlen)
+{
+ int s;
+
+ s = tftp_session_find(slirp, tp);
+
+ if (s < 0) {
+ return;
+ }
+
+ tftp_session_terminate(&slirp->tftp_sessions[s]);
+}
+
void tftp_input(struct mbuf *m)
{
struct tftp_t *tp = (struct tftp_t *)m->m_data;
@@ -397,5 +417,9 @@ void tftp_input(struct mbuf *m)
case TFTP_ACK:
tftp_handle_ack(m->slirp, tp, m->m_len);
break;
+
+ case TFTP_ERROR:
+ tftp_handle_error(m->slirp, tp, m->m_len);
+ break;
}
}
diff --git a/target-i386/helper.c b/target-i386/helper.c
index b58fd8253..fb22f88d8 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -619,6 +619,8 @@ void cpu_reset(CPUX86State *env)
env->dr[7] = DR7_FIXED_1;
cpu_breakpoint_remove_all(env, BP_CPU);
cpu_watchpoint_remove_all(env, BP_CPU);
+
+ env->mcg_status = 0;
}
void cpu_x86_close(CPUX86State *env)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8584507ab..c338bf7cd 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -228,6 +228,7 @@ int kvm_arch_init_vcpu(CPUState *env)
void kvm_arch_reset_vcpu(CPUState *env)
{
+ env->exception_injected = -1;
env->interrupt_injected = -1;
env->nmi_injected = 0;
env->nmi_pending = 0;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 64bc0a3f3..511a4eae9 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6259,6 +6259,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
tval += next_eip;
if (s->dflag == 0)
tval &= 0xffff;
+ else if(!CODE64(s))
+ tval &= 0xffffffff;
gen_movtl_T0_im(next_eip);
gen_push_T0(s);
gen_jmp(s, tval);
diff --git a/vl.c b/vl.c
index 5d713d902..c9d46de0c 100644
--- a/vl.c
+++ b/vl.c
@@ -3528,10 +3528,10 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
- if (kvm_enabled())
- kvm_init_vcpu(env);
env->nr_cores = smp_cores;
env->nr_threads = smp_threads;
+ if (kvm_enabled())
+ kvm_init_vcpu(env);
return;
}
@@ -3863,12 +3863,12 @@ void qemu_init_vcpu(void *_env)
{
CPUState *env = _env;
+ env->nr_cores = smp_cores;
+ env->nr_threads = smp_threads;
if (kvm_enabled())
kvm_start_vcpu(env);
else
tcg_init_vcpu(env);
- env->nr_cores = smp_cores;
- env->nr_threads = smp_threads;
}
void qemu_notify_event(void)
diff --git a/vnc.c b/vnc.c
index c54c6e070..58eac73f9 100644
--- a/vnc.c
+++ b/vnc.c
@@ -2305,6 +2305,10 @@ static void vnc_refresh(void *opaque)
rects += vnc_update_client(vs, has_dirty);
vs = vs->next;
}
+ /* vd->timer could be NULL now if the last client disconnected,
+ * in this case don't update the timer */
+ if (vd->timer == NULL)
+ return;
if (has_dirty && rects) {
vd->timer_interval /= 2;
diff --git a/vnchextile.h b/vnchextile.h
index 432ed89af..78ed8c4e9 100644
--- a/vnchextile.h
+++ b/vnchextile.h
@@ -165,6 +165,8 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
}
+ /* A SubrectsColoured subtile invalidates the foreground color */
+ *has_fg = 0;
if (n_data > (w * h * sizeof(pixel_t))) {
n_colors = 4;
flags = 0x01;