master
c 107 lines 2.49 KB
Raw
1 /*
2 * QMP commands to dump physical memory
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "qemu/osdep.h"
11 #include "qapi/error.h"
12 #include "qapi/qapi-commands-machine.h"
13 #include "qapi/qmp/qerror.h"
14 #include "hw/core/cpu.h"
15 #include "system/physmem.h"
16 #include "migration/misc.h"
17
18 void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
19 bool has_cpu, int64_t cpu_index, Error **errp)
20 {
21 FILE *f;
22 uint64_t l;
23 CPUState *cpu;
24 uint8_t buf[1024];
25 uint64_t orig_addr = addr, orig_size = size;
26
27 if (migration_guest_ram_loading()) {
28 error_setg(errp, "Guest memory access not allowed during migration");
29 return;
30 }
31
32 if (!has_cpu) {
33 cpu_index = 0;
34 }
35
36 cpu = qemu_get_cpu(cpu_index);
37 if (cpu == NULL) {
38 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
39 "a CPU number");
40 return;
41 }
42
43 f = fopen(filename, "wb");
44 if (!f) {
45 error_setg_file_open(errp, errno, filename);
46 return;
47 }
48
49 while (size != 0) {
50 l = sizeof(buf);
51 if (l > size) {
52 l = size;
53 }
54 if (cpu_memory_rw_debug(cpu, addr, buf, l, 0) != 0) {
55 error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu64
56 " specified", orig_addr, orig_size);
57 goto exit;
58 }
59 if (fwrite(buf, 1, l, f) != l) {
60 error_setg(errp, "writing memory to '%s' failed",
61 filename);
62 goto exit;
63 }
64 addr += l;
65 size -= l;
66 }
67
68 exit:
69 fclose(f);
70 }
71
72 void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
73 Error **errp)
74 {
75 FILE *f;
76 uint64_t l;
77 uint8_t buf[1024];
78
79 if (migration_guest_ram_loading()) {
80 error_setg(errp, "Guest memory access not allowed during migration");
81 return;
82 }
83
84 f = fopen(filename, "wb");
85 if (!f) {
86 error_setg_file_open(errp, errno, filename);
87 return;
88 }
89
90 while (size != 0) {
91 l = sizeof(buf);
92 if (l > size) {
93 l = size;
94 }
95 physical_memory_read(addr, buf, l);
96 if (fwrite(buf, 1, l, f) != l) {
97 error_setg(errp, "writing memory to '%s' failed",
98 filename);
99 goto exit;
100 }
101 addr += l;
102 size -= l;
103 }
104
105 exit:
106 fclose(f);
107 }