#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/target_page.h"
-#include "tcg.h"
+#include "tcg/tcg.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#if !defined(CONFIG_USER_ONLY)
#include "exec/ram_addr.h"
#include "exec/log.h"
+#include "qemu/pmem.h"
+
#include "migration/vmstate.h"
#include "qemu/range.h"
fprintf(stderr, "\n");
cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP);
if (qemu_log_separate()) {
- qemu_log_lock();
+ FILE *logfile = qemu_log_lock();
qemu_log("qemu: fatal: ");
qemu_log_vprintf(fmt, ap2);
qemu_log("\n");
log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
qemu_log_flush();
- qemu_log_unlock();
+ qemu_log_unlock(logfile);
qemu_log_close();
}
va_end(ap2);
bool truncate,
Error **errp)
{
+ Error *err = NULL;
MachineState *ms = MACHINE(qdev_get_machine());
void *area;
}
if (mem_prealloc) {
- os_mem_prealloc(fd, area, memory, ms->smp.cpus, errp);
- if (errp && *errp) {
+ os_mem_prealloc(fd, area, memory, ms->smp.cpus, &err);
+ if (err) {
+ error_propagate(errp, err);
qemu_ram_munmap(fd, area, memory);
return NULL;
}
return 0;
}
+/*
+ * Trigger sync on the given ram block for range [start, start + length]
+ * with the backing store if one is available.
+ * Otherwise no-op.
+ * @Note: this is supposed to be a synchronous op.
+ */
+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)) {
+ pmem_persist(addr, length);
+ return;
+ }
+#endif
+ if (block->fd >= 0) {
+ /**
+ * Case there is no support for PMEM or the memory has not been
+ * specified as persistent (or is not one) - use the msync.
+ * Less optimal but still achieves the same goal
+ */
+ if (qemu_msync(addr, length, block->fd)) {
+ warn_report("%s: failed to sync memory range: start: "
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
+ __func__, start, length);
+ }
+ }
+}
+
/* Called with ram_list.mutex held */
static void dirty_memory_extend(ram_addr_t old_ram_size,
ram_addr_t new_ram_size)
uint8_t *host_startaddr = rb->host + start;
- if ((uintptr_t)host_startaddr & (rb->page_size - 1)) {
+ if (!QEMU_PTR_IS_ALIGNED(host_startaddr, rb->page_size)) {
error_report("ram_block_discard_range: Unaligned start address: %p",
host_startaddr);
goto err;
if ((start + length) <= rb->used_length) {
bool need_madvise, need_fallocate;
- uint8_t *host_endaddr = host_startaddr + length;
- if ((uintptr_t)host_endaddr & (rb->page_size - 1)) {
- error_report("ram_block_discard_range: Unaligned end address: %p",
- host_endaddr);
+ if (!QEMU_IS_ALIGNED(length, rb->page_size)) {
+ error_report("ram_block_discard_range: Unaligned length: %zx",
+ length);
goto err;
}