diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-05-23 16:15:51 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-05-23 16:15:52 +0100 |
commit | c9158547617584bb9d19db7fb139998fbef80133 (patch) | |
tree | 7fd630b63555af50eaabc3101afe070345904db7 | |
parent | 2b5f477789aa4d0a4aa444533558e21e63a310ec (diff) | |
parent | 1453e6627d19a8d6d54480c6980f5cef5dfc6833 (diff) | |
download | qemu-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-- | Makefile | 1 | ||||
-rw-r--r-- | block/iscsi.c | 1 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | cpus.c | 16 | ||||
-rw-r--r-- | docs/atomics.txt | 4 | ||||
-rw-r--r-- | exec.c | 64 | ||||
-rw-r--r-- | hw/core/nmi.c | 24 | ||||
-rw-r--r-- | hw/i386/kvmvapic.c | 2 | ||||
-rw-r--r-- | hw/i386/pc.c | 20 | ||||
-rw-r--r-- | hw/intc/ioapic.c | 33 | ||||
-rw-r--r-- | hw/scsi/esp.c | 17 | ||||
-rw-r--r-- | hw/watchdog/watchdog.c | 2 | ||||
-rw-r--r-- | include/exec/cpu-common.h | 4 | ||||
-rw-r--r-- | include/exec/memory.h | 1 | ||||
-rw-r--r-- | include/exec/ram_addr.h | 2 | ||||
-rw-r--r-- | include/hw/i386/ioapic_internal.h | 5 | ||||
-rw-r--r-- | include/hw/nmi.h | 1 | ||||
-rw-r--r-- | include/qemu/osdep.h | 13 | ||||
-rw-r--r-- | memory.c | 46 | ||||
-rw-r--r-- | migration/ram.c | 2 | ||||
-rw-r--r-- | migration/savevm.c | 4 | ||||
-rw-r--r-- | scripts/cocci-macro-file.h | 6 | ||||
-rw-r--r-- | scripts/signrom.py | 28 | ||||
-rw-r--r-- | target-i386/translate.c | 5 | ||||
-rw-r--r-- | translate-all.c | 3 | ||||
-rw-r--r-- | util/oslib-posix.c | 13 | ||||
-rw-r--r-- | vl.c | 4 |
27 files changed, 158 insertions, 165 deletions
@@ -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 @@ -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"\ @@ -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. @@ -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, ...); @@ -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> @@ -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], |