提交 c9158547 编写于 作者: P Peter Maydell

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: NPeter Maydell <peter.maydell@linaro.org>
......@@ -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"\
......
......@@ -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.
......
......@@ -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;
......
......@@ -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, ...);
......
......@@ -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>
......
......@@ -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],
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册