mirror of https://github.com/xemu-project/xemu.git
* 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) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJXQxxqAAoJEL/70l94x66DDxsH/ivM720+5xfAOjPmOzSrzwYf wGqsP5Z1kxbvQ9KSFq+DNb3aooqyiPLkv8lDqn+RAy7Hba3d61NW8exYGB/sMn59 lKaEOcs+1eUFYF+G5K2wH+O/7l7cowqIMNmlN5sLKfmEjK7CsBAZyBYYRPl4Stft pLYGfnu9BWPXynwJS1aNpAsHXE2XvPHimCc2+wKad/g72Sk21Mls6nohM2yn7bip J511t4IAIcsQ8x81NDUDIzVX/1YoMUWhNDygHskgn0dEP6b5vLod0yZmAsaJWxxm xMgyZAV5W71rOKt8cVek/dESncPBXgR5FDjvO8Ec3Z7gOBCcKZYG/p7VGBhrI0E= =RNrL -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
c915854761
1
Makefile
1
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)
|
||||
|
||||
|
|
|
@ -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"\
|
||||
|
|
16
cpus.c
16
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)
|
||||
|
|
|
@ -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.
|
||||
|
|
64
exec.c
64
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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
20
hw/i386/pc.c
20
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 },
|
||||
{ }
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -45,6 +45,5 @@ typedef struct NMIClass {
|
|||
} NMIClass;
|
||||
|
||||
void nmi_monitor_handle(int cpu_index, Error **errp);
|
||||
void inject_nmi(void);
|
||||
|
||||
#endif /* NMI_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, ...);
|
||||
|
|
46
memory.c
46
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,34 +1848,12 @@ 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;
|
||||
|
||||
memory_region_transaction_begin();
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
4
vl.c
4
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],
|
||||
|
|
Loading…
Reference in New Issue