- miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan)

- next part in the thread-safe address_space_* saga: atomic access
   to the bounce buffer and the map_clients list, from Fam
 - optional support for linking with tcmalloc, also from Fam
 - reapplying Peter Crosthwaite's "Respect as_translate_internal
   length clamp" after fixing the SPARC fallout.
 - build system fix from Wei Liu
 - small acpi-build and ioport cleanup by myself
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABCAAGBQJVQJd4AAoJEL/70l94x66DYFYH/3ifhqWZsd4dfJri0CGAHI4i
 SpPmNeouc8W+F/3lwf6Inrh5NnTgd5QzoUBMQaWVkQKwUiWls8g2mXkT3jo0iDqT
 /B40YXnZjNm20MixNaZmk9AsOF6OqPM8EMufau874k5zTlx3tCGAW1QD+I1N7WK7
 DfsFsIUD1svo2prn55fSoitMG1TIVPnpcklb4YGJRbAacQYUDhr5KAIhT1quDR2R
 93BvToyQmPqRQ4YKqnJLp8HAkL4FaJumfFZVvyh2cZvyaYGN/RVdi2Dw985dJDPX
 /z4enE4GCAs4RDw3lZ1RDbiZDqpT2ibFgASg/arX3SxzqHirOGvMdkOjO99r9j4=
 =aLjh
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

- miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan)
- next part in the thread-safe address_space_* saga: atomic access
  to the bounce buffer and the map_clients list, from Fam
- optional support for linking with tcmalloc, also from Fam
- reapplying Peter Crosthwaite's "Respect as_translate_internal
  length clamp" after fixing the SPARC fallout.
- build system fix from Wei Liu
- small acpi-build and ioport cleanup by myself

# gpg: Signature made Wed Apr 29 09:34:00 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (22 commits)
  nbd/trivial: fix type cast for ioctl
  translate-all: use bitmap helpers for PageDesc's bitmap
  target-i386: disable LINT0 after reset
  Makefile.target: prepend $libs_softmmu to $LIBS
  milkymist: do not modify libs-softmmu
  configure: Add support for tcmalloc
  exec: Respect as_translate_internal length clamp
  ioport: reserve the whole range of an I/O port in the AddressSpace
  ioport: loosen assertions on emulation of 16-bit ports
  ioport: remove wrong comment
  ide: there is only one data port
  gus: clean up MemoryRegionPortio
  sb16: remove useless mixer_write_indexw
  sun4m: fix slavio sysctrl and led register sizes
  acpi-build: remove dependency from ram_addr.h
  memory: add memory_region_ram_resize
  dma-helpers: Fix race condition of continue_after_map_failure and dma_aio_cancel
  exec: Notify cpu_register_map_client caller if the bounce buffer is available
  exec: Protect map_client_list with mutex
  linux-user, bsd-user: Remove two calls to cpu_exec_init_all
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-04-30 12:04:11 +01:00
commit 06feaacfb4
21 changed files with 170 additions and 173 deletions

View File

@ -134,7 +134,7 @@ obj-$(CONFIG_KVM) += kvm-all.o
obj-y += memory.o savevm.o cputlb.o obj-y += memory.o savevm.o cputlb.o
obj-y += memory_mapping.o obj-y += memory_mapping.o
obj-y += dump.o obj-y += dump.o
LIBS+=$(libs_softmmu) LIBS := $(libs_softmmu) $(LIBS)
# xen support # xen support
obj-$(CONFIG_XEN) += xen-common.o obj-$(CONFIG_XEN) += xen-common.o

View File

@ -905,7 +905,6 @@ int main(int argc, char **argv)
#endif #endif
} }
tcg_exec_init(0); tcg_exec_init(0);
cpu_exec_init_all();
/* NOTE: we need to init the CPU at this stage to get /* NOTE: we need to init the CPU at this stage to get
qemu_host_page_size */ qemu_host_page_size */
cpu = cpu_init(cpu_model); cpu = cpu_init(cpu_model);

24
configure vendored
View File

@ -336,6 +336,7 @@ libssh2=""
vhdx="" vhdx=""
quorum="" quorum=""
numa="" numa=""
tcmalloc="no"
# parse CC options first # parse CC options first
for opt do for opt do
@ -1134,6 +1135,10 @@ for opt do
;; ;;
--enable-numa) numa="yes" --enable-numa) numa="yes"
;; ;;
--disable-tcmalloc) tcmalloc="no"
;;
--enable-tcmalloc) tcmalloc="yes"
;;
*) *)
echo "ERROR: unknown option $opt" echo "ERROR: unknown option $opt"
echo "Try '$0 --help' for more information" echo "Try '$0 --help' for more information"
@ -1407,6 +1412,8 @@ Advanced options (experts only):
--enable-quorum enable quorum block filter support --enable-quorum enable quorum block filter support
--disable-numa disable libnuma support --disable-numa disable libnuma support
--enable-numa enable libnuma support --enable-numa enable libnuma support
--disable-tcmalloc disable tcmalloc support
--enable-tcmalloc enable tcmalloc support
NOTE: The object files are built at the place where configure is launched NOTE: The object files are built at the place where configure is launched
EOF EOF
@ -3330,6 +3337,22 @@ EOF
fi fi
fi fi
##########################################
# tcmalloc probe
if test "$tcmalloc" = "yes" ; then
cat > $TMPC << EOF
#include <stdlib.h>
int main(void) { malloc(1); return 0; }
EOF
if compile_prog "" "-ltcmalloc" ; then
LIBS="-ltcmalloc $LIBS"
else
feature_not_found "tcmalloc" "install gperftools devel"
fi
fi
########################################## ##########################################
# signalfd probe # signalfd probe
signalfd="no" signalfd="no"
@ -4441,6 +4464,7 @@ echo "lzo support $lzo"
echo "snappy support $snappy" echo "snappy support $snappy"
echo "bzip2 support $bzip2" echo "bzip2 support $bzip2"
echo "NUMA host support $numa" echo "NUMA host support $numa"
echo "tcmalloc support $tcmalloc"
if test "$sdl_too_old" = "yes"; then if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support" echo "-> Your SDL version is too old - please upgrade to have SDL support"

View File

@ -93,14 +93,6 @@ static void reschedule_dma(void *opaque)
dma_blk_cb(dbs, 0); dma_blk_cb(dbs, 0);
} }
static void continue_after_map_failure(void *opaque)
{
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
dbs->bh = qemu_bh_new(reschedule_dma, dbs);
qemu_bh_schedule(dbs->bh);
}
static void dma_blk_unmap(DMAAIOCB *dbs) static void dma_blk_unmap(DMAAIOCB *dbs)
{ {
int i; int i;
@ -162,7 +154,9 @@ static void dma_blk_cb(void *opaque, int ret)
if (dbs->iov.size == 0) { if (dbs->iov.size == 0) {
trace_dma_map_wait(dbs); trace_dma_map_wait(dbs);
cpu_register_map_client(dbs, continue_after_map_failure); dbs->bh = aio_bh_new(blk_get_aio_context(dbs->blk),
reschedule_dma, dbs);
cpu_register_map_client(dbs->bh);
return; return;
} }
@ -184,6 +178,11 @@ static void dma_aio_cancel(BlockAIOCB *acb)
if (dbs->acb) { if (dbs->acb) {
blk_aio_cancel_async(dbs->acb); blk_aio_cancel_async(dbs->acb);
} }
if (dbs->bh) {
cpu_unregister_map_client(dbs->bh);
qemu_bh_delete(dbs->bh);
dbs->bh = NULL;
}
} }

85
exec.c
View File

@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
IOMMUTLBEntry iotlb; IOMMUTLBEntry iotlb;
MemoryRegionSection *section; MemoryRegionSection *section;
MemoryRegion *mr; MemoryRegion *mr;
hwaddr len = *plen;
rcu_read_lock(); rcu_read_lock();
for (;;) { for (;;) {
@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
iotlb = mr->iommu_ops->translate(mr, addr, is_write); iotlb = mr->iommu_ops->translate(mr, addr, is_write);
addr = ((iotlb.translated_addr & ~iotlb.addr_mask) addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
| (addr & iotlb.addr_mask)); | (addr & iotlb.addr_mask));
len = MIN(len, (addr | iotlb.addr_mask) - addr + 1); *plen = MIN(*plen, (addr | iotlb.addr_mask) - addr + 1);
if (!(iotlb.perm & (1 << is_write))) { if (!(iotlb.perm & (1 << is_write))) {
mr = &io_mem_unassigned; mr = &io_mem_unassigned;
break; break;
@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
if (xen_enabled() && memory_access_is_direct(mr, is_write)) { if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
len = MIN(page, len); *plen = MIN(page, *plen);
} }
*plen = len;
*xlat = addr; *xlat = addr;
rcu_read_unlock(); rcu_read_unlock();
return mr; return mr;
@ -429,15 +427,6 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
} }
#endif #endif
void cpu_exec_init_all(void)
{
#if !defined(CONFIG_USER_ONLY)
qemu_mutex_init(&ram_list.mutex);
memory_map_init();
io_mem_init();
#endif
}
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
static int cpu_common_post_load(void *opaque, int version_id) static int cpu_common_post_load(void *opaque, int version_id)
@ -2518,48 +2507,79 @@ typedef struct {
void *buffer; void *buffer;
hwaddr addr; hwaddr addr;
hwaddr len; hwaddr len;
bool in_use;
} BounceBuffer; } BounceBuffer;
static BounceBuffer bounce; static BounceBuffer bounce;
typedef struct MapClient { typedef struct MapClient {
void *opaque; QEMUBH *bh;
void (*callback)(void *opaque);
QLIST_ENTRY(MapClient) link; QLIST_ENTRY(MapClient) link;
} MapClient; } MapClient;
QemuMutex map_client_list_lock;
static QLIST_HEAD(map_client_list, MapClient) map_client_list static QLIST_HEAD(map_client_list, MapClient) map_client_list
= QLIST_HEAD_INITIALIZER(map_client_list); = QLIST_HEAD_INITIALIZER(map_client_list);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)) static void cpu_unregister_map_client_do(MapClient *client)
{ {
MapClient *client = g_malloc(sizeof(*client));
client->opaque = opaque;
client->callback = callback;
QLIST_INSERT_HEAD(&map_client_list, client, link);
return client;
}
static void cpu_unregister_map_client(void *_client)
{
MapClient *client = (MapClient *)_client;
QLIST_REMOVE(client, link); QLIST_REMOVE(client, link);
g_free(client); g_free(client);
} }
static void cpu_notify_map_clients(void) static void cpu_notify_map_clients_locked(void)
{ {
MapClient *client; MapClient *client;
while (!QLIST_EMPTY(&map_client_list)) { while (!QLIST_EMPTY(&map_client_list)) {
client = QLIST_FIRST(&map_client_list); client = QLIST_FIRST(&map_client_list);
client->callback(client->opaque); qemu_bh_schedule(client->bh);
cpu_unregister_map_client(client); cpu_unregister_map_client_do(client);
} }
} }
void cpu_register_map_client(QEMUBH *bh)
{
MapClient *client = g_malloc(sizeof(*client));
qemu_mutex_lock(&map_client_list_lock);
client->bh = bh;
QLIST_INSERT_HEAD(&map_client_list, client, link);
if (!atomic_read(&bounce.in_use)) {
cpu_notify_map_clients_locked();
}
qemu_mutex_unlock(&map_client_list_lock);
}
void cpu_exec_init_all(void)
{
qemu_mutex_init(&ram_list.mutex);
memory_map_init();
io_mem_init();
qemu_mutex_init(&map_client_list_lock);
}
void cpu_unregister_map_client(QEMUBH *bh)
{
MapClient *client;
qemu_mutex_lock(&map_client_list_lock);
QLIST_FOREACH(client, &map_client_list, link) {
if (client->bh == bh) {
cpu_unregister_map_client_do(client);
break;
}
}
qemu_mutex_unlock(&map_client_list_lock);
}
static void cpu_notify_map_clients(void)
{
qemu_mutex_lock(&map_client_list_lock);
cpu_notify_map_clients_locked();
qemu_mutex_unlock(&map_client_list_lock);
}
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write) bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
{ {
MemoryRegion *mr; MemoryRegion *mr;
@ -2606,7 +2626,7 @@ void *address_space_map(AddressSpace *as,
l = len; l = len;
mr = address_space_translate(as, addr, &xlat, &l, is_write); mr = address_space_translate(as, addr, &xlat, &l, is_write);
if (!memory_access_is_direct(mr, is_write)) { if (!memory_access_is_direct(mr, is_write)) {
if (bounce.buffer) { if (atomic_xchg(&bounce.in_use, true)) {
return NULL; return NULL;
} }
/* Avoid unbounded allocations */ /* Avoid unbounded allocations */
@ -2678,6 +2698,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
qemu_vfree(bounce.buffer); qemu_vfree(bounce.buffer);
bounce.buffer = NULL; bounce.buffer = NULL;
memory_region_unref(bounce.mr); memory_region_unref(bounce.mr);
atomic_mb_set(&bounce.in_use, false);
cpu_notify_map_clients(); cpu_notify_map_clients();
} }

View File

@ -71,13 +71,6 @@ IO_READ_PROTO (gus_readb)
return gus_read (&s->emu, nport, 1); return gus_read (&s->emu, nport, 1);
} }
IO_READ_PROTO (gus_readw)
{
GUSState *s = opaque;
return gus_read (&s->emu, nport, 2);
}
IO_WRITE_PROTO (gus_writeb) IO_WRITE_PROTO (gus_writeb)
{ {
GUSState *s = opaque; GUSState *s = opaque;
@ -85,13 +78,6 @@ IO_WRITE_PROTO (gus_writeb)
gus_write (&s->emu, nport, 1, val); gus_write (&s->emu, nport, 1, val);
} }
IO_WRITE_PROTO (gus_writew)
{
GUSState *s = opaque;
gus_write (&s->emu, nport, 2, val);
}
static int write_audio (GUSState *s, int samples) static int write_audio (GUSState *s, int samples)
{ {
int net = 0; int net = 0;
@ -236,17 +222,13 @@ static const VMStateDescription vmstate_gus = {
static const MemoryRegionPortio gus_portio_list1[] = { static const MemoryRegionPortio gus_portio_list1[] = {
{0x000, 1, 1, .write = gus_writeb }, {0x000, 1, 1, .write = gus_writeb },
{0x000, 1, 2, .write = gus_writew },
{0x006, 10, 1, .read = gus_readb, .write = gus_writeb }, {0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
{0x006, 10, 2, .read = gus_readw, .write = gus_writew },
{0x100, 8, 1, .read = gus_readb, .write = gus_writeb }, {0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
{0x100, 8, 2, .read = gus_readw, .write = gus_writew },
PORTIO_END_OF_LIST (), PORTIO_END_OF_LIST (),
}; };
static const MemoryRegionPortio gus_portio_list2[] = { static const MemoryRegionPortio gus_portio_list2[] = {
{0, 1, 1, .read = gus_readb }, {0, 2, 1, .read = gus_readb },
{0, 1, 2, .read = gus_readw },
PORTIO_END_OF_LIST (), PORTIO_END_OF_LIST (),
}; };

View File

@ -1121,12 +1121,6 @@ static IO_WRITE_PROTO (mixer_write_datab)
s->mixer_regs[s->mixer_nreg] = val; s->mixer_regs[s->mixer_nreg] = val;
} }
static IO_WRITE_PROTO (mixer_write_indexw)
{
mixer_write_indexb (opaque, nport, val & 0xff);
mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
}
static IO_READ_PROTO (mixer_read) static IO_READ_PROTO (mixer_read)
{ {
SB16State *s = opaque; SB16State *s = opaque;
@ -1345,7 +1339,6 @@ static const VMStateDescription vmstate_sb16 = {
static const MemoryRegionPortio sb16_ioport_list[] = { static const MemoryRegionPortio sb16_ioport_list[] = {
{ 4, 1, 1, .write = mixer_write_indexb }, { 4, 1, 1, .write = mixer_write_indexb },
{ 4, 1, 2, .write = mixer_write_indexw },
{ 5, 1, 1, .read = mixer_read, .write = mixer_write_datab }, { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
{ 6, 1, 1, .read = dsp_read, .write = dsp_write }, { 6, 1, 1, .read = dsp_read, .write = dsp_write },
{ 10, 1, 1, .read = dsp_read }, { 10, 1, 1, .read = dsp_read },

View File

@ -835,12 +835,12 @@ err:
return -1; return -1;
} }
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len, MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr, const char *fw_file_name, size_t max_len, hwaddr addr, const char *fw_file_name,
FWCfgReadCallback fw_callback, void *callback_opaque) FWCfgReadCallback fw_callback, void *callback_opaque)
{ {
Rom *rom; Rom *rom;
ram_addr_t ret = RAM_ADDR_MAX; MemoryRegion *mr = NULL;
rom = g_malloc0(sizeof(*rom)); rom = g_malloc0(sizeof(*rom));
rom->name = g_strdup(name); rom->name = g_strdup(name);
@ -858,7 +858,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
if (rom_file_has_mr) { if (rom_file_has_mr) {
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
ret = memory_region_get_ram_addr(rom->mr); mr = rom->mr;
} else { } else {
data = rom->data; data = rom->data;
} }
@ -867,7 +867,7 @@ ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len,
fw_callback, callback_opaque, fw_callback, callback_opaque,
data, rom->datasize); data, rom->datasize);
} }
return ret; return mr;
} }
/* This function is specific for elf program because we don't need to allocate /* This function is specific for elf program because we don't need to allocate

View File

@ -21,7 +21,7 @@ common-obj-$(CONFIG_ZAURUS) += tc6393xb.o
ifeq ($(CONFIG_MILKYMIST_TMU2),y) ifeq ($(CONFIG_MILKYMIST_TMU2),y)
common-obj-y += milkymist-tmu2.o common-obj-y += milkymist-tmu2.o
milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS) milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS)
libs_softmmu += $(OPENGL_LIBS) milkymist-tmu2.o-libs += $(OPENGL_LIBS)
endif endif
obj-$(CONFIG_OMAP) += omap_dss.o obj-$(CONFIG_OMAP) += omap_dss.o

View File

@ -58,7 +58,6 @@
#include "qapi/qmp/qint.h" #include "qapi/qmp/qint.h"
#include "qom/qom-qobject.h" #include "qom/qom-qobject.h"
#include "exec/ram_addr.h"
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
@ -1323,13 +1322,13 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
typedef typedef
struct AcpiBuildState { struct AcpiBuildState {
/* Copy of table in RAM (for patching). */ /* Copy of table in RAM (for patching). */
ram_addr_t table_ram; MemoryRegion *table_mr;
/* Is table patched? */ /* Is table patched? */
uint8_t patched; uint8_t patched;
PcGuestInfo *guest_info; PcGuestInfo *guest_info;
void *rsdp; void *rsdp;
ram_addr_t rsdp_ram; MemoryRegion *rsdp_mr;
ram_addr_t linker_ram; MemoryRegion *linker_mr;
} AcpiBuildState; } AcpiBuildState;
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
@ -1513,15 +1512,15 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
g_array_free(table_offsets, true); g_array_free(table_offsets, true);
} }
static void acpi_ram_update(ram_addr_t ram, GArray *data) static void acpi_ram_update(MemoryRegion *mr, GArray *data)
{ {
uint32_t size = acpi_data_len(data); uint32_t size = acpi_data_len(data);
/* Make sure RAM size is correct - in case it got changed e.g. by migration */ /* Make sure RAM size is correct - in case it got changed e.g. by migration */
qemu_ram_resize(ram, size, &error_abort); memory_region_ram_resize(mr, size, &error_abort);
memcpy(qemu_get_ram_ptr(ram), data->data, size); memcpy(memory_region_get_ram_ptr(mr), data->data, size);
cpu_physical_memory_set_dirty_range_nocode(ram, size); memory_region_set_dirty(mr, 0, size);
} }
static void acpi_build_update(void *build_opaque, uint32_t offset) static void acpi_build_update(void *build_opaque, uint32_t offset)
@ -1539,15 +1538,15 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
acpi_build(build_state->guest_info, &tables); acpi_build(build_state->guest_info, &tables);
acpi_ram_update(build_state->table_ram, tables.table_data); acpi_ram_update(build_state->table_mr, tables.table_data);
if (build_state->rsdp) { if (build_state->rsdp) {
memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
} else { } else {
acpi_ram_update(build_state->rsdp_ram, tables.rsdp); acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
} }
acpi_ram_update(build_state->linker_ram, tables.linker); acpi_ram_update(build_state->linker_mr, tables.linker);
acpi_build_tables_cleanup(&tables, true); acpi_build_tables_cleanup(&tables, true);
} }
@ -1557,8 +1556,9 @@ static void acpi_build_reset(void *build_opaque)
build_state->patched = 0; build_state->patched = 0;
} }
static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob, static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
const char *name, uint64_t max_size) GArray *blob, const char *name,
uint64_t max_size)
{ {
return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1, return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
name, acpi_build_update, build_state); name, acpi_build_update, build_state);
@ -1604,12 +1604,12 @@ void acpi_setup(PcGuestInfo *guest_info)
acpi_build(build_state->guest_info, &tables); acpi_build(build_state->guest_info, &tables);
/* Now expose it all to Guest */ /* Now expose it all to Guest */
build_state->table_ram = acpi_add_rom_blob(build_state, tables.table_data, build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
ACPI_BUILD_TABLE_FILE, ACPI_BUILD_TABLE_FILE,
ACPI_BUILD_TABLE_MAX_SIZE); ACPI_BUILD_TABLE_MAX_SIZE);
assert(build_state->table_ram != RAM_ADDR_MAX); assert(build_state->table_mr != NULL);
build_state->linker_ram = build_state->linker_mr =
acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
@ -1627,10 +1627,10 @@ void acpi_setup(PcGuestInfo *guest_info)
fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE, fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
acpi_build_update, build_state, acpi_build_update, build_state,
build_state->rsdp, rsdp_size); build_state->rsdp, rsdp_size);
build_state->rsdp_ram = (ram_addr_t)-1; build_state->rsdp_mr = NULL;
} else { } else {
build_state->rsdp = NULL; build_state->rsdp = NULL;
build_state->rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp, build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
ACPI_BUILD_RSDP_FILE, 0); ACPI_BUILD_RSDP_FILE, 0);
} }

View File

@ -2436,8 +2436,8 @@ void ide_init2(IDEBus *bus, qemu_irq irq)
static const MemoryRegionPortio ide_portio_list[] = { static const MemoryRegionPortio ide_portio_list[] = {
{ 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
{ 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew }, { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew },
{ 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel }, { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel },
PORTIO_END_OF_LIST(), PORTIO_END_OF_LIST(),
}; };

View File

@ -243,15 +243,6 @@ static void apic_reset_common(DeviceState *dev)
info->vapic_base_update(s); info->vapic_base_update(s);
apic_init_reset(dev); apic_init_reset(dev);
if (bsp) {
/*
* LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
* time typically by BIOS, so PIC interrupt can be delivered to the
* processor when local APIC is enabled.
*/
s->lvt[APIC_LVT_LINT0] = 0x700;
}
} }
/* This function is only used for old state version 1 and 2 */ /* This function is only used for old state version 1 and 2 */

View File

@ -68,6 +68,7 @@ typedef struct APCState {
} APCState; } APCState;
#define MISC_SIZE 1 #define MISC_SIZE 1
#define LED_SIZE 2
#define SYSCTRL_SIZE 4 #define SYSCTRL_SIZE 4
#define AUX1_TC 0x02 #define AUX1_TC 0x02
@ -452,13 +453,13 @@ static int slavio_misc_init1(SysBusDevice *sbd)
/* 16 bit registers */ /* 16 bit registers */
/* ss600mp diag LEDs */ /* ss600mp diag LEDs */
memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s, memory_region_init_io(&s->led_iomem, OBJECT(s), &slavio_led_mem_ops, s,
"leds", MISC_SIZE); "leds", LED_SIZE);
sysbus_init_mmio(sbd, &s->led_iomem); sysbus_init_mmio(sbd, &s->led_iomem);
/* 32 bit registers */ /* 32 bit registers */
/* System control */ /* System control */
memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s, memory_region_init_io(&s->sysctrl_iomem, OBJECT(s), &slavio_sysctrl_mem_ops, s,
"system-control", MISC_SIZE); "system-control", SYSCTRL_SIZE);
sysbus_init_mmio(sbd, &s->sysctrl_iomem); sysbus_init_mmio(sbd, &s->sysctrl_iomem);
/* AUX 1 (Misc System Functions) */ /* AUX 1 (Misc System Functions) */

View File

@ -82,7 +82,8 @@ void *cpu_physical_memory_map(hwaddr addr,
int is_write); int is_write);
void cpu_physical_memory_unmap(void *buffer, hwaddr len, void cpu_physical_memory_unmap(void *buffer, hwaddr len,
int is_write, hwaddr access_len); int is_write, hwaddr access_len);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)); void cpu_register_map_client(QEMUBH *bh);
void cpu_unregister_map_client(QEMUBH *bh);
bool cpu_physical_memory_is_io(hwaddr phys_addr); bool cpu_physical_memory_is_io(hwaddr phys_addr);

View File

@ -627,6 +627,18 @@ int memory_region_get_fd(MemoryRegion *mr);
*/ */
void *memory_region_get_ram_ptr(MemoryRegion *mr); void *memory_region_get_ram_ptr(MemoryRegion *mr);
/* memory_region_ram_resize: Resize a RAM region.
*
* Only legal before guest might have detected the memory size: e.g. on
* incoming migration, or right after reset.
*
* @mr: a memory region created with @memory_region_init_resizeable_ram.
* @newsize: the new size the region
* @errp: pointer to Error*, to store an error if it happens.
*/
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
Error **errp);
/** /**
* memory_region_set_log: Turn dirty logging on or off for a region. * memory_region_set_log: Turn dirty logging on or off for a region.
* *

View File

@ -68,9 +68,11 @@ extern bool rom_file_has_mr;
int rom_add_file(const char *file, const char *fw_dir, int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex, hwaddr addr, int32_t bootindex,
bool option_rom); bool option_rom);
ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len, MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr, const char *fw_file_name, size_t max_len, hwaddr addr,
FWCfgReadCallback fw_callback, void *callback_opaque); const char *fw_file_name,
FWCfgReadCallback fw_callback,
void *callback_opaque);
int rom_add_elf_program(const char *name, void *data, size_t datasize, int rom_add_elf_program(const char *name, void *data, size_t datasize,
size_t romsize, hwaddr addr); size_t romsize, hwaddr addr);
int rom_load_all(void); int rom_load_all(void);

View File

@ -191,9 +191,14 @@ static uint64_t portio_read(void *opaque, hwaddr addr, unsigned size)
data = mrp->read(mrpio->portio_opaque, mrp->base + addr); data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
} else if (size == 2) { } else if (size == 2) {
mrp = find_portio(mrpio, addr, 1, false); mrp = find_portio(mrpio, addr, 1, false);
assert(mrp); if (mrp) {
data = mrp->read(mrpio->portio_opaque, mrp->base + addr) | data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
(mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8); if (addr + 1 < mrp->offset + mrp->len) {
data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8;
} else {
data |= 0xff00;
}
}
} }
return data; return data;
} }
@ -208,11 +213,14 @@ static void portio_write(void *opaque, hwaddr addr, uint64_t data,
mrp->write(mrpio->portio_opaque, mrp->base + addr, data); mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
} else if (size == 2) { } else if (size == 2) {
mrp = find_portio(mrpio, addr, 1, true); mrp = find_portio(mrpio, addr, 1, true);
assert(mrp); if (mrp) {
mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff); mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
if (addr + 1 < mrp->offset + mrp->len) {
mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8); mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8);
} }
} }
}
}
static const MemoryRegionOps portio_ops = { static const MemoryRegionOps portio_ops = {
.read = portio_read, .read = portio_read,
@ -243,10 +251,6 @@ static void portio_list_add_1(PortioList *piolist,
mrpio->ports[i].base = start + off_low; mrpio->ports[i].base = start + off_low;
} }
/*
* Use an alias so that the callback is called with an absolute address,
* rather than an offset relative to to start + off_low.
*/
memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio, memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio,
piolist->name, off_high - off_low); piolist->name, off_high - off_low);
if (piolist->flush_coalesced_mmio) { if (piolist->flush_coalesced_mmio) {
@ -269,7 +273,7 @@ void portio_list_add(PortioList *piolist,
/* Handle the first entry specially. */ /* Handle the first entry specially. */
off_last = off_low = pio_start->offset; off_last = off_low = pio_start->offset;
off_high = off_low + pio_start->len; off_high = off_low + pio_start->len + pio_start->size - 1;
count = 1; count = 1;
for (pio = pio_start + 1; pio->size != 0; pio++, count++) { for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
@ -284,10 +288,10 @@ void portio_list_add(PortioList *piolist,
/* ... and start collecting anew. */ /* ... and start collecting anew. */
pio_start = pio; pio_start = pio;
off_low = off_last; off_low = off_last;
off_high = off_low + pio->len; off_high = off_low + pio->len + pio_start->size - 1;
count = 0; count = 0;
} else if (off_last + pio->len > off_high) { } else if (off_last + pio->len > off_high) {
off_high = off_last + pio->len; off_high = off_last + pio->len + pio_start->size - 1;
} }
} }

View File

@ -3934,7 +3934,6 @@ int main(int argc, char **argv, char **envp)
#endif #endif
} }
tcg_exec_init(0); tcg_exec_init(0);
cpu_exec_init_all();
/* NOTE: we need to init the CPU at this stage to get /* NOTE: we need to init the CPU at this stage to get
qemu_host_page_size */ qemu_host_page_size */
cpu = cpu_init(cpu_model); cpu = cpu_init(cpu_model);

View File

@ -1523,6 +1523,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK); return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
} }
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp)
{
assert(mr->terminates);
qemu_ram_resize(mr->ram_addr, newsize, errp);
}
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as) static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
{ {
FlatView *view; FlatView *view;

2
nbd.c
View File

@ -681,7 +681,7 @@ int nbd_init(int fd, int csock, uint32_t flags, off_t size)
TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE)); TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / (size_t)BDRV_SECTOR_SIZE) < 0) { if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) {
int serrno = errno; int serrno = errno;
LOG("Failed setting size (in blocks)"); LOG("Failed setting size (in blocks)");
return -serrno; return -serrno;

View File

@ -59,6 +59,7 @@
#include "exec/cputlb.h" #include "exec/cputlb.h"
#include "translate-all.h" #include "translate-all.h"
#include "qemu/bitmap.h"
#include "qemu/timer.h" #include "qemu/timer.h"
//#define DEBUG_TB_INVALIDATE //#define DEBUG_TB_INVALIDATE
@ -79,7 +80,7 @@ typedef struct PageDesc {
/* in order to optimize self modifying code, we count the number /* in order to optimize self modifying code, we count the number
of lookups we do to a given page to use a bitmap */ of lookups we do to a given page to use a bitmap */
unsigned int code_write_count; unsigned int code_write_count;
uint8_t *code_bitmap; unsigned long *code_bitmap;
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
unsigned long flags; unsigned long flags;
#endif #endif
@ -389,18 +390,6 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
void **lp; void **lp;
int i; int i;
#if defined(CONFIG_USER_ONLY)
/* We can't use g_malloc because it may recurse into a locked mutex. */
# define ALLOC(P, SIZE) \
do { \
P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
} while (0)
#else
# define ALLOC(P, SIZE) \
do { P = g_malloc0(SIZE); } while (0)
#endif
/* Level 1. Always allocated. */ /* Level 1. Always allocated. */
lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1)); lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
@ -412,7 +401,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
if (!alloc) { if (!alloc) {
return NULL; return NULL;
} }
ALLOC(p, sizeof(void *) * V_L2_SIZE); p = g_new0(void *, V_L2_SIZE);
*lp = p; *lp = p;
} }
@ -424,12 +413,10 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
if (!alloc) { if (!alloc) {
return NULL; return NULL;
} }
ALLOC(pd, sizeof(PageDesc) * V_L2_SIZE); pd = g_new0(PageDesc, V_L2_SIZE);
*lp = pd; *lp = pd;
} }
#undef ALLOC
return pd + (index & (V_L2_SIZE - 1)); return pd + (index & (V_L2_SIZE - 1));
} }
@ -978,39 +965,12 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
tcg_ctx.tb_ctx.tb_phys_invalidate_count++; tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
} }
static inline void set_bits(uint8_t *tab, int start, int len)
{
int end, mask, end1;
end = start + len;
tab += start >> 3;
mask = 0xff << (start & 7);
if ((start & ~7) == (end & ~7)) {
if (start < end) {
mask &= ~(0xff << (end & 7));
*tab |= mask;
}
} else {
*tab++ |= mask;
start = (start + 8) & ~7;
end1 = end & ~7;
while (start < end1) {
*tab++ = 0xff;
start += 8;
}
if (start < end) {
mask = ~(0xff << (end & 7));
*tab |= mask;
}
}
}
static void build_page_bitmap(PageDesc *p) static void build_page_bitmap(PageDesc *p)
{ {
int n, tb_start, tb_end; int n, tb_start, tb_end;
TranslationBlock *tb; TranslationBlock *tb;
p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8); p->code_bitmap = bitmap_new(TARGET_PAGE_SIZE);
tb = p->first_tb; tb = p->first_tb;
while (tb != NULL) { while (tb != NULL) {
@ -1029,7 +989,7 @@ static void build_page_bitmap(PageDesc *p)
tb_start = 0; tb_start = 0;
tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK); tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
} }
set_bits(p->code_bitmap, tb_start, tb_end - tb_start); bitmap_set(p->code_bitmap, tb_start, tb_end - tb_start);
tb = tb->page_next[n]; tb = tb->page_next[n];
} }
} }
@ -1219,7 +1179,6 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len) void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
{ {
PageDesc *p; PageDesc *p;
int offset, b;
#if 0 #if 0
if (1) { if (1) {
@ -1235,8 +1194,11 @@ void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
return; return;
} }
if (p->code_bitmap) { if (p->code_bitmap) {
offset = start & ~TARGET_PAGE_MASK; unsigned int nr;
b = p->code_bitmap[offset >> 3] >> (offset & 7); unsigned long b;
nr = start & ~TARGET_PAGE_MASK;
b = p->code_bitmap[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG - 1));
if (b & ((1 << len) - 1)) { if (b & ((1 << len) - 1)) {
goto do_invalidate; goto do_invalidate;
} }