diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-04-30 12:04:11 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-04-30 12:04:11 +0100 |
commit | 06feaacfb4cfef10cc0c93d97df7bfc8a71dbc7e (patch) | |
tree | 2aa3c097c678d2d5dde83d6df450aec28b994452 | |
parent | a1fe58f6ad2282399da256b8579b49b43527e486 (diff) | |
parent | d064d9f381b00538e41f14104b88a1ae85d78865 (diff) | |
download | qemu-06feaacfb4cfef10cc0c93d97df7bfc8a71dbc7e.zip qemu-06feaacfb4cfef10cc0c93d97df7bfc8a71dbc7e.tar.gz qemu-06feaacfb4cfef10cc0c93d97df7bfc8a71dbc7e.tar.bz2 |
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>
-rw-r--r-- | Makefile.target | 2 | ||||
-rw-r--r-- | bsd-user/main.c | 1 | ||||
-rwxr-xr-x | configure | 24 | ||||
-rw-r--r-- | dma-helpers.c | 17 | ||||
-rw-r--r-- | exec.c | 81 | ||||
-rw-r--r-- | hw/audio/gus.c | 20 | ||||
-rw-r--r-- | hw/audio/sb16.c | 7 | ||||
-rw-r--r-- | hw/core/loader.c | 8 | ||||
-rw-r--r-- | hw/display/Makefile.objs | 2 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 36 | ||||
-rw-r--r-- | hw/ide/core.c | 4 | ||||
-rw-r--r-- | hw/intc/apic_common.c | 9 | ||||
-rw-r--r-- | hw/misc/slavio_misc.c | 5 | ||||
-rw-r--r-- | include/exec/cpu-common.h | 3 | ||||
-rw-r--r-- | include/exec/memory.h | 12 | ||||
-rw-r--r-- | include/hw/loader.h | 8 | ||||
-rw-r--r-- | ioport.c | 30 | ||||
-rw-r--r-- | linux-user/main.c | 1 | ||||
-rw-r--r-- | memory.c | 7 | ||||
-rw-r--r-- | nbd.c | 2 | ||||
-rw-r--r-- | translate-all.c | 60 |
21 files changed, 168 insertions, 171 deletions
diff --git a/Makefile.target b/Makefile.target index 2262d89..1083377 100644 --- a/Makefile.target +++ b/Makefile.target @@ -134,7 +134,7 @@ obj-$(CONFIG_KVM) += kvm-all.o obj-y += memory.o savevm.o cputlb.o obj-y += memory_mapping.o obj-y += dump.o -LIBS+=$(libs_softmmu) +LIBS := $(libs_softmmu) $(LIBS) # xen support obj-$(CONFIG_XEN) += xen-common.o diff --git a/bsd-user/main.c b/bsd-user/main.c index 1bb2754..5bfaf5c 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -905,7 +905,6 @@ int main(int argc, char **argv) #endif } tcg_exec_init(0); - cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ cpu = cpu_init(cpu_model); @@ -336,6 +336,7 @@ libssh2="" vhdx="" quorum="" numa="" +tcmalloc="no" # parse CC options first for opt do @@ -1134,6 +1135,10 @@ for opt do ;; --enable-numa) numa="yes" ;; + --disable-tcmalloc) tcmalloc="no" + ;; + --enable-tcmalloc) tcmalloc="yes" + ;; *) echo "ERROR: unknown option $opt" echo "Try '$0 --help' for more information" @@ -1407,6 +1412,8 @@ Advanced options (experts only): --enable-quorum enable quorum block filter support --disable-numa disable 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 EOF @@ -3331,6 +3338,22 @@ EOF 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="no" cat > $TMPC << EOF @@ -4441,6 +4464,7 @@ echo "lzo support $lzo" echo "snappy support $snappy" echo "bzip2 support $bzip2" echo "NUMA host support $numa" +echo "tcmalloc support $tcmalloc" if test "$sdl_too_old" = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" diff --git a/dma-helpers.c b/dma-helpers.c index 33b1983..19901a8 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -93,14 +93,6 @@ static void reschedule_dma(void *opaque) 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) { int i; @@ -162,7 +154,9 @@ static void dma_blk_cb(void *opaque, int ret) if (dbs->iov.size == 0) { 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; } @@ -184,6 +178,11 @@ static void dma_aio_cancel(BlockAIOCB *acb) if (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; + } } @@ -380,7 +380,6 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, IOMMUTLBEntry iotlb; MemoryRegionSection *section; MemoryRegion *mr; - hwaddr len = *plen; rcu_read_lock(); for (;;) { @@ -395,7 +394,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, iotlb = mr->iommu_ops->translate(mr, addr, is_write); addr = ((iotlb.translated_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))) { mr = &io_mem_unassigned; break; @@ -406,10 +405,9 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, if (xen_enabled() && memory_access_is_direct(mr, is_write)) { hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; - len = MIN(page, len); + *plen = MIN(page, *plen); } - *plen = len; *xlat = addr; rcu_read_unlock(); return mr; @@ -429,15 +427,6 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, } #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) static int cpu_common_post_load(void *opaque, int version_id) @@ -2518,46 +2507,77 @@ typedef struct { void *buffer; hwaddr addr; hwaddr len; + bool in_use; } BounceBuffer; static BounceBuffer bounce; typedef struct MapClient { - void *opaque; - void (*callback)(void *opaque); + QEMUBH *bh; QLIST_ENTRY(MapClient) link; } MapClient; +QemuMutex map_client_list_lock; static QLIST_HEAD(map_client_list, MapClient) 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) +{ + QLIST_REMOVE(client, link); + g_free(client); +} + +static void cpu_notify_map_clients_locked(void) +{ + MapClient *client; + + while (!QLIST_EMPTY(&map_client_list)) { + client = QLIST_FIRST(&map_client_list); + qemu_bh_schedule(client->bh); + cpu_unregister_map_client_do(client); + } +} + +void cpu_register_map_client(QEMUBH *bh) { MapClient *client = g_malloc(sizeof(*client)); - client->opaque = opaque; - client->callback = callback; + qemu_mutex_lock(&map_client_list_lock); + client->bh = bh; QLIST_INSERT_HEAD(&map_client_list, client, link); - return client; + if (!atomic_read(&bounce.in_use)) { + cpu_notify_map_clients_locked(); + } + qemu_mutex_unlock(&map_client_list_lock); } -static void cpu_unregister_map_client(void *_client) +void cpu_exec_init_all(void) { - MapClient *client = (MapClient *)_client; - - QLIST_REMOVE(client, link); - g_free(client); + qemu_mutex_init(&ram_list.mutex); + memory_map_init(); + io_mem_init(); + qemu_mutex_init(&map_client_list_lock); } -static void cpu_notify_map_clients(void) +void cpu_unregister_map_client(QEMUBH *bh) { MapClient *client; - while (!QLIST_EMPTY(&map_client_list)) { - client = QLIST_FIRST(&map_client_list); - client->callback(client->opaque); - cpu_unregister_map_client(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) @@ -2606,7 +2626,7 @@ void *address_space_map(AddressSpace *as, l = len; mr = address_space_translate(as, addr, &xlat, &l, is_write); if (!memory_access_is_direct(mr, is_write)) { - if (bounce.buffer) { + if (atomic_xchg(&bounce.in_use, true)) { return NULL; } /* Avoid unbounded allocations */ @@ -2678,6 +2698,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, qemu_vfree(bounce.buffer); bounce.buffer = NULL; memory_region_unref(bounce.mr); + atomic_mb_set(&bounce.in_use, false); cpu_notify_map_clients(); } diff --git a/hw/audio/gus.c b/hw/audio/gus.c index 4a43ce7..86223a9 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -71,13 +71,6 @@ IO_READ_PROTO (gus_readb) 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) { GUSState *s = opaque; @@ -85,13 +78,6 @@ IO_WRITE_PROTO (gus_writeb) 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) { int net = 0; @@ -236,17 +222,13 @@ static const VMStateDescription vmstate_gus = { static const MemoryRegionPortio gus_portio_list1[] = { {0x000, 1, 1, .write = gus_writeb }, - {0x000, 1, 2, .write = gus_writew }, {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, 2, .read = gus_readw, .write = gus_writew }, PORTIO_END_OF_LIST (), }; static const MemoryRegionPortio gus_portio_list2[] = { - {0, 1, 1, .read = gus_readb }, - {0, 1, 2, .read = gus_readw }, + {0, 2, 1, .read = gus_readb }, PORTIO_END_OF_LIST (), }; diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 444eb9e..b052de5 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1121,12 +1121,6 @@ static IO_WRITE_PROTO (mixer_write_datab) 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) { SB16State *s = opaque; @@ -1345,7 +1339,6 @@ static const VMStateDescription vmstate_sb16 = { static const MemoryRegionPortio sb16_ioport_list[] = { { 4, 1, 1, .write = mixer_write_indexb }, - { 4, 1, 2, .write = mixer_write_indexw }, { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab }, { 6, 1, 1, .read = dsp_read, .write = dsp_write }, { 10, 1, 1, .read = dsp_read }, diff --git a/hw/core/loader.c b/hw/core/loader.c index d4c441f..7ee675c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -835,12 +835,12 @@ err: 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, FWCfgReadCallback fw_callback, void *callback_opaque) { Rom *rom; - ram_addr_t ret = RAM_ADDR_MAX; + MemoryRegion *mr = NULL; rom = g_malloc0(sizeof(*rom)); 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) { data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); - ret = memory_region_get_ram_addr(rom->mr); + mr = rom->mr; } else { 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, data, rom->datasize); } - return ret; + return mr; } /* This function is specific for elf program because we don't need to allocate diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index e73cb7d..3ea106d 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -21,7 +21,7 @@ common-obj-$(CONFIG_ZAURUS) += tc6393xb.o ifeq ($(CONFIG_MILKYMIST_TMU2),y) common-obj-y += milkymist-tmu2.o milkymist-tmu2.o-cflags := $(OPENGL_CFLAGS) -libs_softmmu += $(OPENGL_LIBS) +milkymist-tmu2.o-libs += $(OPENGL_LIBS) endif obj-$(CONFIG_OMAP) += omap_dss.o diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e761005..2aaf21a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -58,7 +58,6 @@ #include "qapi/qmp/qint.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 * -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 struct AcpiBuildState { /* Copy of table in RAM (for patching). */ - ram_addr_t table_ram; + MemoryRegion *table_mr; /* Is table patched? */ uint8_t patched; PcGuestInfo *guest_info; void *rsdp; - ram_addr_t rsdp_ram; - ram_addr_t linker_ram; + MemoryRegion *rsdp_mr; + MemoryRegion *linker_mr; } AcpiBuildState; 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); } -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); /* 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); - cpu_physical_memory_set_dirty_range_nocode(ram, size); + memcpy(memory_region_get_ram_ptr(mr), data->data, size); + memory_region_set_dirty(mr, 0, size); } 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_ram_update(build_state->table_ram, tables.table_data); + acpi_ram_update(build_state->table_mr, tables.table_data); if (build_state->rsdp) { memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); } 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); } @@ -1557,8 +1556,9 @@ static void acpi_build_reset(void *build_opaque) build_state->patched = 0; } -static ram_addr_t acpi_add_rom_blob(AcpiBuildState *build_state, GArray *blob, - const char *name, uint64_t max_size) +static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state, + GArray *blob, const char *name, + uint64_t max_size) { return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1, name, acpi_build_update, build_state); @@ -1604,12 +1604,12 @@ void acpi_setup(PcGuestInfo *guest_info) acpi_build(build_state->guest_info, &tables); /* 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_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); 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, acpi_build_update, build_state, build_state->rsdp, rsdp_size); - build_state->rsdp_ram = (ram_addr_t)-1; + build_state->rsdp_mr = NULL; } else { 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); } diff --git a/hw/ide/core.c b/hw/ide/core.c index a895fd8..fcb9080 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2436,8 +2436,8 @@ void ide_init2(IDEBus *bus, qemu_irq irq) static const MemoryRegionPortio ide_portio_list[] = { { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, - { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew }, - { 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel }, + { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew }, + { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel }, PORTIO_END_OF_LIST(), }; diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 042e960..d38d24b 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -243,15 +243,6 @@ static void apic_reset_common(DeviceState *dev) info->vapic_base_update(s); 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 */ diff --git a/hw/misc/slavio_misc.c b/hw/misc/slavio_misc.c index 5098595..ec50f10 100644 --- a/hw/misc/slavio_misc.c +++ b/hw/misc/slavio_misc.c @@ -68,6 +68,7 @@ typedef struct APCState { } APCState; #define MISC_SIZE 1 +#define LED_SIZE 2 #define SYSCTRL_SIZE 4 #define AUX1_TC 0x02 @@ -452,13 +453,13 @@ static int slavio_misc_init1(SysBusDevice *sbd) /* 16 bit registers */ /* ss600mp diag LEDs */ 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); /* 32 bit registers */ /* System control */ 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); /* AUX 1 (Misc System Functions) */ diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index fcc3162..43428bd 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -82,7 +82,8 @@ void *cpu_physical_memory_map(hwaddr addr, int is_write); void cpu_physical_memory_unmap(void *buffer, hwaddr 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); diff --git a/include/exec/memory.h b/include/exec/memory.h index 2f386ce..0ccfd3b 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -627,6 +627,18 @@ int memory_region_get_fd(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. * diff --git a/include/hw/loader.h b/include/hw/loader.h index 4f0681b..485ff8f 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -68,9 +68,11 @@ extern bool rom_file_has_mr; int rom_add_file(const char *file, const char *fw_dir, hwaddr addr, int32_t bootindex, bool option_rom); -ram_addr_t rom_add_blob(const char *name, const void *blob, size_t len, - size_t max_len, hwaddr addr, const char *fw_file_name, - FWCfgReadCallback fw_callback, void *callback_opaque); +MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len, + size_t max_len, hwaddr addr, + const char *fw_file_name, + FWCfgReadCallback fw_callback, + void *callback_opaque); int rom_add_elf_program(const char *name, void *data, size_t datasize, size_t romsize, hwaddr addr); int rom_load_all(void); @@ -191,9 +191,14 @@ static uint64_t portio_read(void *opaque, hwaddr addr, unsigned size) data = mrp->read(mrpio->portio_opaque, mrp->base + addr); } else if (size == 2) { mrp = find_portio(mrpio, addr, 1, false); - assert(mrp); - data = mrp->read(mrpio->portio_opaque, mrp->base + addr) | - (mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8); + if (mrp) { + data = mrp->read(mrpio->portio_opaque, mrp->base + addr); + if (addr + 1 < mrp->offset + mrp->len) { + data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8; + } else { + data |= 0xff00; + } + } } return data; } @@ -208,9 +213,12 @@ static void portio_write(void *opaque, hwaddr addr, uint64_t data, mrp->write(mrpio->portio_opaque, mrp->base + addr, data); } else if (size == 2) { mrp = find_portio(mrpio, addr, 1, true); - assert(mrp); - mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff); - mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8); + if (mrp) { + 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); + } + } } } @@ -243,10 +251,6 @@ static void portio_list_add_1(PortioList *piolist, 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, piolist->name, off_high - off_low); if (piolist->flush_coalesced_mmio) { @@ -269,7 +273,7 @@ void portio_list_add(PortioList *piolist, /* Handle the first entry specially. */ 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; for (pio = pio_start + 1; pio->size != 0; pio++, count++) { @@ -284,10 +288,10 @@ void portio_list_add(PortioList *piolist, /* ... and start collecting anew. */ pio_start = pio; off_low = off_last; - off_high = off_low + pio->len; + off_high = off_low + pio->len + pio_start->size - 1; count = 0; } else if (off_last + pio->len > off_high) { - off_high = off_last + pio->len; + off_high = off_last + pio->len + pio_start->size - 1; } } diff --git a/linux-user/main.c b/linux-user/main.c index a8adb04..3f32db0 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3934,7 +3934,6 @@ int main(int argc, char **argv, char **envp) #endif } tcg_exec_init(0); - cpu_exec_init_all(); /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ cpu = cpu_init(cpu_model); @@ -1523,6 +1523,13 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr) 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) { FlatView *view; @@ -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)); - 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; LOG("Failed setting size (in blocks)"); return -serrno; diff --git a/translate-all.c b/translate-all.c index 11763c6..65a76c5 100644 --- a/translate-all.c +++ b/translate-all.c @@ -59,6 +59,7 @@ #include "exec/cputlb.h" #include "translate-all.h" +#include "qemu/bitmap.h" #include "qemu/timer.h" //#define DEBUG_TB_INVALIDATE @@ -79,7 +80,7 @@ typedef struct PageDesc { /* in order to optimize self modifying code, we count the number of lookups we do to a given page to use a bitmap */ unsigned int code_write_count; - uint8_t *code_bitmap; + unsigned long *code_bitmap; #if defined(CONFIG_USER_ONLY) unsigned long flags; #endif @@ -389,18 +390,6 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc) void **lp; 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. */ 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) { return NULL; } - ALLOC(p, sizeof(void *) * V_L2_SIZE); + p = g_new0(void *, V_L2_SIZE); *lp = p; } @@ -424,12 +413,10 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc) if (!alloc) { return NULL; } - ALLOC(pd, sizeof(PageDesc) * V_L2_SIZE); + pd = g_new0(PageDesc, V_L2_SIZE); *lp = pd; } -#undef ALLOC - 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++; } -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) { int n, tb_start, tb_end; TranslationBlock *tb; - p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8); + p->code_bitmap = bitmap_new(TARGET_PAGE_SIZE); tb = p->first_tb; while (tb != NULL) { @@ -1029,7 +989,7 @@ static void build_page_bitmap(PageDesc *p) tb_start = 0; 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]; } } @@ -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) { PageDesc *p; - int offset, b; #if 0 if (1) { @@ -1235,8 +1194,11 @@ void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len) return; } if (p->code_bitmap) { - offset = start & ~TARGET_PAGE_MASK; - b = p->code_bitmap[offset >> 3] >> (offset & 7); + unsigned int nr; + 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)) { goto do_invalidate; } |