#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
+#include "sysemu/qtest.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
unsigned client)
{
DirtyMemoryBlocks *blocks;
- unsigned long end, page;
+ unsigned long end, page, start_page;
bool dirty = false;
RAMBlock *ramblock;
uint64_t mr_offset, mr_size;
}
end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
- page = start >> TARGET_PAGE_BITS;
+ start_page = start >> TARGET_PAGE_BITS;
+ page = start_page;
WITH_RCU_READ_LOCK_GUARD() {
blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
page += num;
}
- mr_offset = (ram_addr_t)(page << TARGET_PAGE_BITS) - ramblock->offset;
- mr_size = (end - page) << TARGET_PAGE_BITS;
+ mr_offset = (ram_addr_t)(start_page << TARGET_PAGE_BITS) - ramblock->offset;
+ mr_size = (end - start_page) << TARGET_PAGE_BITS;
memory_region_clear_dirty_bitmap(ramblock->mr, mr_offset, mr_size);
}
long qemu_minrampagesize(void)
{
long hpsize = LONG_MAX;
- long mainrampagesize;
- Object *memdev_root;
- MachineState *ms = MACHINE(qdev_get_machine());
-
- mainrampagesize = qemu_mempath_getpagesize(mem_path);
-
- /* it's possible we have memory-backend objects with
- * hugepage-backed RAM. these may get mapped into system
- * address space via -numa parameters or memory hotplug
- * hooks. we want to take these into account, but we
- * also want to make sure these supported hugepage
- * sizes are applicable across the entire range of memory
- * we may boot from, so we take the min across all
- * backends, and assume normal pages in cases where a
- * backend isn't backed by hugepages.
- */
- memdev_root = object_resolve_path("/objects", NULL);
- if (memdev_root) {
- object_child_foreach(memdev_root, find_min_backend_pagesize, &hpsize);
- }
- if (hpsize == LONG_MAX) {
- /* No additional memory regions found ==> Report main RAM page size */
- return mainrampagesize;
- }
-
- /* If NUMA is disabled or the NUMA nodes are not backed with a
- * memory-backend, then there is at least one node using "normal" RAM,
- * so if its page size is smaller we have got to report that size instead.
- */
- if (hpsize > mainrampagesize &&
- (ms->numa_state == NULL ||
- ms->numa_state->num_nodes == 0 ||
- ms->numa_state->nodes[0].node_memdev == NULL)) {
- static bool warned;
- if (!warned) {
- error_report("Huge page support disabled (n/a for main memory).");
- warned = true;
- }
- return mainrampagesize;
- }
+ Object *memdev_root = object_resolve_path("/objects", NULL);
+ object_child_foreach(memdev_root, find_min_backend_pagesize, &hpsize);
return hpsize;
}
long qemu_maxrampagesize(void)
{
- long pagesize = qemu_mempath_getpagesize(mem_path);
+ long pagesize = 0;
Object *memdev_root = object_resolve_path("/objects", NULL);
- if (memdev_root) {
- object_child_foreach(memdev_root, find_max_backend_pagesize,
- &pagesize);
- }
+ object_child_foreach(memdev_root, find_max_backend_pagesize, &pagesize);
return pagesize;
}
#else
bool truncate,
Error **errp)
{
- Error *err = NULL;
- MachineState *ms = MACHINE(qdev_get_machine());
void *area;
block->page_size = qemu_fd_getpagesize(fd);
return NULL;
}
- if (mem_prealloc) {
- os_mem_prealloc(fd, area, memory, ms->smp.cpus, &err);
- if (err) {
- error_propagate(errp, err);
- qemu_ram_munmap(fd, area, memory);
- return NULL;
- }
- }
-
block->fd = fd;
return area;
}
*/
void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
{
- void *addr = ramblock_ptr(block, start);
-
/* The requested range should fit in within the block range */
g_assert((start + length) <= block->used_length);
#ifdef CONFIG_LIBPMEM
/* The lack of support for pmem should not block the sync */
if (ramblock_is_pmem(block)) {
+ void *addr = ramblock_ptr(block, start);
pmem_persist(addr, length);
return;
}
* specified as persistent (or is not one) - use the msync.
* Less optimal but still achieves the same goal
*/
+ void *addr = ramblock_ptr(block, start);
if (qemu_msync(addr, length, block->fd)) {
warn_report("%s: failed to sync memory range: start: "
RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
if (new_block->host) {
qemu_ram_setup_dump(new_block->host, new_block->max_length);
qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
- /* MADV_DONTFORK is also needed by KVM in absence of synchronous MMU */
- qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
+ /*
+ * MADV_DONTFORK is also needed by KVM in absence of synchronous MMU
+ * Configure it unless the machine is a qtest server, in which case
+ * KVM is not used and it may be forked (eg for fuzzing purposes).
+ */
+ if (!qtest_enabled()) {
+ qemu_madvise(new_block->host, new_block->max_length,
+ QEMU_MADV_DONTFORK);
+ }
ram_block_notify_add(new_block->host, new_block->max_length);
}
}
size = HOST_PAGE_ALIGN(size);
file_size = get_file_size(fd);
if (file_size > 0 && file_size < size) {
- error_setg(errp, "backing store %s size 0x%" PRIx64
+ error_setg(errp, "backing store size 0x%" PRIx64
" does not match 'size' option 0x" RAM_ADDR_FMT,
- mem_path, file_size, size);
+ file_size, size);
return NULL;
}
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- void *ptr, target_ulong len, int is_write)
+ void *ptr, target_ulong len, bool is_write)
{
int flags;
target_ulong l, page;
}
void cpu_physical_memory_rw(hwaddr addr, void *buf,
- hwaddr len, int is_write)
+ hwaddr len, bool is_write)
{
address_space_rw(&address_space_memory, addr, MEMTXATTRS_UNSPECIFIED,
buf, len, is_write);
void *cpu_physical_memory_map(hwaddr addr,
hwaddr *plen,
- int is_write)
+ bool is_write)
{
return address_space_map(&address_space_memory, addr, plen, is_write,
MEMTXATTRS_UNSPECIFIED);
}
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
- int is_write, hwaddr access_len)
+ bool is_write, hwaddr access_len)
{
return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len);
}
/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- void *ptr, target_ulong len, int is_write)
+ void *ptr, target_ulong len, bool is_write)
{
hwaddr phys_addr;
target_ulong l, page;