Skip to content

Commit

Permalink
Merge tag 'dump-pull-request' of https://gitlab.com/marcandre.lureau/…
Browse files Browse the repository at this point in the history
…qemu into staging

dump queue

Hi

The "dump" queue, with:
- [PATCH v3/v4 0/9] dump: Cleanup and consolidation
- [PATCH v4 0/4] dump: add 32-bit guest Windows support

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmNXlSIcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5USfD/451iqJXMA51bNel7nH
# +XXaczRcT/8X/o3yzDRWlD/BO3R6+GjbVvR9RwTVi0M/mok4WWoXknpsEnlVpatE
# 9INsVObaYQs5eP7lh+QB2WXtOS++aJK3c8yoT1SjlHIPHkMKpNpTfxF3fnVImFcA
# 4zIRgjb2V7M+cqRVAkS4jPD3Gfrg8ernQgLilYB+Q6XW5l2vY4MF05bcMSdEG2Af
# ySdSQnufqznDiAJDa63yUVfXZKCT/y8yKRVlQ7LjhWjaRN7CdY2sEPNuTKI7zIFI
# MF/oayJ8IIGAy8b6yuqWBPXUKRopppe4QmLR4ZkTMSD0ah3bh8ucgEtNTN95s2NF
# ALn4IA8+ZqqAEKOQgvGH03U5nvbymOXyIhHmtNgvf6Afo4JIB9hC7eFaKsgDcgG8
# sTVAlB1EH5uKg3zTybjnpxPdBw5rZhlgpBTrEjAK69h5sOk5af5GzFCF67UGPcH7
# 4sT1IHJ7F19SaOEZRQcJiOJR5eE2Bj9G2WnT1rJHDC1wu8K4qwBK3AVwoG5XWbTa
# jReJWhBKslANX793MYKzbQewEzt6wqPdSc0mt+47zLcfdwE6gVR+TH2Q1ATKzXuC
# WpzO1DMIf1n8yXiA0MubUVniqUCQlghsCISl112nTKbGv3XtmvWcG6AV+enuJi0Q
# m8TyGSZAsNQj5O8J6jJMLQjrTQ==
# =8FEI
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 25 Oct 2022 03:49:54 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/win_dump: limit number of processed PRCBs
  s390x: pv: Add dump support
  s390x: Add KVM PV dump interface
  include/elf.h: add s390x note types
  s390x: Introduce PV query interface
  s390x: Add protected dump cap
  dump: Add architecture section and section string table support
  dump: Reintroduce memory_offset and section_offset
  dump: Reorder struct DumpState
  dump: Write ELF section headers right after ELF header
  dump: Use a buffer for ELF section data and headers

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Oct 25, 2022
2 parents 79fc2fb + 1c08fb2 commit 29f3399
Show file tree
Hide file tree
Showing 11 changed files with 635 additions and 98 deletions.
288 changes: 224 additions & 64 deletions dump/dump.c

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions dump/win_dump.c
Expand Up @@ -273,6 +273,13 @@ static void patch_and_save_context(WinDumpHeader *h, bool x64,
uint64_t Context;
WinContext ctx;

if (i >= WIN_DUMP_FIELD(NumberProcessors)) {
warn_report("win-dump: number of QEMU CPUs is bigger than"
" NumberProcessors (%u) in guest Windows",
WIN_DUMP_FIELD(NumberProcessors));
return;
}

if (cpu_read_ptr(x64, first_cpu,
KiProcessorBlock + i * win_dump_ptr_size(x64),
&Prcb)) {
Expand Down
112 changes: 112 additions & 0 deletions hw/s390x/pv.c
Expand Up @@ -20,6 +20,11 @@
#include "exec/confidential-guest-support.h"
#include "hw/s390x/ipl.h"
#include "hw/s390x/pv.h"
#include "target/s390x/kvm/kvm_s390x.h"

static bool info_valid;
static struct kvm_s390_pv_info_vm info_vm;
static struct kvm_s390_pv_info_dump info_dump;

static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
{
Expand Down Expand Up @@ -56,6 +61,42 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data)
} \
}

int s390_pv_query_info(void)
{
struct kvm_s390_pv_info info = {
.header.id = KVM_PV_INFO_VM,
.header.len_max = sizeof(info.header) + sizeof(info.vm),
};
int rc;

/* Info API's first user is dump so they are bundled */
if (!kvm_s390_get_protected_dump()) {
return 0;
}

rc = s390_pv_cmd(KVM_PV_INFO, &info);
if (rc) {
error_report("KVM PV INFO cmd %x failed: %s",
info.header.id, strerror(-rc));
return rc;
}
memcpy(&info_vm, &info.vm, sizeof(info.vm));

info.header.id = KVM_PV_INFO_DUMP;
info.header.len_max = sizeof(info.header) + sizeof(info.dump);
rc = s390_pv_cmd(KVM_PV_INFO, &info);
if (rc) {
error_report("KVM PV INFO cmd %x failed: %s",
info.header.id, strerror(-rc));
return rc;
}

memcpy(&info_dump, &info.dump, sizeof(info.dump));
info_valid = true;

return rc;
}

int s390_pv_vm_enable(void)
{
return s390_pv_cmd(KVM_PV_ENABLE, NULL);
Expand Down Expand Up @@ -114,6 +155,77 @@ void s390_pv_inject_reset_error(CPUState *cs)
env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV;
}

uint64_t kvm_s390_pv_dmp_get_size_cpu(void)
{
return info_dump.dump_cpu_buffer_len;
}

uint64_t kvm_s390_pv_dmp_get_size_completion_data(void)
{
return info_dump.dump_config_finalize_len;
}

uint64_t kvm_s390_pv_dmp_get_size_mem_state(void)
{
return info_dump.dump_config_mem_buffer_per_1m;
}

bool kvm_s390_pv_info_basic_valid(void)
{
return info_valid;
}

static int s390_pv_dump_cmd(uint64_t subcmd, uint64_t uaddr, uint64_t gaddr,
uint64_t len)
{
struct kvm_s390_pv_dmp dmp = {
.subcmd = subcmd,
.buff_addr = uaddr,
.buff_len = len,
.gaddr = gaddr,
};
int ret;

ret = s390_pv_cmd(KVM_PV_DUMP, (void *)&dmp);
if (ret) {
error_report("KVM DUMP command %ld failed", subcmd);
}
return ret;
}

int kvm_s390_dump_cpu(S390CPU *cpu, void *buff)
{
struct kvm_s390_pv_dmp dmp = {
.subcmd = KVM_PV_DUMP_CPU,
.buff_addr = (uint64_t)buff,
.gaddr = 0,
.buff_len = info_dump.dump_cpu_buffer_len,
};
struct kvm_pv_cmd pv = {
.cmd = KVM_PV_DUMP,
.data = (uint64_t)&dmp,
};

return kvm_vcpu_ioctl(CPU(cpu), KVM_S390_PV_CPU_COMMAND, &pv);
}

int kvm_s390_dump_init(void)
{
return s390_pv_dump_cmd(KVM_PV_DUMP_INIT, 0, 0, 0);
}

int kvm_s390_dump_mem_state(uint64_t gaddr, size_t len, void *dest)
{
return s390_pv_dump_cmd(KVM_PV_DUMP_CONFIG_STOR_STATE, (uint64_t)dest,
gaddr, len);
}

int kvm_s390_dump_completion_data(void *buff)
{
return s390_pv_dump_cmd(KVM_PV_DUMP_COMPLETE, (uint64_t)buff, 0,
info_dump.dump_config_finalize_len);
}

#define TYPE_S390_PV_GUEST "s390-pv-guest"
OBJECT_DECLARE_SIMPLE_TYPE(S390PVGuest, S390_PV_GUEST)

Expand Down
6 changes: 6 additions & 0 deletions hw/s390x/s390-virtio-ccw.c
Expand Up @@ -366,6 +366,12 @@ static int s390_machine_protect(S390CcwMachineState *ms)

ms->pv = true;

/* Will return 0 if API is not available since it's not vital */
rc = s390_pv_query_info();
if (rc) {
goto out_err;
}

/* Set SE header and unpack */
rc = s390_ipl_prepare_pv_header();
if (rc) {
Expand Down
2 changes: 2 additions & 0 deletions include/elf.h
Expand Up @@ -1650,6 +1650,8 @@ typedef struct elf64_shdr {
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data */
#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation */
#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */
#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */
#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 (lower half) */
Expand Down
19 changes: 19 additions & 0 deletions include/hw/s390x/pv.h
Expand Up @@ -38,6 +38,7 @@ static inline bool s390_is_pv(void)
return ccw->pv;
}

int s390_pv_query_info(void);
int s390_pv_vm_enable(void);
void s390_pv_vm_disable(void);
int s390_pv_set_sec_parms(uint64_t origin, uint64_t length);
Expand All @@ -46,8 +47,17 @@ void s390_pv_prep_reset(void);
int s390_pv_verify(void);
void s390_pv_unshare(void);
void s390_pv_inject_reset_error(CPUState *cs);
uint64_t kvm_s390_pv_dmp_get_size_cpu(void);
uint64_t kvm_s390_pv_dmp_get_size_mem_state(void);
uint64_t kvm_s390_pv_dmp_get_size_completion_data(void);
bool kvm_s390_pv_info_basic_valid(void);
int kvm_s390_dump_init(void);
int kvm_s390_dump_cpu(S390CPU *cpu, void *buff);
int kvm_s390_dump_mem_state(uint64_t addr, size_t len, void *dest);
int kvm_s390_dump_completion_data(void *buff);
#else /* CONFIG_KVM */
static inline bool s390_is_pv(void) { return false; }
static inline int s390_pv_query_info(void) { return 0; }
static inline int s390_pv_vm_enable(void) { return 0; }
static inline void s390_pv_vm_disable(void) {}
static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; }
Expand All @@ -56,6 +66,15 @@ static inline void s390_pv_prep_reset(void) {}
static inline int s390_pv_verify(void) { return 0; }
static inline void s390_pv_unshare(void) {}
static inline void s390_pv_inject_reset_error(CPUState *cs) {};
static inline uint64_t kvm_s390_pv_dmp_get_size_cpu(void) { return 0; }
static inline uint64_t kvm_s390_pv_dmp_get_size_mem_state(void) { return 0; }
static inline uint64_t kvm_s390_pv_dmp_get_size_completion_data(void) { return 0; }
static inline bool kvm_s390_pv_info_basic_valid(void) { return false; }
static inline int kvm_s390_dump_init(void) { return 0; }
static inline int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) { return 0; }
static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len,
void *dest) { return 0; }
static inline int kvm_s390_dump_completion_data(void *buff) { return 0; }
#endif /* CONFIG_KVM */

int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp);
Expand Down
3 changes: 3 additions & 0 deletions include/sysemu/dump-arch.h
Expand Up @@ -21,6 +21,9 @@ typedef struct ArchDumpInfo {
uint32_t page_size; /* The target's page size. If it's variable and
* unknown, then this should be the maximum. */
uint64_t phys_base; /* The target's physmem base. */
void (*arch_sections_add_fn)(DumpState *s);
uint64_t (*arch_sections_write_hdr_fn)(DumpState *s, uint8_t *buff);
int (*arch_sections_write_fn)(DumpState *s, uint8_t *buff);
} ArchDumpInfo;

struct GuestPhysBlockList; /* memory_mapping.h */
Expand Down
26 changes: 19 additions & 7 deletions include/sysemu/dump.h
Expand Up @@ -154,15 +154,8 @@ typedef struct DumpState {
GuestPhysBlockList guest_phys_blocks;
ArchDumpInfo dump_info;
MemoryMappingList list;
uint32_t phdr_num;
uint32_t shdr_num;
bool resume;
bool detached;
ssize_t note_size;
hwaddr shdr_offset;
hwaddr phdr_offset;
hwaddr section_offset;
hwaddr note_offset;
hwaddr memory_offset;
int fd;

Expand All @@ -177,6 +170,20 @@ typedef struct DumpState {
int64_t filter_area_begin; /* Start address of partial guest memory area */
int64_t filter_area_length; /* Length of partial guest memory area */

/* Elf dump related data */
uint32_t phdr_num;
uint32_t shdr_num;
ssize_t note_size;
hwaddr shdr_offset;
hwaddr phdr_offset;
hwaddr section_offset;
hwaddr note_offset;

void *elf_section_hdrs; /* Pointer to section header buffer */
void *elf_section_data; /* Pointer to section data buffer */
uint64_t elf_section_data_size; /* Size of section data */
GArray *string_table_buf; /* String table data buffer */

uint8_t *note_buf; /* buffer for notes */
size_t note_buf_offset; /* the writing place in note_buf */
uint32_t nr_cpus; /* number of guest's cpu */
Expand Down Expand Up @@ -208,4 +215,9 @@ typedef struct DumpState {
uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
uint32_t cpu_to_dump32(DumpState *s, uint32_t val);
uint64_t cpu_to_dump64(DumpState *s, uint64_t val);

int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start,
int64_t filter_area_length);
int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start,
int64_t filter_area_length);
#endif

0 comments on commit 29f3399

Please sign in to comment.