Files
s390-tools/zdump/zg.h
Marc Hartmayer 8fa1b5a00b zdump: dfi: add support to read Protected Virtualization dumps
Sometimes dumping a virtual machine from the outside is the only way to
get the data that is needed. This can be the case if a dumping mechanism
like kdump hasn't been configured or data needs to be fetched at a
specific point. Dumping a protected guest from the outside without help
from FW/HW doesn't yield sufficient data to be useful. Hence we have
introduced Protected Virtualization (PV) dump support - also named
confidential dump support.

The confidential dump support works by integrating the firmware into the
dump process. New Ultravisor calls (UVC) are used to initiate the dump
process, dump CPU data, dump memory state and lastly complete the dump
process. The guest's data is fully encrypted and can only be decrypted
by the entity that owns the customer communication key (CCK) for the
dumped guest. The output format is very similar the normal s390 vmcore
ELF format, it's only enriched by new sections where the returned data
from the UVC "Complete Configuration Dump" and the UVC "Dump
Configuration Storage State" is stored. The encrypted CPU data is stored
in a new note type `NT_S390_PV_CPU_DATA`. The old note types do still
exists but without any confidential data stored. The memory data is
stored in the LOAD segment as usual but for PV dumps it's fully AES-XTS
encrypted.

This commit adds support for reading/decrypting PV guest dumps to
zgetdump by introducing a new DFI input module (`dfi_pv_elf.c`). For
specifying the customer communication key a new command line option
`--key` is added.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-11-03 17:45:38 +01:00

173 lines
4.2 KiB
C

/*
* zgetdump - Tool for copying and converting System z dumps
*
* Helper functions
*
* Copyright IBM Corp. 2001, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef ZG_H
#define ZG_H
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "boot/s390.h"
#include "lib/util_base.h"
#include "lib/zt_common.h"
#define U64_MAX ((u64) -1)
#define U32_MAX ((u32) -1)
#define U16_MAX ((u16) -1)
#define U8_MAX ((u8) -1)
#define OFF_T_MAX LONG_MAX
STATIC_ASSERT(sizeof(off_t) == sizeof(long))
/*
* IEC definitions
*/
#define KIB (1024)
#define MIB (1024 * 1024)
#define GIB (1024 * 1024 * 1024)
#define TO_MIB(x) ((x + (MIB / 2)) / MIB)
#define TO_KIB(x) ((x + (KIB / 2)) / KIB)
/*
* Memory functions
*/
void *zg_alloc(size_t size);
void *zg_realloc(void *ptr, size_t size);
void zg_free(void *ptr);
char *zg_strdup(const char *str);
/*
* At exit functions
*/
typedef void (*zg_atexit_fn_t)(void);
void zg_atexit(zg_atexit_fn_t fn);
void __noreturn zg_exit(int rc);
/*
* Temporary device node functions
*/
char *zg_devnode_create(dev_t dev);
/*
* Progress bar functions
*/
void zg_progress_init(const char *msg, u64 mem_size);
void zg_progress(u64 addr);
/*
* Error and print functions
*/
void zg_err(const char *fmt, ...);
void zg_err_exit(const char *fmt, ...);
void zg_err_exit_errno(const char *fmt, ...);
void zg_abort(const char *fmt, ...);
#define ERR(fmt, ...) zg_err(fmt, ## __VA_ARGS__)
#define ERR_EXIT(fmt, ...) zg_err_exit(fmt, ## __VA_ARGS__)
#define ERR_EXIT_ERRNO(fmt, ...) zg_err_exit_errno(fmt, ## __VA_ARGS__)
#define ABORT(fmt, ...) zg_abort(fmt, ## __VA_ARGS__)
#define ERR_NEWLINE "\n "
void zg_stderr(const char *fmt, ...);
void zg_stderr_pr(const char *fmt, ...);
void zg_stdout(const char *fmt, ...);
#define STDERR(fmt, ...) zg_stderr(fmt, ## __VA_ARGS__)
#define STDERR_PR(fmt, ...) zg_stderr_pr(fmt, ## __VA_ARGS__)
#define STDOUT(fmt, ...) zg_stdout(fmt, ## __VA_ARGS__)
/*
* Misc
*/
#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
#define IS_ALIGNED(addr, size) (!((addr) & (size - 1)))
#define IS_PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
static inline u32 zg_csum_partial(const void *buf, int len, u32 sum)
{
register unsigned long reg2 asm("2") = (unsigned long) buf;
register unsigned long reg3 asm("3") = (unsigned long) len;
asm volatile(
"0: cksm %0,%1\n" /* do checksum on longs */
" jo 0b\n"
: "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory");
return sum;
}
/*
* Pointer atrithmetic
*/
#define PTR_SUB(x, y) ((void *)(((char *) (x)) - ((unsigned long) (y))))
#define PTR_ADD(x, y) ((void *)(((char *) (x)) + ((unsigned long) (y))))
#define PTR_DIFF(x, y) ((unsigned long)PTR_SUB(x, y))
/*
* File functions
*/
struct zg_fh {
const char *path;
int fh;
struct stat sb;
};
enum zg_type {
ZG_TYPE_DASD,
ZG_TYPE_DASD_PART,
ZG_TYPE_FILE,
ZG_TYPE_TAPE,
ZG_TYPE_UNKNOWN,
};
enum zg_check {
ZG_CHECK,
ZG_CHECK_ERR,
ZG_CHECK_NONE,
};
const char *zg_path(const struct zg_fh *zg_fh);
const struct stat *zg_stat(const struct zg_fh *zg_fh);
struct zg_fh *zg_open(const char *path, int flags, enum zg_check check);
void zg_close(struct zg_fh *zg_fh);
ssize_t zg_read(const struct zg_fh *zg_fh, void *buf, size_t cnt, enum zg_check check);
ssize_t zg_gets(const struct zg_fh *zg_fh, void *buf, size_t cnt, enum zg_check check);
u64 zg_size(const struct zg_fh *zg_fh);
off_t zg_tell(const struct zg_fh *zg_fh, enum zg_check check);
off_t zg_seek(const struct zg_fh *zg_fh, off_t off, enum zg_check check);
off_t zg_seek_end(const struct zg_fh *zg_fh, off_t off, enum zg_check check);
off_t zg_seek_cur(const struct zg_fh *zg_fh, off_t off, enum zg_check check);
int zg_ioctl(const struct zg_fh *zg_fh, unsigned long rq, void *data, const char *op,
enum zg_check check);
enum zg_type zg_type(const struct zg_fh *zg_fh);
/*
* zgetdump actions
*/
enum zg_action {
ZG_ACTION_COPY,
ZG_ACTION_DUMP_INFO,
ZG_ACTION_DEVICE_INFO,
ZG_ACTION_MOUNT,
ZG_ACTION_UMOUNT,
};
#endif /* ZG_H */