dump patches
Hi Includes: - the first patches from "[PATCH v5 00/18] dump: Add arch section and s390x PV dump" - "[PATCH v2 0/2] Fix dumping in kdump format with non-aligned memory" -----BEGIN PGP SIGNATURE----- iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmM+9UocHG1hcmNhbmRy ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5aoMD/0eya5IqxX0ke9jjUcB wWhRbsVdiO9yt2oN3gsQVkUtuK98p7/JpWSKHWXsQQjd7vIYPCj8RBHXZ4Cp71+S n+Db/K22fmWvuP0LtCNzYujq1ZxKdQI8KdKmYwHQdGkgy85QwYO+0SgpVgLjRd/2 1IWzHuzIcEmraxkSLvR8N0lmz/Z2CBc7ME5izO1mHSZrs8Ria2tDpXnz5rFxPy+q TDqo+LP0GIapoHbbE+6JWGL2u9mLiP0sg9SclZOPZG3CsPQ5XYEStyZcLw1YYIO1 rruom463SbP4NJHIRspC8pADFI+d4uBamj/eUu8/9CUVqetk0UpKyXWiqgEDvmkO /2/yFYS60gEghvd3XVnuZnTNeRSDSE1aUXUmKdGqDjYL4DYcsehIQ9z8ut/tuYIO D+4RuiuCmEyznV/DDecnwHhrv9jWftNwdwjW5GAniEjDBp/DtoouAeMArQw9rE1Z mXqTa5NaeW69VTtzxzN25GzSAjiEzFT7UFRt3bT8fb0NX+UOkluD/agBqRIM5lzh KbUJjqWhqA6TnHtDekbNLlmocDCn+NeBeXxDUIa19C4LICCuuxbFU+MG7cvdjSEg sXRB6/qAdWgv4O3zGw1SHff+qmvtHjKVj0ihrNkrrYrL+31O2splqTMeaCqGdq9C elE/TAS46CcMUSYuWzxy6mAMmA== =O9tr -----END PGP SIGNATURE----- Merge tag 'dump-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging dump patches Hi Includes: - the first patches from "[PATCH v5 00/18] dump: Add arch section and s390x PV dump" - "[PATCH v2 0/2] Fix dumping in kdump format with non-aligned memory" # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmM+9UocHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5aoMD/0eya5IqxX0ke9jjUcB # wWhRbsVdiO9yt2oN3gsQVkUtuK98p7/JpWSKHWXsQQjd7vIYPCj8RBHXZ4Cp71+S # n+Db/K22fmWvuP0LtCNzYujq1ZxKdQI8KdKmYwHQdGkgy85QwYO+0SgpVgLjRd/2 # 1IWzHuzIcEmraxkSLvR8N0lmz/Z2CBc7ME5izO1mHSZrs8Ria2tDpXnz5rFxPy+q # TDqo+LP0GIapoHbbE+6JWGL2u9mLiP0sg9SclZOPZG3CsPQ5XYEStyZcLw1YYIO1 # rruom463SbP4NJHIRspC8pADFI+d4uBamj/eUu8/9CUVqetk0UpKyXWiqgEDvmkO # /2/yFYS60gEghvd3XVnuZnTNeRSDSE1aUXUmKdGqDjYL4DYcsehIQ9z8ut/tuYIO # D+4RuiuCmEyznV/DDecnwHhrv9jWftNwdwjW5GAniEjDBp/DtoouAeMArQw9rE1Z # mXqTa5NaeW69VTtzxzN25GzSAjiEzFT7UFRt3bT8fb0NX+UOkluD/agBqRIM5lzh # KbUJjqWhqA6TnHtDekbNLlmocDCn+NeBeXxDUIa19C4LICCuuxbFU+MG7cvdjSEg # sXRB6/qAdWgv4O3zGw1SHff+qmvtHjKVj0ihrNkrrYrL+31O2splqTMeaCqGdq9C # elE/TAS46CcMUSYuWzxy6mAMmA== # =O9tr # -----END PGP SIGNATURE----- # gpg: Signature made Thu 06 Oct 2022 11:33:30 EDT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'dump-pull-request' of https://gitlab.com/marcandre.lureau/qemu: dump: fix kdump to work over non-aligned blocks dump: simplify a bit kdump get_next_page() dump: Rename write_elf*_phdr_note to prepare_elf*_phdr_note dump: Split elf header functions into prepare and write dump: Rework dump_calculate_size function dump: Rework filter area variables dump: Rework get_start_block dump: Refactor dump_iterate and introduce dump_filter_memblock_*() dump: Rename write_elf_loads to write_elf_phdr_loads dump: Replace opaque DumpState pointer with a typed one Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
42e1e350bf
371
dump/dump.c
371
dump/dump.c
@ -59,6 +59,11 @@ static inline bool dump_is_64bit(DumpState *s)
|
||||
return s->dump_info.d_class == ELFCLASS64;
|
||||
}
|
||||
|
||||
static inline bool dump_has_filter(DumpState *s)
|
||||
{
|
||||
return s->filter_area_length > 0;
|
||||
}
|
||||
|
||||
uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
|
||||
{
|
||||
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||
@ -126,7 +131,7 @@ static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_elf64_header(DumpState *s, Error **errp)
|
||||
static void prepare_elf64_header(DumpState *s, Elf64_Ehdr *elf_header)
|
||||
{
|
||||
/*
|
||||
* phnum in the elf header is 16 bit, if we have more segments we
|
||||
@ -134,34 +139,27 @@ static void write_elf64_header(DumpState *s, Error **errp)
|
||||
* special section.
|
||||
*/
|
||||
uint16_t phnum = MIN(s->phdr_num, PN_XNUM);
|
||||
Elf64_Ehdr elf_header;
|
||||
int ret;
|
||||
|
||||
memset(&elf_header, 0, sizeof(Elf64_Ehdr));
|
||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||
elf_header.e_ident[EI_CLASS] = ELFCLASS64;
|
||||
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header.e_phoff = cpu_to_dump64(s, s->phdr_offset);
|
||||
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
|
||||
elf_header.e_phnum = cpu_to_dump16(s, phnum);
|
||||
memset(elf_header, 0, sizeof(Elf64_Ehdr));
|
||||
memcpy(elf_header, ELFMAG, SELFMAG);
|
||||
elf_header->e_ident[EI_CLASS] = ELFCLASS64;
|
||||
elf_header->e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header->e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header->e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header->e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header->e_phoff = cpu_to_dump64(s, s->phdr_offset);
|
||||
elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
|
||||
elf_header->e_phnum = cpu_to_dump16(s, phnum);
|
||||
if (s->shdr_num) {
|
||||
elf_header.e_shoff = cpu_to_dump64(s, s->shdr_offset);
|
||||
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
|
||||
elf_header.e_shnum = cpu_to_dump16(s, s->shdr_num);
|
||||
}
|
||||
|
||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "dump: failed to write elf header");
|
||||
elf_header->e_shoff = cpu_to_dump64(s, s->shdr_offset);
|
||||
elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
|
||||
elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_elf32_header(DumpState *s, Error **errp)
|
||||
static void prepare_elf32_header(DumpState *s, Elf32_Ehdr *elf_header)
|
||||
{
|
||||
/*
|
||||
* phnum in the elf header is 16 bit, if we have more segments we
|
||||
@ -169,28 +167,45 @@ static void write_elf32_header(DumpState *s, Error **errp)
|
||||
* special section.
|
||||
*/
|
||||
uint16_t phnum = MIN(s->phdr_num, PN_XNUM);
|
||||
Elf32_Ehdr elf_header;
|
||||
|
||||
memset(elf_header, 0, sizeof(Elf32_Ehdr));
|
||||
memcpy(elf_header, ELFMAG, SELFMAG);
|
||||
elf_header->e_ident[EI_CLASS] = ELFCLASS32;
|
||||
elf_header->e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header->e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header->e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header->e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header->e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header->e_phoff = cpu_to_dump32(s, s->phdr_offset);
|
||||
elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
|
||||
elf_header->e_phnum = cpu_to_dump16(s, phnum);
|
||||
if (s->shdr_num) {
|
||||
elf_header->e_shoff = cpu_to_dump32(s, s->shdr_offset);
|
||||
elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
|
||||
elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_elf_header(DumpState *s, Error **errp)
|
||||
{
|
||||
Elf32_Ehdr elf32_header;
|
||||
Elf64_Ehdr elf64_header;
|
||||
size_t header_size;
|
||||
void *header_ptr;
|
||||
int ret;
|
||||
|
||||
memset(&elf_header, 0, sizeof(Elf32_Ehdr));
|
||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||
elf_header.e_ident[EI_CLASS] = ELFCLASS32;
|
||||
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||
elf_header.e_phoff = cpu_to_dump32(s, s->phdr_offset);
|
||||
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
|
||||
elf_header.e_phnum = cpu_to_dump16(s, phnum);
|
||||
if (s->shdr_num) {
|
||||
elf_header.e_shoff = cpu_to_dump32(s, s->shdr_offset);
|
||||
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
|
||||
elf_header.e_shnum = cpu_to_dump16(s, s->shdr_num);
|
||||
if (dump_is_64bit(s)) {
|
||||
prepare_elf64_header(s, &elf64_header);
|
||||
header_size = sizeof(elf64_header);
|
||||
header_ptr = &elf64_header;
|
||||
} else {
|
||||
prepare_elf32_header(s, &elf32_header);
|
||||
header_size = sizeof(elf32_header);
|
||||
header_ptr = &elf32_header;
|
||||
}
|
||||
|
||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||
ret = fd_write_vmcore(header_ptr, header_size, s);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "dump: failed to write elf header");
|
||||
}
|
||||
@ -245,7 +260,7 @@ static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_elf64_phdr_note(DumpState *s, Elf64_Phdr *phdr)
|
||||
static void prepare_elf64_phdr_note(DumpState *s, Elf64_Phdr *phdr)
|
||||
{
|
||||
memset(phdr, 0, sizeof(*phdr));
|
||||
phdr->p_type = cpu_to_dump32(s, PT_NOTE);
|
||||
@ -301,7 +316,7 @@ static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
|
||||
write_guest_note(f, s, errp);
|
||||
}
|
||||
|
||||
static void write_elf32_phdr_note(DumpState *s, Elf32_Phdr *phdr)
|
||||
static void prepare_elf32_phdr_note(DumpState *s, Elf32_Phdr *phdr)
|
||||
{
|
||||
memset(phdr, 0, sizeof(*phdr));
|
||||
phdr->p_type = cpu_to_dump32(s, PT_NOTE);
|
||||
@ -349,11 +364,11 @@ static void write_elf_phdr_note(DumpState *s, Error **errp)
|
||||
int ret;
|
||||
|
||||
if (dump_is_64bit(s)) {
|
||||
write_elf64_phdr_note(s, &phdr64);
|
||||
prepare_elf64_phdr_note(s, &phdr64);
|
||||
size = sizeof(phdr64);
|
||||
phdr = &phdr64;
|
||||
} else {
|
||||
write_elf32_phdr_note(s, &phdr32);
|
||||
prepare_elf32_phdr_note(s, &phdr32);
|
||||
size = sizeof(phdr32);
|
||||
phdr = &phdr32;
|
||||
}
|
||||
@ -443,29 +458,30 @@ static void get_offset_range(hwaddr phys_addr,
|
||||
*p_offset = -1;
|
||||
*p_filesz = 0;
|
||||
|
||||
if (s->has_filter) {
|
||||
if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
|
||||
if (dump_has_filter(s)) {
|
||||
if (phys_addr < s->filter_area_begin ||
|
||||
phys_addr >= s->filter_area_begin + s->filter_area_length) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||
if (s->has_filter) {
|
||||
if (block->target_start >= s->begin + s->length ||
|
||||
block->target_end <= s->begin) {
|
||||
if (dump_has_filter(s)) {
|
||||
if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
|
||||
block->target_end <= s->filter_area_begin) {
|
||||
/* This block is out of the range */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->begin <= block->target_start) {
|
||||
if (s->filter_area_begin <= block->target_start) {
|
||||
start = block->target_start;
|
||||
} else {
|
||||
start = s->begin;
|
||||
start = s->filter_area_begin;
|
||||
}
|
||||
|
||||
size_in_block = block->target_end - start;
|
||||
if (s->begin + s->length < block->target_end) {
|
||||
size_in_block -= block->target_end - (s->begin + s->length);
|
||||
if (s->filter_area_begin + s->filter_area_length < block->target_end) {
|
||||
size_in_block -= block->target_end - (s->filter_area_begin + s->filter_area_length);
|
||||
}
|
||||
} else {
|
||||
start = block->target_start;
|
||||
@ -490,7 +506,7 @@ static void get_offset_range(hwaddr phys_addr,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_elf_loads(DumpState *s, Error **errp)
|
||||
static void write_elf_phdr_loads(DumpState *s, Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
hwaddr offset, filesz;
|
||||
@ -558,11 +574,7 @@ static void dump_begin(DumpState *s, Error **errp)
|
||||
*/
|
||||
|
||||
/* write elf header to vmcore */
|
||||
if (dump_is_64bit(s)) {
|
||||
write_elf64_header(s, errp);
|
||||
} else {
|
||||
write_elf32_header(s, errp);
|
||||
}
|
||||
write_elf_header(s, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
@ -573,8 +585,8 @@ static void dump_begin(DumpState *s, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
/* write all PT_LOAD to vmcore */
|
||||
write_elf_loads(s, errp);
|
||||
/* write all PT_LOADs to vmcore */
|
||||
write_elf_phdr_loads(s, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
@ -591,31 +603,43 @@ static void dump_begin(DumpState *s, Error **errp)
|
||||
write_elf_notes(s, errp);
|
||||
}
|
||||
|
||||
static int get_next_block(DumpState *s, GuestPhysBlock *block)
|
||||
static int64_t dump_filtered_memblock_size(GuestPhysBlock *block,
|
||||
int64_t filter_area_start,
|
||||
int64_t filter_area_length)
|
||||
{
|
||||
while (1) {
|
||||
block = QTAILQ_NEXT(block, next);
|
||||
if (!block) {
|
||||
/* no more block */
|
||||
return 1;
|
||||
}
|
||||
int64_t size, left, right;
|
||||
|
||||
s->start = 0;
|
||||
s->next_block = block;
|
||||
if (s->has_filter) {
|
||||
if (block->target_start >= s->begin + s->length ||
|
||||
block->target_end <= s->begin) {
|
||||
/* This block is out of the range */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->begin > block->target_start) {
|
||||
s->start = s->begin - block->target_start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* No filter, return full size */
|
||||
if (!filter_area_length) {
|
||||
return block->target_end - block->target_start;
|
||||
}
|
||||
|
||||
/* calculate the overlapped region. */
|
||||
left = MAX(filter_area_start, block->target_start);
|
||||
right = MIN(filter_area_start + filter_area_length, block->target_end);
|
||||
size = right - left;
|
||||
size = size > 0 ? size : 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int64_t dump_filtered_memblock_start(GuestPhysBlock *block,
|
||||
int64_t filter_area_start,
|
||||
int64_t filter_area_length)
|
||||
{
|
||||
if (filter_area_length) {
|
||||
/* return -1 if the block is not within filter area */
|
||||
if (block->target_start >= filter_area_start + filter_area_length ||
|
||||
block->target_end <= filter_area_start) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (filter_area_start > block->target_start) {
|
||||
return filter_area_start - block->target_start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write all memory to vmcore */
|
||||
@ -623,24 +647,22 @@ static void dump_iterate(DumpState *s, Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
GuestPhysBlock *block;
|
||||
int64_t size;
|
||||
int64_t memblock_size, memblock_start;
|
||||
|
||||
do {
|
||||
block = s->next_block;
|
||||
|
||||
size = block->target_end - block->target_start;
|
||||
if (s->has_filter) {
|
||||
size -= s->start;
|
||||
if (s->begin + s->length < block->target_end) {
|
||||
size -= block->target_end - (s->begin + s->length);
|
||||
}
|
||||
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||
memblock_start = dump_filtered_memblock_start(block, s->filter_area_begin, s->filter_area_length);
|
||||
if (memblock_start == -1) {
|
||||
continue;
|
||||
}
|
||||
write_memory(s, block, s->start, size, errp);
|
||||
|
||||
memblock_size = dump_filtered_memblock_size(block, s->filter_area_begin, s->filter_area_length);
|
||||
|
||||
/* Write the memory to file */
|
||||
write_memory(s, block, memblock_start, memblock_size, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
|
||||
} while (!get_next_block(s, block));
|
||||
}
|
||||
}
|
||||
|
||||
static void create_vmcore(DumpState *s, Error **errp)
|
||||
@ -1094,55 +1116,81 @@ static uint64_t dump_pfn_to_paddr(DumpState *s, uint64_t pfn)
|
||||
}
|
||||
|
||||
/*
|
||||
* exam every page and return the page frame number and the address of the page.
|
||||
* bufptr can be NULL. note: the blocks here is supposed to reflect guest-phys
|
||||
* blocks, so block->target_start and block->target_end should be interal
|
||||
* multiples of the target page size.
|
||||
* Return the page frame number and the page content in *bufptr. bufptr can be
|
||||
* NULL. If not NULL, *bufptr must contains a target page size of pre-allocated
|
||||
* memory. This is not necessarily the memory returned.
|
||||
*/
|
||||
static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
|
||||
uint8_t **bufptr, DumpState *s)
|
||||
{
|
||||
GuestPhysBlock *block = *blockptr;
|
||||
hwaddr addr, target_page_mask = ~((hwaddr)s->dump_info.page_size - 1);
|
||||
uint8_t *buf;
|
||||
uint32_t page_size = s->dump_info.page_size;
|
||||
uint8_t *buf = NULL, *hbuf;
|
||||
hwaddr addr;
|
||||
|
||||
/* block == NULL means the start of the iteration */
|
||||
if (!block) {
|
||||
block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
||||
*blockptr = block;
|
||||
assert((block->target_start & ~target_page_mask) == 0);
|
||||
assert((block->target_end & ~target_page_mask) == 0);
|
||||
*pfnptr = dump_paddr_to_pfn(s, block->target_start);
|
||||
if (bufptr) {
|
||||
*bufptr = block->host_addr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
*pfnptr = *pfnptr + 1;
|
||||
addr = dump_pfn_to_paddr(s, *pfnptr);
|
||||
|
||||
if ((addr >= block->target_start) &&
|
||||
(addr + s->dump_info.page_size <= block->target_end)) {
|
||||
buf = block->host_addr + (addr - block->target_start);
|
||||
addr = block->target_start;
|
||||
*pfnptr = dump_paddr_to_pfn(s, addr);
|
||||
} else {
|
||||
/* the next page is in the next block */
|
||||
block = QTAILQ_NEXT(block, next);
|
||||
*blockptr = block;
|
||||
if (!block) {
|
||||
return false;
|
||||
*pfnptr += 1;
|
||||
addr = dump_pfn_to_paddr(s, *pfnptr);
|
||||
}
|
||||
assert(block != NULL);
|
||||
|
||||
while (1) {
|
||||
if (addr >= block->target_start && addr < block->target_end) {
|
||||
size_t n = MIN(block->target_end - addr, page_size - addr % page_size);
|
||||
hbuf = block->host_addr + (addr - block->target_start);
|
||||
if (!buf) {
|
||||
if (n == page_size) {
|
||||
/* this is a whole target page, go for it */
|
||||
assert(addr % page_size == 0);
|
||||
buf = hbuf;
|
||||
break;
|
||||
} else if (bufptr) {
|
||||
assert(*bufptr);
|
||||
buf = *bufptr;
|
||||
memset(buf, 0, page_size);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buf + addr % page_size, hbuf, n);
|
||||
addr += n;
|
||||
if (addr % page_size == 0) {
|
||||
/* we filled up the page */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* the next page is in the next block */
|
||||
*blockptr = block = QTAILQ_NEXT(block, next);
|
||||
if (!block) {
|
||||
break;
|
||||
}
|
||||
|
||||
addr = block->target_start;
|
||||
/* are we still in the same page? */
|
||||
if (dump_paddr_to_pfn(s, addr) != *pfnptr) {
|
||||
if (buf) {
|
||||
/* no, but we already filled something earlier, return it */
|
||||
break;
|
||||
} else {
|
||||
/* else continue from there */
|
||||
*pfnptr = dump_paddr_to_pfn(s, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert((block->target_start & ~target_page_mask) == 0);
|
||||
assert((block->target_end & ~target_page_mask) == 0);
|
||||
*pfnptr = dump_paddr_to_pfn(s, block->target_start);
|
||||
buf = block->host_addr;
|
||||
}
|
||||
|
||||
if (bufptr) {
|
||||
*bufptr = buf;
|
||||
}
|
||||
|
||||
return true;
|
||||
return buf != NULL;
|
||||
}
|
||||
|
||||
static void write_dump_bitmap(DumpState *s, Error **errp)
|
||||
@ -1280,6 +1328,7 @@ static void write_dump_pages(DumpState *s, Error **errp)
|
||||
uint8_t *buf;
|
||||
GuestPhysBlock *block_iter = NULL;
|
||||
uint64_t pfn_iter;
|
||||
g_autofree uint8_t *page = NULL;
|
||||
|
||||
/* get offset of page_desc and page_data in dump file */
|
||||
offset_desc = s->offset_page;
|
||||
@ -1315,12 +1364,13 @@ static void write_dump_pages(DumpState *s, Error **errp)
|
||||
}
|
||||
|
||||
offset_data += s->dump_info.page_size;
|
||||
page = g_malloc(s->dump_info.page_size);
|
||||
|
||||
/*
|
||||
* dump memory to vmcore page by page. zero page will all be resided in the
|
||||
* first page of page section
|
||||
*/
|
||||
while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
|
||||
for (buf = page; get_next_page(&block_iter, &pfn_iter, &buf, s); buf = page) {
|
||||
/* check zero page */
|
||||
if (buffer_is_zero(buf, s->dump_info.page_size)) {
|
||||
ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
|
||||
@ -1490,30 +1540,22 @@ static void create_kdump_vmcore(DumpState *s, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
static ram_addr_t get_start_block(DumpState *s)
|
||||
static int validate_start_block(DumpState *s)
|
||||
{
|
||||
GuestPhysBlock *block;
|
||||
|
||||
if (!s->has_filter) {
|
||||
s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
||||
if (!dump_has_filter(s)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||
if (block->target_start >= s->begin + s->length ||
|
||||
block->target_end <= s->begin) {
|
||||
/* This block is out of the range */
|
||||
/* This block is out of the range */
|
||||
if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
|
||||
block->target_end <= s->filter_area_begin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
s->next_block = block;
|
||||
if (s->begin > block->target_start) {
|
||||
s->start = s->begin - block->target_start;
|
||||
} else {
|
||||
s->start = 0;
|
||||
}
|
||||
return s->start;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1540,25 +1582,19 @@ bool qemu_system_dump_in_progress(void)
|
||||
return (qatomic_read(&state->status) == DUMP_STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
/* calculate total size of memory to be dumped (taking filter into
|
||||
* acoount.) */
|
||||
/*
|
||||
* calculate total size of memory to be dumped (taking filter into
|
||||
* account.)
|
||||
*/
|
||||
static int64_t dump_calculate_size(DumpState *s)
|
||||
{
|
||||
GuestPhysBlock *block;
|
||||
int64_t size = 0, total = 0, left = 0, right = 0;
|
||||
int64_t total = 0;
|
||||
|
||||
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||
if (s->has_filter) {
|
||||
/* calculate the overlapped region. */
|
||||
left = MAX(s->begin, block->target_start);
|
||||
right = MIN(s->begin + s->length, block->target_end);
|
||||
size = right - left;
|
||||
size = size > 0 ? size : 0;
|
||||
} else {
|
||||
/* count the whole region in */
|
||||
size = (block->target_end - block->target_start);
|
||||
}
|
||||
total += size;
|
||||
total += dump_filtered_memblock_size(block,
|
||||
s->filter_area_begin,
|
||||
s->filter_area_length);
|
||||
}
|
||||
|
||||
return total;
|
||||
@ -1641,9 +1677,12 @@ static void dump_init(DumpState *s, int fd, bool has_format,
|
||||
}
|
||||
|
||||
s->fd = fd;
|
||||
s->has_filter = has_filter;
|
||||
s->begin = begin;
|
||||
s->length = length;
|
||||
if (has_filter && !length) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER, "length");
|
||||
goto cleanup;
|
||||
}
|
||||
s->filter_area_begin = begin;
|
||||
s->filter_area_length = length;
|
||||
|
||||
memory_mapping_list_init(&s->list);
|
||||
|
||||
@ -1660,8 +1699,8 @@ static void dump_init(DumpState *s, int fd, bool has_format,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
s->start = get_start_block(s);
|
||||
if (s->start == -1) {
|
||||
/* Is the filter filtering everything? */
|
||||
if (validate_start_block(s) == -1) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER, "begin");
|
||||
goto cleanup;
|
||||
}
|
||||
@ -1776,8 +1815,8 @@ static void dump_init(DumpState *s, int fd, bool has_format,
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->has_filter) {
|
||||
memory_mapping_filter(&s->list, s->begin, s->length);
|
||||
if (dump_has_filter(s)) {
|
||||
memory_mapping_filter(&s->list, s->filter_area_begin, s->filter_area_length);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -53,25 +53,25 @@ typedef struct SysemuCPUOps {
|
||||
* 32-bit VM coredump.
|
||||
*/
|
||||
int (*write_elf32_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
/**
|
||||
* @write_elf64_note: Callback for writing a CPU-specific ELF note to a
|
||||
* 64-bit VM coredump.
|
||||
*/
|
||||
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
/**
|
||||
* @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF
|
||||
* note to a 32-bit VM coredump.
|
||||
*/
|
||||
int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque);
|
||||
DumpState *s);
|
||||
/**
|
||||
* @write_elf64_qemunote: Callback for writing a CPU- and QEMU-specific ELF
|
||||
* note to a 64-bit VM coredump.
|
||||
*/
|
||||
int (*write_elf64_qemunote)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque);
|
||||
DumpState *s);
|
||||
/**
|
||||
* @virtio_is_big_endian: Callback to return %true if a CPU which supports
|
||||
* runtime configurable endianness is currently big-endian.
|
||||
|
@ -131,6 +131,7 @@ typedef struct VirtIODevice VirtIODevice;
|
||||
typedef struct Visitor Visitor;
|
||||
typedef struct VMChangeStateEntry VMChangeStateEntry;
|
||||
typedef struct VMStateDescription VMStateDescription;
|
||||
typedef struct DumpState DumpState;
|
||||
|
||||
/*
|
||||
* Pointer types
|
||||
|
@ -166,11 +166,16 @@ typedef struct DumpState {
|
||||
hwaddr memory_offset;
|
||||
int fd;
|
||||
|
||||
GuestPhysBlock *next_block;
|
||||
ram_addr_t start;
|
||||
bool has_filter;
|
||||
int64_t begin;
|
||||
int64_t length;
|
||||
/*
|
||||
* Dump filter area variables
|
||||
*
|
||||
* A filtered dump only contains the guest memory designated by
|
||||
* the start address and length variables defined below.
|
||||
*
|
||||
* If length is 0, no filtering is applied.
|
||||
*/
|
||||
int64_t filter_area_begin; /* Start address of partial guest memory area */
|
||||
int64_t filter_area_length; /* Length of partial guest memory area */
|
||||
|
||||
uint8_t *note_buf; /* buffer for notes */
|
||||
size_t note_buf_offset; /* the writing place in note_buf */
|
||||
|
@ -232,12 +232,11 @@ static int aarch64_write_elf64_sve(WriteCoreDumpFunction f,
|
||||
#endif
|
||||
|
||||
int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
struct aarch64_note note;
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
DumpState *s = opaque;
|
||||
uint64_t pstate, sp;
|
||||
int ret, i;
|
||||
|
||||
@ -360,12 +359,11 @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
|
||||
}
|
||||
|
||||
int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
struct arm_note note;
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
DumpState *s = opaque;
|
||||
int ret, i;
|
||||
bool fpvalid = cpu_isar_feature(aa32_vfp_simd, cpu);
|
||||
|
||||
|
@ -1102,9 +1102,9 @@ int arm_gen_dynamic_svereg_xml(CPUState *cpu, int base_reg);
|
||||
const char *arm_gdb_get_dynamic_xml(CPUState *cpu, const char *xmlname);
|
||||
|
||||
int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
int aarch64_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
|
||||
|
@ -42,7 +42,7 @@ typedef struct {
|
||||
|
||||
static int x86_64_write_elf64_note(WriteCoreDumpFunction f,
|
||||
CPUX86State *env, int id,
|
||||
void *opaque)
|
||||
DumpState *s)
|
||||
{
|
||||
x86_64_user_regs_struct regs;
|
||||
Elf64_Nhdr *note;
|
||||
@ -94,7 +94,7 @@ static int x86_64_write_elf64_note(WriteCoreDumpFunction f,
|
||||
buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
|
||||
memcpy(buf, ®s, sizeof(x86_64_user_regs_struct));
|
||||
|
||||
ret = f(note, note_size, opaque);
|
||||
ret = f(note, note_size, s);
|
||||
g_free(note);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@ -148,7 +148,7 @@ static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env,
|
||||
}
|
||||
|
||||
static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
|
||||
int id, void *opaque)
|
||||
int id, DumpState *s)
|
||||
{
|
||||
x86_elf_prstatus prstatus;
|
||||
Elf64_Nhdr *note;
|
||||
@ -170,7 +170,7 @@ static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
|
||||
buf += ROUND_UP(name_size, 4);
|
||||
memcpy(buf, &prstatus, sizeof(prstatus));
|
||||
|
||||
ret = f(note, note_size, opaque);
|
||||
ret = f(note, note_size, s);
|
||||
g_free(note);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@ -180,7 +180,7 @@ static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
|
||||
}
|
||||
|
||||
int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
int ret;
|
||||
@ -189,10 +189,10 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
|
||||
|
||||
if (lma) {
|
||||
ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
|
||||
ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, s);
|
||||
} else {
|
||||
#endif
|
||||
ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque);
|
||||
ret = x86_write_elf64_note(f, &cpu->env, cpuid, s);
|
||||
#ifdef TARGET_X86_64
|
||||
}
|
||||
#endif
|
||||
@ -201,7 +201,7 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
}
|
||||
|
||||
int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
x86_elf_prstatus prstatus;
|
||||
@ -224,7 +224,7 @@ int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
buf += ROUND_UP(name_size, 4);
|
||||
memcpy(buf, &prstatus, sizeof(prstatus));
|
||||
|
||||
ret = f(note, note_size, opaque);
|
||||
ret = f(note, note_size, s);
|
||||
g_free(note);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@ -329,7 +329,7 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env)
|
||||
|
||||
static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
|
||||
CPUX86State *env,
|
||||
void *opaque,
|
||||
DumpState *s,
|
||||
int type)
|
||||
{
|
||||
QEMUCPUState state;
|
||||
@ -369,7 +369,7 @@ static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
|
||||
buf += ROUND_UP(name_size, 4);
|
||||
memcpy(buf, &state, sizeof(state));
|
||||
|
||||
ret = f(note, note_size, opaque);
|
||||
ret = f(note, note_size, s);
|
||||
g_free(note);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@ -379,19 +379,19 @@ static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
|
||||
}
|
||||
|
||||
int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs,
|
||||
void *opaque)
|
||||
DumpState *s)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
|
||||
return cpu_write_qemu_note(f, &cpu->env, opaque, 1);
|
||||
return cpu_write_qemu_note(f, &cpu->env, s, 1);
|
||||
}
|
||||
|
||||
int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
|
||||
void *opaque)
|
||||
DumpState *s)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
|
||||
return cpu_write_qemu_note(f, &cpu->env, opaque, 0);
|
||||
return cpu_write_qemu_note(f, &cpu->env, s, 0);
|
||||
}
|
||||
|
||||
int cpu_get_dump_info(ArchDumpInfo *info,
|
||||
|
@ -1938,13 +1938,13 @@ extern const VMStateDescription vmstate_x86_cpu;
|
||||
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
|
||||
|
||||
int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque);
|
||||
DumpState *s);
|
||||
int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
void *opaque);
|
||||
DumpState *s);
|
||||
|
||||
void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||
Error **errp);
|
||||
|
@ -270,23 +270,23 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
|
||||
static int ppc_write_all_elf_notes(const char *note_name,
|
||||
WriteCoreDumpFunction f,
|
||||
PowerPCCPU *cpu, int id,
|
||||
void *opaque)
|
||||
DumpState *s)
|
||||
{
|
||||
NoteFuncArg arg = { .state = opaque };
|
||||
NoteFuncArg arg = { .state = s };
|
||||
int ret = -1;
|
||||
int note_size;
|
||||
const NoteFuncDesc *nf;
|
||||
|
||||
for (nf = note_func; nf->note_contents_func; nf++) {
|
||||
arg.note.hdr.n_namesz = cpu_to_dump32(opaque, sizeof(arg.note.name));
|
||||
arg.note.hdr.n_descsz = cpu_to_dump32(opaque, nf->contents_size);
|
||||
arg.note.hdr.n_namesz = cpu_to_dump32(s, sizeof(arg.note.name));
|
||||
arg.note.hdr.n_descsz = cpu_to_dump32(s, nf->contents_size);
|
||||
strncpy(arg.note.name, note_name, sizeof(arg.note.name));
|
||||
|
||||
(*nf->note_contents_func)(&arg, cpu);
|
||||
|
||||
note_size =
|
||||
sizeof(arg.note) - sizeof(arg.note.contents) + nf->contents_size;
|
||||
ret = f(&arg.note, note_size, opaque);
|
||||
ret = f(&arg.note, note_size, s);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -295,15 +295,15 @@ static int ppc_write_all_elf_notes(const char *note_name,
|
||||
}
|
||||
|
||||
int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
|
||||
return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, s);
|
||||
}
|
||||
|
||||
int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, opaque);
|
||||
return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, s);
|
||||
}
|
||||
|
@ -1354,9 +1354,9 @@ void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu);
|
||||
const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name);
|
||||
#endif
|
||||
int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void ppc_cpu_do_interrupt(CPUState *cpu);
|
||||
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
|
||||
|
@ -64,12 +64,11 @@ static void riscv64_note_init(struct riscv64_note *note, DumpState *s,
|
||||
}
|
||||
|
||||
int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
struct riscv64_note note;
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
DumpState *s = opaque;
|
||||
int ret, i = 0;
|
||||
const char name[] = "CORE";
|
||||
|
||||
@ -134,12 +133,11 @@ static void riscv32_note_init(struct riscv32_note *note, DumpState *s,
|
||||
}
|
||||
|
||||
int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
struct riscv32_note note;
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
DumpState *s = opaque;
|
||||
int ret, i;
|
||||
const char name[] = "CORE";
|
||||
|
||||
|
@ -534,9 +534,9 @@ extern const char * const riscv_fpr_regnames[];
|
||||
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
|
||||
void riscv_cpu_do_interrupt(CPUState *cpu);
|
||||
int riscv_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
|
||||
int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
|
||||
|
@ -204,7 +204,7 @@ static const NoteFuncDesc note_linux[] = {
|
||||
static int s390x_write_elf64_notes(const char *note_name,
|
||||
WriteCoreDumpFunction f,
|
||||
S390CPU *cpu, int id,
|
||||
void *opaque,
|
||||
DumpState *s,
|
||||
const NoteFuncDesc *funcs)
|
||||
{
|
||||
Note note;
|
||||
@ -222,7 +222,7 @@ static int s390x_write_elf64_notes(const char *note_name,
|
||||
(*nf->note_contents_func)(¬e, cpu, id);
|
||||
|
||||
note_size = sizeof(note) - sizeof(note.contents) + nf->contents_size;
|
||||
ret = f(¬e, note_size, opaque);
|
||||
ret = f(¬e, note_size, s);
|
||||
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
@ -235,16 +235,16 @@ static int s390x_write_elf64_notes(const char *note_name,
|
||||
|
||||
|
||||
int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque)
|
||||
int cpuid, DumpState *s)
|
||||
{
|
||||
S390CPU *cpu = S390_CPU(cs);
|
||||
int r;
|
||||
|
||||
r = s390x_write_elf64_notes("CORE", f, cpu, cpuid, opaque, note_core);
|
||||
r = s390x_write_elf64_notes("CORE", f, cpu, cpuid, s, note_core);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
return s390x_write_elf64_notes("LINUX", f, cpu, cpuid, opaque, note_linux);
|
||||
return s390x_write_elf64_notes("LINUX", f, cpu, cpuid, s, note_linux);
|
||||
}
|
||||
|
||||
int cpu_get_dump_info(ArchDumpInfo *info,
|
||||
|
@ -227,7 +227,7 @@ static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb,
|
||||
|
||||
/* arch_dump.c */
|
||||
int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
int cpuid, void *opaque);
|
||||
int cpuid, DumpState *s);
|
||||
|
||||
|
||||
/* cc_helper.c */
|
||||
|
Loading…
Reference in New Issue
Block a user