aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-05-23 16:15:51 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-05-23 16:15:52 +0100
commitc9158547617584bb9d19db7fb139998fbef80133 (patch)
tree7fd630b63555af50eaabc3101afe070345904db7
parent2b5f477789aa4d0a4aa444533558e21e63a310ec (diff)
parent1453e6627d19a8d6d54480c6980f5cef5dfc6833 (diff)
downloadqemu-c9158547617584bb9d19db7fb139998fbef80133.zip
qemu-c9158547617584bb9d19db7fb139998fbef80133.tar.gz
qemu-c9158547617584bb9d19db7fb139998fbef80133.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* NMI cleanups (Bandan) * RAMBlock/Memory cleanups and fixes (Dominik, Gonglei, Fam, me) * first part of linuxboot support for fw_cfg DMA (Richard) * IOAPIC fix (Peter Xu) * iSCSI SG_IO fix (Vadim) * Various infrastructure bug fixes (Zhijian, Peter M., Stefan) * CVE fixes (Prasad) # gpg: Signature made Mon 23 May 2016 16:06:18 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: (24 commits) cpus: call the core nmi injection function nmi: remove x86 specific nmi handling target-i386: add a generic x86 nmi handler coccinelle: add g_assert_cmp* to macro file iscsi: pass SCSI status back for SG_IO esp: check dma length before reading scsi command(CVE-2016-4441) esp: check command buffer length before write(CVE-2016-4439) scripts/signrom.py: Check for magic in option ROMs. scripts/signrom.py: Allow option ROM checksum script to write the size header. Remove config-devices.mak on 'make clean' cpus.c: Use pthread_sigmask() rather than sigprocmask() memory: remove unnecessary masking of MemoryRegion ram_addr memory: Drop FlatRange.romd_mode memory: Remove code for mr->may_overlap exec: adjust rcu_read_lock requirement memory: drop find_ram_block() vl: change runstate only if new state is different from current state ioapic: clear remote irr bit for edge-triggered interrupts ioapic: keep RO bits for IOAPIC entry target-i386: key sfence availability on CPUID_SSE, not CPUID_SSE2 ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--Makefile1
-rw-r--r--block/iscsi.c1
-rwxr-xr-xconfigure2
-rw-r--r--cpus.c16
-rw-r--r--docs/atomics.txt4
-rw-r--r--exec.c64
-rw-r--r--hw/core/nmi.c24
-rw-r--r--hw/i386/kvmvapic.c2
-rw-r--r--hw/i386/pc.c20
-rw-r--r--hw/intc/ioapic.c33
-rw-r--r--hw/scsi/esp.c17
-rw-r--r--hw/watchdog/watchdog.c2
-rw-r--r--include/exec/cpu-common.h4
-rw-r--r--include/exec/memory.h1
-rw-r--r--include/exec/ram_addr.h2
-rw-r--r--include/hw/i386/ioapic_internal.h5
-rw-r--r--include/hw/nmi.h1
-rw-r--r--include/qemu/osdep.h13
-rw-r--r--memory.c46
-rw-r--r--migration/ram.c2
-rw-r--r--migration/savevm.c4
-rw-r--r--scripts/cocci-macro-file.h6
-rw-r--r--scripts/signrom.py28
-rw-r--r--target-i386/translate.c5
-rw-r--r--translate-all.c3
-rw-r--r--util/oslib-posix.c13
-rw-r--r--vl.c4
27 files changed, 158 insertions, 165 deletions
diff --git a/Makefile b/Makefile
index 1d076a9..a5d7e62 100644
--- a/Makefile
+++ b/Makefile
@@ -356,6 +356,7 @@ clean:
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
rm -f $$d/qemu-options.def; \
done
+ rm -f $(SUBDIR_DEVICES_MAK) config-all-devices.mak
VERSION ?= $(shell cat VERSION)
diff --git a/block/iscsi.c b/block/iscsi.c
index 10f3906..2ca8e72 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -761,6 +761,7 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
acb->ioh->driver_status = 0;
acb->ioh->host_status = 0;
acb->ioh->resid = 0;
+ acb->ioh->status = status;
#define SG_ERR_DRIVER_SENSE 0x08
diff --git a/configure b/configure
index 293639c..b5aab72 100755
--- a/configure
+++ b/configure
@@ -2985,7 +2985,7 @@ int main(void) {
}
EOF
-if ! compile_prog "-Werror $CFLAGS" "$LIBS" ; then
+if ! compile_prog "$CFLAGS" "$LIBS" ; then
error_exit "sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T."\
"You probably need to set PKG_CONFIG_LIBDIR"\
"to point to the right pkg-config files for your"\
diff --git a/cpus.c b/cpus.c
index eb34b4f..e75895a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -780,7 +780,7 @@ static void sigbus_reraise(void)
raise(SIGBUS);
sigemptyset(&set);
sigaddset(&set, SIGBUS);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
+ pthread_sigmask(SIG_UNBLOCK, &set, NULL);
}
perror("Failed to re-raise SIGBUS!\n");
abort();
@@ -1693,21 +1693,7 @@ exit:
void qmp_inject_nmi(Error **errp)
{
-#if defined(TARGET_I386)
- CPUState *cs;
-
- CPU_FOREACH(cs) {
- X86CPU *cpu = X86_CPU(cs);
-
- if (!cpu->apic_state) {
- cpu_interrupt(cs, CPU_INTERRUPT_NMI);
- } else {
- apic_deliver_nmi(cpu->apic_state);
- }
- }
-#else
nmi_monitor_handle(monitor_get_cpu_index(), errp);
-#endif
}
void dump_drift_info(FILE *f, fprintf_function cpu_fprintf)
diff --git a/docs/atomics.txt b/docs/atomics.txt
index ef285e3..bba771e 100644
--- a/docs/atomics.txt
+++ b/docs/atomics.txt
@@ -62,7 +62,7 @@ operations:
typeof(*ptr) atomic_fetch_sub(ptr, val)
typeof(*ptr) atomic_fetch_and(ptr, val)
typeof(*ptr) atomic_fetch_or(ptr, val)
- typeof(*ptr) atomic_xchg(ptr, val
+ typeof(*ptr) atomic_xchg(ptr, val)
typeof(*ptr) atomic_cmpxchg(ptr, old, new)
all of which return the old value of *ptr. These operations are
@@ -328,7 +328,7 @@ and memory barriers, and the equivalents in QEMU:
- atomic_read and atomic_set in Linux give no guarantee at all;
atomic_read and atomic_set in QEMU include a compiler barrier
- (similar to the ACCESS_ONCE macro in Linux).
+ (similar to the READ_ONCE/WRITE_ONCE macros in Linux).
- most atomic read-modify-write operations in Linux return void;
in QEMU, all of them return the old value of the variable.
diff --git a/exec.c b/exec.c
index 2e363f0..a3a93ae 100644
--- a/exec.c
+++ b/exec.c
@@ -1046,8 +1046,7 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
if (memory_region_is_ram(section->mr)) {
/* Normal RAM. */
- iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
- + xlat;
+ iotlb = memory_region_get_ram_addr(section->mr) + xlat;
if (!section->readonly) {
iotlb |= PHYS_SECTION_NOTDIRTY;
} else {
@@ -1299,7 +1298,7 @@ static void *file_ram_alloc(RAMBlock *block,
}
page_size = qemu_fd_getpagesize(fd);
- block->mr->align = page_size;
+ block->mr->align = MAX(page_size, QEMU_VMALLOC_ALIGN);
if (memory < page_size) {
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
@@ -1320,7 +1319,8 @@ static void *file_ram_alloc(RAMBlock *block,
perror("ftruncate");
}
- area = qemu_ram_mmap(fd, memory, page_size, block->flags & RAM_SHARED);
+ area = qemu_ram_mmap(fd, memory, block->mr->align,
+ block->flags & RAM_SHARED);
if (area == MAP_FAILED) {
error_setg_errno(errp, errno,
"unable to map backing store for guest RAM");
@@ -1410,34 +1410,16 @@ static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
}
}
-/* Called within an RCU critical section, or while the ramlist lock
- * is held.
- */
-static RAMBlock *find_ram_block(ram_addr_t addr)
-{
- RAMBlock *block;
-
- QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
- if (block->offset == addr) {
- return block;
- }
- }
-
- return NULL;
-}
-
const char *qemu_ram_get_idstr(RAMBlock *rb)
{
return rb->idstr;
}
/* Called with iothread lock held. */
-void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
+void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev)
{
- RAMBlock *new_block, *block;
+ RAMBlock *block;
- rcu_read_lock();
- new_block = find_ram_block(addr);
assert(new_block);
assert(!new_block->idstr[0]);
@@ -1450,8 +1432,10 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
}
pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
+ rcu_read_lock();
QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
- if (block != new_block && !strcmp(block->idstr, new_block->idstr)) {
+ if (block != new_block &&
+ !strcmp(block->idstr, new_block->idstr)) {
fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
new_block->idstr);
abort();
@@ -1461,21 +1445,15 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
}
/* Called with iothread lock held. */
-void qemu_ram_unset_idstr(ram_addr_t addr)
+void qemu_ram_unset_idstr(RAMBlock *block)
{
- RAMBlock *block;
-
/* FIXME: arch_init.c assumes that this is not called throughout
* migration. Ignore the problem since hot-unplug during migration
* does not work anyway.
*/
-
- rcu_read_lock();
- block = find_ram_block(addr);
if (block) {
memset(block->idstr, 0, sizeof(block->idstr));
}
- rcu_read_unlock();
}
static int memory_try_enable_merging(void *addr, size_t len)
@@ -1495,10 +1473,8 @@ static int memory_try_enable_merging(void *addr, size_t len)
* resize callback to update device state and/or add assertions to detect
* misuse, if necessary.
*/
-int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp)
+int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
{
- RAMBlock *block = find_ram_block(base);
-
assert(block);
newsize = HOST_PAGE_ALIGN(newsize);
@@ -3102,9 +3078,7 @@ static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr,
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(mr->ram_block,
- (memory_region_get_ram_addr(mr)
- & TARGET_PAGE_MASK)
- + addr1);
+ memory_region_get_ram_addr(mr) + addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = ldl_le_p(ptr);
@@ -3198,9 +3172,7 @@ static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr,
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(mr->ram_block,
- (memory_region_get_ram_addr(mr)
- & TARGET_PAGE_MASK)
- + addr1);
+ memory_region_get_ram_addr(mr) + addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = ldq_le_p(ptr);
@@ -3314,9 +3286,7 @@ static inline uint32_t address_space_lduw_internal(AddressSpace *as,
} else {
/* RAM case */
ptr = qemu_get_ram_ptr(mr->ram_block,
- (memory_region_get_ram_addr(mr)
- & TARGET_PAGE_MASK)
- + addr1);
+ memory_region_get_ram_addr(mr) + addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = lduw_le_p(ptr);
@@ -3398,7 +3368,7 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
} else {
- addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+ addr1 += memory_region_get_ram_addr(mr);
ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
stl_p(ptr, val);
@@ -3453,7 +3423,7 @@ static inline void address_space_stl_internal(AddressSpace *as,
r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
} else {
/* RAM case */
- addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+ addr1 += memory_region_get_ram_addr(mr);
ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
@@ -3563,7 +3533,7 @@ static inline void address_space_stw_internal(AddressSpace *as,
r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
} else {
/* RAM case */
- addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
+ addr1 += memory_region_get_ram_addr(mr);
ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index f616a79..bfd0896 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -20,16 +20,11 @@
*/
#include "qemu/osdep.h"
-#include "qom/cpu.h"
#include "hw/nmi.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "monitor/monitor.h"
-#if defined(TARGET_I386)
-#include "cpu.h"
-#endif
-
struct do_nmi_s {
int cpu_index;
Error *err;
@@ -78,25 +73,6 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
}
}
-void inject_nmi(void)
-{
-#if defined(TARGET_I386)
- CPUState *cs;
-
- CPU_FOREACH(cs) {
- X86CPU *cpu = X86_CPU(cs);
-
- if (!cpu->apic_state) {
- cpu_interrupt(cs, CPU_INTERRUPT_NMI);
- } else {
- apic_deliver_nmi(cpu->apic_state);
- }
- }
-#else
- nmi_monitor_handle(0, NULL);
-#endif
-}
-
static const TypeInfo nmi_info = {
.name = TYPE_NMI,
.parent = TYPE_INTERFACE,
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 8fd27ba..5b71b1b 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -397,7 +397,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
CPUX86State *env = &cpu->env;
VAPICHandlers *handlers;
uint8_t opcode[2];
- uint32_t imm32;
+ uint32_t imm32 = 0;
target_ulong current_pc = 0;
target_ulong current_cs_base = 0;
uint32_t current_flags = 0;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 99437e0..e29ccc8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -67,6 +67,7 @@
#include "qapi/visitor.h"
#include "qapi-visit.h"
#include "qom/cpu.h"
+#include "hw/nmi.h"
/* debug PC/ISA interrupts */
//#define DEBUG_IRQ
@@ -1963,11 +1964,28 @@ static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine)
return list;
}
+static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+ /* cpu index isn't used */
+ CPUState *cs;
+
+ CPU_FOREACH(cs) {
+ X86CPU *cpu = X86_CPU(cs);
+
+ if (!cpu->apic_state) {
+ cpu_interrupt(cs, CPU_INTERRUPT_NMI);
+ } else {
+ apic_deliver_nmi(cpu->apic_state);
+ }
+ }
+}
+
static void pc_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ NMIClass *nc = NMI_CLASS(oc);
pcmc->get_hotplug_handler = mc->get_hotplug_handler;
pcmc->pci_enabled = true;
@@ -1993,6 +2011,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
hc->plug = pc_machine_device_plug_cb;
hc->unplug_request = pc_machine_device_unplug_request_cb;
hc->unplug = pc_machine_device_unplug_cb;
+ nc->nmi_monitor_handler = x86_nmi;
}
static const TypeInfo pc_machine_info = {
@@ -2005,6 +2024,7 @@ static const TypeInfo pc_machine_info = {
.class_init = pc_machine_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
+ { TYPE_NMI },
{ }
},
};
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 4f42b91..273bb08 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -255,6 +255,34 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
return val;
}
+/*
+ * This is to satisfy the hack in Linux kernel. One hack of it is to
+ * simulate clearing the Remote IRR bit of IOAPIC entry using the
+ * following:
+ *
+ * "For IO-APIC's with EOI register, we use that to do an explicit EOI.
+ * Otherwise, we simulate the EOI message manually by changing the trigger
+ * mode to edge and then back to level, with RTE being masked during
+ * this."
+ *
+ * (See linux kernel __eoi_ioapic_pin() comment in commit c0205701)
+ *
+ * This is based on the assumption that, Remote IRR bit will be
+ * cleared by IOAPIC hardware when configured as edge-triggered
+ * interrupts.
+ *
+ * Without this, level-triggered interrupts in IR mode might fail to
+ * work correctly.
+ */
+static inline void
+ioapic_fix_edge_remote_irr(uint64_t *entry)
+{
+ if (!(*entry & IOAPIC_LVT_TRIGGER_MODE)) {
+ /* Edge-triggered interrupts, make sure remote IRR is zero */
+ *entry &= ~((uint64_t)IOAPIC_LVT_REMOTE_IRR);
+ }
+}
+
static void
ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
unsigned int size)
@@ -281,6 +309,7 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
default:
index = (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1;
if (index >= 0 && index < IOAPIC_NUM_PINS) {
+ uint64_t ro_bits = s->ioredtbl[index] & IOAPIC_RO_BITS;
if (s->ioregsel & 1) {
s->ioredtbl[index] &= 0xffffffff;
s->ioredtbl[index] |= (uint64_t)val << 32;
@@ -288,6 +317,10 @@ ioapic_mem_write(void *opaque, hwaddr addr, uint64_t val,
s->ioredtbl[index] &= ~0xffffffffULL;
s->ioredtbl[index] |= val;
}
+ /* restore RO bits */
+ s->ioredtbl[index] &= IOAPIC_RW_BITS;
+ s->ioredtbl[index] |= ro_bits;
+ ioapic_fix_edge_remote_irr(&s->ioredtbl[index]);
ioapic_service(s);
}
}
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8961be2..591c817 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -82,7 +82,7 @@ void esp_request_cancelled(SCSIRequest *req)
}
}
-static uint32_t get_cmd(ESPState *s, uint8_t *buf)
+static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
{
uint32_t dmalen;
int target;
@@ -92,6 +92,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
dmalen = s->rregs[ESP_TCLO];
dmalen |= s->rregs[ESP_TCMID] << 8;
dmalen |= s->rregs[ESP_TCHI] << 16;
+ if (dmalen > buflen) {
+ return 0;
+ }
s->dma_memory_read(s->dma_opaque, buf, dmalen);
} else {
dmalen = s->ti_size;
@@ -166,7 +169,7 @@ static void handle_satn(ESPState *s)
s->dma_cb = handle_satn;
return;
}
- len = get_cmd(s, buf);
+ len = get_cmd(s, buf, sizeof(buf));
if (len)
do_cmd(s, buf);
}
@@ -180,7 +183,7 @@ static void handle_s_without_atn(ESPState *s)
s->dma_cb = handle_s_without_atn;
return;
}
- len = get_cmd(s, buf);
+ len = get_cmd(s, buf, sizeof(buf));
if (len) {
do_busid_cmd(s, buf, 0);
}
@@ -192,7 +195,7 @@ static void handle_satn_stop(ESPState *s)
s->dma_cb = handle_satn_stop;
return;
}
- s->cmdlen = get_cmd(s, s->cmdbuf);
+ s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
if (s->cmdlen) {
trace_esp_handle_satn_stop(s->cmdlen);
s->do_cmd = 1;
@@ -448,7 +451,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
break;
case ESP_FIFO:
if (s->do_cmd) {
- s->cmdbuf[s->cmdlen++] = val & 0xff;
+ if (s->cmdlen < TI_BUFSZ) {
+ s->cmdbuf[s->cmdlen++] = val & 0xff;
+ } else {
+ trace_esp_error_fifo_overrun();
+ }
} else if (s->ti_size == TI_BUFSZ - 1) {
trace_esp_error_fifo_overrun();
} else {
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index bbf3646..2aeaf1f 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -143,7 +143,7 @@ void watchdog_perform_action(void)
case WDT_NMI:
qapi_event_send_watchdog(WATCHDOG_EXPIRATION_ACTION_INJECT_NMI,
&error_abort);
- inject_nmi();
+ nmi_monitor_handle(0, NULL);
break;
}
}
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 04eade5..a2c3b92 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -61,8 +61,8 @@ MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
RAMBlock *qemu_ram_block_by_name(const char *name);
RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
ram_addr_t *ram_addr, ram_addr_t *offset);
-void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
-void qemu_ram_unset_idstr(ram_addr_t addr);
+void qemu_ram_set_idstr(RAMBlock *block, const char *name, DeviceState *dev);
+void qemu_ram_unset_idstr(RAMBlock *block);
const char *qemu_ram_get_idstr(RAMBlock *rb);
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7fb9188..f649697 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -187,7 +187,6 @@ struct MemoryRegion {
MemoryRegion *alias;
hwaddr alias_offset;
int32_t priority;
- bool may_overlap;
QTAILQ_HEAD(subregions, MemoryRegion) subregions;
QTAILQ_ENTRY(MemoryRegion) subregions_link;
QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 5adf7a4..5b6e1b8 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -110,7 +110,7 @@ void qemu_set_ram_fd(ram_addr_t addr, int fd);
void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
void qemu_ram_free(RAMBlock *block);
-int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
+int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index 797ed47..cab9e67 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -47,6 +47,11 @@
#define IOAPIC_LVT_DEST_MODE (1 << IOAPIC_LVT_DEST_MODE_SHIFT)
#define IOAPIC_LVT_DELIV_MODE (7 << IOAPIC_LVT_DELIV_MODE_SHIFT)
+/* Bits that are read-only for IOAPIC entry */
+#define IOAPIC_RO_BITS (IOAPIC_LVT_REMOTE_IRR | \
+ IOAPIC_LVT_DELIV_STATUS)
+#define IOAPIC_RW_BITS (~(uint64_t)IOAPIC_RO_BITS)
+
#define IOAPIC_TRIGGER_EDGE 0
#define IOAPIC_TRIGGER_LEVEL 1
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
index f4cec62..b541772 100644
--- a/include/hw/nmi.h
+++ b/include/hw/nmi.h
@@ -45,6 +45,5 @@ typedef struct NMIClass {
} NMIClass;
void nmi_monitor_handle(int cpu_index, Error **errp);
-void inject_nmi(void);
#endif /* NMI_H */
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 268ec66..994bfa0 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -263,6 +263,19 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#endif
+#if defined(__linux__) && \
+ (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
+ /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
+ Valgrind does not support alignments larger than 1 MiB,
+ therefore we need special code which handles running on Valgrind. */
+# define QEMU_VMALLOC_ALIGN (512 * 4096)
+#elif defined(__linux__) && defined(__s390x__)
+ /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
+# define QEMU_VMALLOC_ALIGN (256 * 4096)
+#else
+# define QEMU_VMALLOC_ALIGN getpagesize()
+#endif
+
int qemu_madvise(void *addr, size_t len, int advice);
int qemu_open(const char *name, int flags, ...);
diff --git a/memory.c b/memory.c
index a8ef852..4e3cda8 100644
--- a/memory.c
+++ b/memory.c
@@ -227,7 +227,6 @@ struct FlatRange {
hwaddr offset_in_region;
AddrRange addr;
uint8_t dirty_log_mask;
- bool romd_mode;
bool readonly;
};
@@ -252,7 +251,6 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
return a->mr == b->mr
&& addrrange_equal(a->addr, b->addr)
&& a->offset_in_region == b->offset_in_region
- && a->romd_mode == b->romd_mode
&& a->readonly == b->readonly;
}
@@ -312,7 +310,6 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
r1->addr.size),
int128_make64(r2->offset_in_region))
&& r1->dirty_log_mask == r2->dirty_log_mask
- && r1->romd_mode == r2->romd_mode
&& r1->readonly == r2->readonly;
}
@@ -666,7 +663,6 @@ static void render_memory_region(FlatView *view,
fr.mr = mr;
fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
- fr.romd_mode = mr->romd_mode;
fr.readonly = readonly;
/* Render the region itself into any gaps left by the current view. */
@@ -1057,13 +1053,6 @@ static void memory_region_get_priority(Object *obj, Visitor *v,
visit_type_int32(v, name, &value, errp);
}
-static bool memory_region_get_may_overlap(Object *obj, Error **errp)
-{
- MemoryRegion *mr = MEMORY_REGION(obj);
-
- return mr->may_overlap;
-}
-
static void memory_region_get_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -1101,10 +1090,6 @@ static void memory_region_initfn(Object *obj)
memory_region_get_priority,
NULL, /* memory_region_set_priority */
NULL, NULL, &error_abort);
- object_property_add_bool(OBJECT(mr), "may-overlap",
- memory_region_get_may_overlap,
- NULL, /* memory_region_set_may_overlap */
- &error_abort);
object_property_add(OBJECT(mr), "size", "uint64",
memory_region_get_size,
NULL, /* memory_region_set_size, */
@@ -1643,7 +1628,7 @@ int memory_region_get_fd(MemoryRegion *mr)
assert(mr->ram_block);
- return qemu_get_ram_fd(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+ return qemu_get_ram_fd(memory_region_get_ram_addr(mr));
}
void *memory_region_get_ram_ptr(MemoryRegion *mr)
@@ -1657,8 +1642,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
mr = mr->alias;
}
assert(mr->ram_block);
- ptr = qemu_get_ram_ptr(mr->ram_block,
- memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+ ptr = qemu_get_ram_ptr(mr->ram_block, memory_region_get_ram_addr(mr));
rcu_read_unlock();
return ptr + offset;
@@ -1673,7 +1657,7 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
{
assert(mr->ram_block);
- qemu_ram_resize(memory_region_get_ram_addr(mr), newsize, errp);
+ qemu_ram_resize(mr->ram_block, newsize, errp);
}
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
@@ -1864,7 +1848,6 @@ void memory_region_del_eventfd(MemoryRegion *mr,
static void memory_region_update_container_subregions(MemoryRegion *subregion)
{
- hwaddr offset = subregion->addr;
MemoryRegion *mr = subregion->container;
MemoryRegion *other;
@@ -1872,27 +1855,6 @@ static void memory_region_update_container_subregions(MemoryRegion *subregion)
memory_region_ref(subregion);
QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
- if (subregion->may_overlap || other->may_overlap) {
- continue;
- }
- if (int128_ge(int128_make64(offset),
- int128_add(int128_make64(other->addr), other->size))
- || int128_le(int128_add(int128_make64(offset), subregion->size),
- int128_make64(other->addr))) {
- continue;
- }
-#if 0
- printf("warning: subregion collision %llx/%llx (%s) "
- "vs %llx/%llx (%s)\n",
- (unsigned long long)offset,
- (unsigned long long)int128_get64(subregion->size),
- subregion->name,
- (unsigned long long)other->addr,
- (unsigned long long)int128_get64(other->size),
- other->name);
-#endif
- }
- QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
if (subregion->priority >= other->priority) {
QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
goto done;
@@ -1918,7 +1880,6 @@ void memory_region_add_subregion(MemoryRegion *mr,
hwaddr offset,
MemoryRegion *subregion)
{
- subregion->may_overlap = false;
subregion->priority = 0;
memory_region_add_subregion_common(mr, offset, subregion);
}
@@ -1928,7 +1889,6 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
MemoryRegion *subregion,
int priority)
{
- subregion->may_overlap = true;
subregion->priority = priority;
memory_region_add_subregion_common(mr, offset, subregion);
}
diff --git a/migration/ram.c b/migration/ram.c
index 5e88080..6b6900e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2478,7 +2478,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
if (length != block->used_length) {
Error *local_err = NULL;
- ret = qemu_ram_resize(block->offset, length,
+ ret = qemu_ram_resize(block, length,
&local_err);
if (local_err) {
error_report_err(local_err);
diff --git a/migration/savevm.c b/migration/savevm.c
index bfb3d91..9bc362a 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2229,13 +2229,13 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
{
- qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
+ qemu_ram_set_idstr(mr->ram_block,
memory_region_name(mr), dev);
}
void vmstate_unregister_ram(MemoryRegion *mr, DeviceState *dev)
{
- qemu_ram_unset_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK);
+ qemu_ram_unset_idstr(mr->ram_block);
}
void vmstate_register_ram_global(MemoryRegion *mr)
diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
index eceb4be..9f2e72e 100644
--- a/scripts/cocci-macro-file.h
+++ b/scripts/cocci-macro-file.h
@@ -117,3 +117,9 @@ struct { \
type *tqe_next; /* next element */ \
type **tqe_prev; /* address of previous next element */ \
}
+
+/* From glib */
+#define g_assert_cmpint(a, op, b) g_assert(a op b)
+#define g_assert_cmpuint(a, op, b) g_assert(a op b)
+#define g_assert_cmphex(a, op, b) g_assert(a op b)
+#define g_assert_cmpstr(a, op, b) g_assert(strcmp(a, b) op 0)
diff --git a/scripts/signrom.py b/scripts/signrom.py
index f9c35cc..5629bca 100644
--- a/scripts/signrom.py
+++ b/scripts/signrom.py
@@ -17,11 +17,33 @@ if len(sys.argv) < 3:
fin = open(sys.argv[1], 'rb')
fout = open(sys.argv[2], 'wb')
-fin.seek(2)
-size = ord(fin.read(1)) * 512 - 1
+magic = fin.read(2)
+if magic != '\x55\xaa':
+ sys.exit("%s: option ROM does not begin with magic 55 aa" % sys.argv[1])
+size_byte = ord(fin.read(1))
fin.seek(0)
-data = fin.read(size)
+
+if size_byte == 0:
+ # If the caller left the size field blank then we will fill it in,
+ # also rounding the whole input to a multiple of 512 bytes.
+ data = fin.read()
+ # +1 because we need a byte to store the checksum.
+ size = len(data) + 1
+ # Round up to next multiple of 512.
+ size += 511
+ size -= size % 512
+ if size >= 65536:
+ sys.exit("%s: option ROM size too large" % sys.argv[1])
+ # size-1 because a final byte is added below to store the checksum.
+ data = data.ljust(size-1, '\0')
+ data = data[:2] + chr(size/512) + data[3:]
+else:
+ # Otherwise the input file specifies the size so use it.
+ # -1 because we overwrite the last byte of the file with the checksum.
+ size = size_byte * 512 - 1
+ data = fin.read(size)
+
fout.write(data)
checksum = 0
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 8085467..731b10d 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8008,6 +8008,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
}
/* fallthru */
case 0xf9 ... 0xff: /* sfence */
+ if (!(s->cpuid_features & CPUID_SSE)
+ || (prefixes & PREFIX_LOCK)) {
+ goto illegal_op;
+ }
+ break;
case 0xe8 ... 0xef: /* lfence */
case 0xf0 ... 0xf7: /* mfence */
if (!(s->cpuid_features & CPUID_SSE2)
diff --git a/translate-all.c b/translate-all.c
index 1c1c855..c599dc4 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1555,8 +1555,7 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
rcu_read_unlock();
return;
}
- ram_addr = (memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK)
- + addr;
+ ram_addr = memory_region_get_ram_addr(mr) + addr;
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
rcu_read_unlock();
}
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 6cc4b8f..4adde93 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -26,19 +26,6 @@
* THE SOFTWARE.
*/
-#if defined(__linux__) && \
- (defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
- /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
- Valgrind does not support alignments larger than 1 MiB,
- therefore we need special code which handles running on Valgrind. */
-# define QEMU_VMALLOC_ALIGN (512 * 4096)
-#elif defined(__linux__) && defined(__s390x__)
- /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
-# define QEMU_VMALLOC_ALIGN (256 * 4096)
-#else
-# define QEMU_VMALLOC_ALIGN getpagesize()
-#endif
-
#include "qemu/osdep.h"
#include <termios.h>
#include <termios.h>
diff --git a/vl.c b/vl.c
index b1562d8..2569dbb 100644
--- a/vl.c
+++ b/vl.c
@@ -690,6 +690,10 @@ void runstate_set(RunState new_state)
{
assert(new_state < RUN_STATE__MAX);
+ if (current_run_state == new_state) {
+ return;
+ }
+
if (!runstate_valid_transitions[current_run_state][new_state]) {
error_report("invalid runstate transition: '%s' -> '%s'",
RunState_lookup[current_run_state],