aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel/Makefile.objs2
-rw-r--r--accel/kvm/Makefile.objs3
-rw-r--r--accel/kvm/kvm-all.c39
-rw-r--r--accel/kvm/sev-stub.c26
-rw-r--r--accel/stubs/kvm-stub.c10
-rw-r--r--default-configs/i386-softmmu.mak1
-rw-r--r--default-configs/x86_64-softmmu.mak1
-rw-r--r--docs/amd-memory-encryption.txt109
-rw-r--r--hmp-commands-info.hx16
-rw-r--r--hmp.h1
-rw-r--r--hw/core/machine.c22
-rw-r--r--hw/i386/pc_sysfw.c13
-rw-r--r--include/hw/boards.h1
-rw-r--r--include/standard-headers/linux/input-event-codes.h1
-rw-r--r--include/standard-headers/linux/input.h11
-rw-r--r--include/standard-headers/linux/pci_regs.h30
-rw-r--r--include/standard-headers/linux/virtio_net.h13
-rw-r--r--include/standard-headers/linux/virtio_ring.h2
-rw-r--r--include/standard-headers/rdma/vmw_pvrdma-abi.h13
-rw-r--r--include/sysemu/kvm.h17
-rw-r--r--include/sysemu/sev.h21
-rw-r--r--linux-headers/asm-powerpc/kvm.h2
-rw-r--r--linux-headers/asm-powerpc/unistd.h3
-rw-r--r--linux-headers/asm-s390/unistd.h401
-rw-r--r--linux-headers/asm-s390/unistd_32.h364
-rw-r--r--linux-headers/asm-s390/unistd_64.h331
-rw-r--r--linux-headers/asm-x86/kvm_para.h5
-rw-r--r--linux-headers/linux/kvm.h92
-rw-r--r--linux-headers/linux/psci.h3
-rw-r--r--linux-headers/linux/psp-sev.h142
-rw-r--r--linux-headers/linux/vfio.h72
-rw-r--r--monitor.c21
-rw-r--r--qapi/misc.json148
-rw-r--r--qemu-options.hx49
-rwxr-xr-xscripts/update-linux-headers.sh5
-rw-r--r--target/i386/Makefile.objs2
-rw-r--r--target/i386/cpu.c14
-rw-r--r--target/i386/cpu.h3
-rw-r--r--target/i386/kvm.c13
-rw-r--r--target/i386/machine.c20
-rw-r--r--target/i386/monitor.c66
-rw-r--r--target/i386/sev-stub.c51
-rw-r--r--target/i386/sev.c811
-rw-r--r--target/i386/sev_i386.h88
-rw-r--r--target/i386/trace-events10
-rw-r--r--tests/qmp-test.c5
46 files changed, 2653 insertions, 420 deletions
diff --git a/accel/Makefile.objs b/accel/Makefile.objs
index 10666eda71..c3718a10c5 100644
--- a/accel/Makefile.objs
+++ b/accel/Makefile.objs
@@ -1,4 +1,4 @@
obj-$(CONFIG_SOFTMMU) += accel.o
-obj-y += kvm/
+obj-$(CONFIG_KVM) += kvm/
obj-$(CONFIG_TCG) += tcg/
obj-y += stubs/
diff --git a/accel/kvm/Makefile.objs b/accel/kvm/Makefile.objs
index 85351e7de7..fdfa481578 100644
--- a/accel/kvm/Makefile.objs
+++ b/accel/kvm/Makefile.objs
@@ -1 +1,2 @@
-obj-$(CONFIG_KVM) += kvm-all.o
+obj-y += kvm-all.o
+obj-$(call lnot,$(CONFIG_SEV)) += sev-stub.o
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index b91fcb7160..ffee68e603 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -38,6 +38,7 @@
#include "qemu/event_notifier.h"
#include "trace.h"
#include "hw/irq.h"
+#include "sysemu/sev.h"
#include "hw/boards.h"
@@ -103,6 +104,10 @@ struct KVMState
#endif
KVMMemoryListener memory_listener;
QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
+
+ /* memory encryption */
+ void *memcrypt_handle;
+ int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);
};
KVMState *kvm_state;
@@ -138,6 +143,26 @@ int kvm_get_max_memslots(void)
return s->nr_slots;
}
+bool kvm_memcrypt_enabled(void)
+{
+ if (kvm_state && kvm_state->memcrypt_handle) {
+ return true;
+ }
+
+ return false;
+}
+
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_encrypt_data) {
+ return kvm_state->memcrypt_encrypt_data(kvm_state->memcrypt_handle,
+ ptr, len);
+ }
+
+ return 1;
+}
+
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
{
KVMState *s = kvm_state;
@@ -1636,6 +1661,20 @@ static int kvm_init(MachineState *ms)
kvm_state = s;
+ /*
+ * if memory encryption object is specified then initialize the memory
+ * encryption context.
+ */
+ if (ms->memory_encryption) {
+ kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption);
+ if (!kvm_state->memcrypt_handle) {
+ ret = -1;
+ goto err;
+ }
+
+ kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
+ }
+
ret = kvm_arch_init(ms, s);
if (ret < 0) {
goto err;
diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c
new file mode 100644
index 0000000000..4f97452585
--- /dev/null
+++ b/accel/kvm/sev-stub.c
@@ -0,0 +1,26 @@
+/*
+ * QEMU SEV stub
+ *
+ * Copyright Advanced Micro Devices 2018
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/sev.h"
+
+int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
+{
+ abort();
+}
+
+void *sev_guest_init(const char *id)
+{
+ return NULL;
+}
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index c964af3e1c..02d5170031 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -105,6 +105,16 @@ int kvm_on_sigbus(int code, void *addr)
return 1;
}
+bool kvm_memcrypt_enabled(void)
+{
+ return false;
+}
+
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
+{
+ return 1;
+}
+
#ifndef CONFIG_USER_ONLY
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
{
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 3326e3e0bb..8973579bd0 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -63,3 +63,4 @@ CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
CONFIG_I2C=y
+CONFIG_SEV=$(CONFIG_KVM)
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 1c6cda1d9a..5e27a7a4f4 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -63,3 +63,4 @@ CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
CONFIG_I2C=y
+CONFIG_SEV=$(CONFIG_KVM)
diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
new file mode 100644
index 0000000000..f483795eaa
--- /dev/null
+++ b/docs/amd-memory-encryption.txt
@@ -0,0 +1,109 @@
+Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
+
+SEV is an extension to the AMD-V architecture which supports running encrypted
+virtual machine (VMs) under the control of KVM. Encrypted VMs have their pages
+(code and data) secured such that only the guest itself has access to the
+unencrypted version. Each encrypted VM is associated with a unique encryption
+key; if its data is accessed to a different entity using a different key the
+encrypted guests data will be incorrectly decrypted, leading to unintelligible
+data.
+
+The key management of this feature is handled by separate processor known as
+AMD secure processor (AMD-SP) which is present in AMD SOCs. Firmware running
+inside the AMD-SP provide commands to support common VM lifecycle. This
+includes commands for launching, snapshotting, migrating and debugging the
+encrypted guest. Those SEV command can be issued via KVM_MEMORY_ENCRYPT_OP
+ioctls.
+
+Launching
+---------
+Boot images (such as bios) must be encrypted before guest can be booted.
+MEMORY_ENCRYPT_OP ioctl provides commands to encrypt the images :LAUNCH_START,
+LAUNCH_UPDATE_DATA, LAUNCH_MEASURE and LAUNCH_FINISH. These four commands
+together generate a fresh memory encryption key for the VM, encrypt the boot
+images and provide a measurement than can be used as an attestation of the
+successful launch.
+
+LAUNCH_START is called first to create a cryptographic launch context within
+the firmware. To create this context, guest owner must provides guest policy,
+its public Diffie-Hellman key (PDH) and session parameters. These inputs
+should be treated as binary blob and must be passed as-is to the SEV firmware.
+
+The guest policy is passed as plaintext and hypervisor may able to read it
+but should not modify it (any modification of the policy bits will result
+in bad measurement). The guest policy is a 4-byte data structure containing
+several flags that restricts what can be done on running SEV guest.
+See KM Spec section 3 and 6.2 for more details.
+
+The guest policy can be provided via the 'policy' property (see below)
+
+# ${QEMU} \
+ sev-guest,id=sev0,policy=0x1...\
+
+Guest owners provided DH certificate and session parameters will be used to
+establish a cryptographic session with the guest owner to negotiate keys used
+for the attestation.
+
+The DH certificate and session blob can be provided via 'dh-cert-file' and
+'session-file' property (see below
+
+# ${QEMU} \
+ sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
+
+LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
+created via LAUNCH_START command. If required, this command can be called
+multiple times to encrypt different memory regions. The command also calculates
+the measurement of the memory contents as it encrypts.
+
+LAUNCH_MEASURE command can be used to retrieve the measurement of encrypted
+memory. This measurement is a signature of the memory contents that can be
+sent to the guest owner as an attestation that the memory was encrypted
+correctly by the firmware. The guest owner may wait to provide the guest
+confidential information until it can verify the attestation measurement.
+Since the guest owner knows the initial contents of the guest at boot, the
+attestation measurement can be verified by comparing it to what the guest owner
+expects.
+
+LAUNCH_FINISH command finalizes the guest launch and destroy's the cryptographic
+context.
+
+See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
+complete flow chart.
+
+To launch a SEV guest
+
+# ${QEMU} \
+ -machine ...,memory-encryption=sev0 \
+ -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
+
+Debugging
+-----------
+Since memory contents of SEV guest is encrypted hence hypervisor access to the
+guest memory will get a cipher text. If guest policy allows debugging, then
+hypervisor can use DEBUG_DECRYPT and DEBUG_ENCRYPT commands access the guest
+memory region for debug purposes. This is not supported in QEMU yet.
+
+Snapshot/Restore
+-----------------
+TODO
+
+Live Migration
+----------------
+TODO
+
+References
+-----------------
+
+AMD Memory Encryption whitepaper:
+http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
+
+Secure Encrypted Virutualization Key Management:
+[1] http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
+
+KVM Forum slides:
+http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
+
+AMD64 Architecture Programmer's Manual:
+ http://support.amd.com/TechDocs/24593.pdf
+ SME is section 7.10
+ SEV is section 15.34
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index ad590a4ffb..ddfcd5adcc 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -867,6 +867,22 @@ Display the amount of initially allocated and present hotpluggable (if
enabled) memory in bytes.
ETEXI
+#if defined(TARGET_I386)
+ {
+ .name = "sev",
+ .args_type = "",
+ .params = "",
+ .help = "show SEV information",
+ .cmd = hmp_info_sev,
+ },
+#endif
+
+STEXI
+@item info sev
+@findex info sev
+Show SEV information.
+ETEXI
+
STEXI
@end table
ETEXI
diff --git a/hmp.h b/hmp.h
index b89733876d..4e2ec375b0 100644
--- a/hmp.h
+++ b/hmp.h
@@ -143,5 +143,6 @@ void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
+void hmp_info_sev(Monitor *mon, const QDict *qdict);
#endif
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 5e2bbcdace..2040177664 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -334,6 +334,22 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
return ms->enforce_config_section;
}
+static char *machine_get_memory_encryption(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return g_strdup(ms->memory_encryption);
+}
+
+static void machine_set_memory_encryption(Object *obj, const char *value,
+ Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ g_free(ms->memory_encryption);
+ ms->memory_encryption = g_strdup(value);
+}
+
void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
{
strList *item = g_new0(strList, 1);
@@ -612,6 +628,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
&error_abort);
object_class_property_set_description(oc, "enforce-config-section",
"Set on to enforce configuration section migration", &error_abort);
+
+ object_class_property_add_str(oc, "memory-encryption",
+ machine_get_memory_encryption, machine_set_memory_encryption,
+ &error_abort);
+ object_class_property_set_description(oc, "memory-encryption",
+ "Set memory encyption object to use", &error_abort);
}
static void machine_class_base_init(ObjectClass *oc, void *data)
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 4325575e7d..73ac783f20 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -113,6 +113,8 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
pflash_t *system_flash;
MemoryRegion *flash_mem;
char name[64];
+ void *flash_ptr;
+ int ret, flash_size;
sector_bits = 12;
sector_size = 1 << sector_bits;
@@ -169,6 +171,17 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
if (unit == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash);
pc_isa_bios_init(rom_memory, flash_mem, size);
+
+ /* Encrypt the pflash boot ROM */
+ if (kvm_memcrypt_enabled()) {
+ flash_ptr = memory_region_get_ram_ptr(flash_mem);
+ flash_size = memory_region_size(flash_mem);
+ ret = kvm_memcrypt_encrypt_data(flash_ptr, flash_size);
+ if (ret) {
+ error_report("failed to encrypt pflash rom");
+ exit(1);
+ }
+ }
}
}
}
diff --git a/include/hw/boards.h b/include/hw/boards.h
index efb0a9edfd..8ce9a7a21d 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -243,6 +243,7 @@ struct MachineState {
bool suppress_vmdesc;
bool enforce_config_section;
bool enable_graphics;
+ char *memory_encryption;
ram_addr_t ram_size;
ram_addr_t maxram_size;
diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
index 79841b543f..9e6a8ba4ce 100644
--- a/include/standard-headers/linux/input-event-codes.h
+++ b/include/standard-headers/linux/input-event-codes.h
@@ -594,6 +594,7 @@
#define BTN_DPAD_RIGHT 0x223
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
+#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
index bc3e6d3d5b..939b62775c 100644
--- a/include/standard-headers/linux/input.h
+++ b/include/standard-headers/linux/input.h
@@ -18,10 +18,21 @@
/*
* The event structure itself
+ * Note that __USE_TIME_BITS64 is defined by libc based on
+ * application's request to use 64 bit time_t.
*/
struct input_event {
+#if (HOST_LONG_BITS != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL)
struct timeval time;
+#define input_event_sec time.tv_sec
+#define input_event_usec time.tv_usec
+#else
+ __kernel_ulong_t __sec;
+ __kernel_ulong_t __usec;
+#define input_event_sec __sec
+#define input_event_usec __usec
+#endif
uint16_t type;
uint16_t code;
int32_t value;
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
index 70c2b2ade0..0c79eac5e9 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -622,15 +622,19 @@
* safely.
*/
#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
+#define PCI_EXP_DEVCAP2_COMP_TMOUT_DIS 0x00000010 /* Completion Timeout Disable supported */
#define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */
#define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */
-#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP32 0x00000080 /* 32b AtomicOp completion */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */
#define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */
#define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */
#define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */
#define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */
+#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */
#define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */
#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040 /* Set Atomic requests */
#define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080 /* Block atomic egress */
@@ -966,26 +970,28 @@
/* Downstream Port Containment */
#define PCI_EXP_DPC_CAP 4 /* DPC Capability */
-#define PCI_EXP_DPC_IRQ 0x1f /* DPC Interrupt Message Number */
-#define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */
-#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */
-#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */
-#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00 /* RP PIO log size */
+#define PCI_EXP_DPC_IRQ 0x001F /* Interrupt Message Number */
+#define PCI_EXP_DPC_CAP_RP_EXT 0x0020 /* Root Port Extensions */
+#define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040 /* Poisoned TLP Egress Blocking Supported */
+#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080 /* Software Triggering Supported */
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size */
#define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */
#define PCI_EXP_DPC_CTL 6 /* DPC control */
-#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02 /* Enable trigger on ERR_NONFATAL message */
-#define PCI_EXP_DPC_CTL_INT_EN 0x08 /* DPC Interrupt Enable */
+#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x0002 /* Enable trigger on ERR_NONFATAL message */
+#define PCI_EXP_DPC_CTL_INT_EN 0x0008 /* DPC Interrupt Enable */
#define PCI_EXP_DPC_STATUS 8 /* DPC Status */
-#define PCI_EXP_DPC_STATUS_TRIGGER 0x01 /* Trigger Status */
-#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08 /* Interrupt Status */
-#define PCI_EXP_DPC_RP_BUSY 0x10 /* Root Port Busy */
+#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */
+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */
+#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */
+#define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */
+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
#define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */
#define PCI_EXP_DPC_RP_PIO_STATUS 0x0C /* RP PIO Status */
-#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO MASK */
+#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO Mask */
#define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14 /* RP PIO Severity */
#define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18 /* RP PIO SysError */
#define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C /* RP PIO Exception */
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
index 30ff24940d..e9f255ea3f 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -57,6 +57,8 @@
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
+#define VIRTIO_NET_F_SPEED_DUPLEX 63 /* Device set linkspeed and duplex */
+
#ifndef VIRTIO_NET_NO_LEGACY
#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */
#endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,17 @@ struct virtio_net_config {
uint16_t max_virtqueue_pairs;
/* Default maximum transmit unit advice */
uint16_t mtu;
+ /*
+ * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+ * Any other value stands for unknown.
+ */
+ uint32_t speed;
+ /*
+ * 0x00 - half duplex
+ * 0x01 - full duplex
+ * Any other value stands for unknown.
+ */
+ uint8_t duplex;
} QEMU_PACKED;
/*
diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h
index f1dc05df25..d26e72bc6b 100644
--- a/include/standard-headers/linux/virtio_ring.h
+++ b/include/standard-headers/linux/virtio_ring.h
@@ -78,7 +78,7 @@ struct vring_avail {
__virtio16 ring[];
};
-/* u32 is used here for ids for padding reasons. */
+/* uint32_t is used here for ids for padding reasons. */
struct vring_used_elem {
/* Index of start of used descriptor chain. */
__virtio32 id;
diff --git a/include/standard-headers/rdma/vmw_pvrdma-abi.h b/include/standard-headers/rdma/vmw_pvrdma-abi.h
index 0d0f7a8aca..07a820d337 100644
--- a/include/standard-headers/rdma/vmw_pvrdma-abi.h
+++ b/include/standard-headers/rdma/vmw_pvrdma-abi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
/*
* Copyright (c) 2012-2016 VMware, Inc. All rights reserved.
*
@@ -51,12 +52,14 @@
#define PVRDMA_UVERBS_ABI_VERSION 3 /* ABI Version. */
#define PVRDMA_UAR_HANDLE_MASK 0x00FFFFFF /* Bottom 24 bits. */
#define PVRDMA_UAR_QP_OFFSET 0 /* QP doorbell. */
-#define PVRDMA_UAR_QP_SEND BIT(30) /* Send bit. */
-#define PVRDMA_UAR_QP_RECV BIT(31) /* Recv bit. */
+#define PVRDMA_UAR_QP_SEND (1 << 30) /* Send bit. */
+#define PVRDMA_UAR_QP_RECV (1 << 31) /* Recv bit. */
#define PVRDMA_UAR_CQ_OFFSET 4 /* CQ doorbell. */
-#define PVRDMA_UAR_CQ_ARM_SOL BIT(29) /* Arm solicited bit. */
-#define PVRDMA_UAR_CQ_ARM BIT(30) /* Arm bit. */
-#define PVRDMA_UAR_CQ_POLL BIT(31) /* Poll bit. */
+#define PVRDMA_UAR_CQ_ARM_SOL (1 << 29) /* Arm solicited bit. */
+#define PVRDMA_UAR_CQ_ARM (1 << 30) /* Arm bit. */
+#define PVRDMA_UAR_CQ_POLL (1 << 31) /* Poll bit. */
+#define PVRDMA_UAR_SRQ_OFFSET 8 /* SRQ doorbell. */
+#define PVRDMA_UAR_SRQ_RECV (1 << 30) /* Recv bit. */
enum pvrdma_wr_opcode {
PVRDMA_WR_RDMA_WRITE,
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 85002ac49a..23669c4d5a 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -231,6 +231,23 @@ int kvm_destroy_vcpu(CPUState *cpu);
*/
bool kvm_arm_supports_user_irq(void);
+/**
+ * kvm_memcrypt_enabled - return boolean indicating whether memory encryption
+ * is enabled
+ * Returns: 1 memory encryption is enabled
+ * 0 memory encryption is disabled
+ */
+bool kvm_memcrypt_enabled(void);
+
+/**
+ * kvm_memcrypt_encrypt_data: encrypt the memory range
+ *
+ * Return: 1 failed to encrypt the range
+ * 0 succesfully encrypted memory region
+ */
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len);
+
+
#ifdef NEED_CPU_H
#include "cpu.h"
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
new file mode 100644
index 0000000000..98c1ec8d38
--- /dev/null
+++ b/include/sysemu/sev.h
@@ -0,0 +1,21 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016-2018
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_SEV_H
+#define QEMU_SEV_H
+
+#include "sysemu/kvm.h"
+
+void *sev_guest_init(const char *id);
+int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
+#endif
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 637b7263cb..833ed9a16a 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -632,6 +632,8 @@ struct kvm_ppc_cpu_char {
#define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)
#define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd)
+#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe)
+
/* Transactional Memory checkpointed state:
* This is all GPRs, all VSX regs and a subset of SPRs
*/
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
index 36abf58582..0c08edcfcd 100644
--- a/linux-headers/asm-powerpc/unistd.h
+++ b/linux-headers/asm-powerpc/unistd.h
@@ -395,5 +395,8 @@
#define __NR_pwritev2 381
#define __NR_kexec_file_load 382
#define __NR_statx 383
+#define __NR_pkey_alloc 384
+#define __NR_pkey_free 385
+#define __NR_pkey_mprotect 386
#endif /* _ASM_POWERPC_UNISTD_H_ */
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
index 99223b874a..27b8b211c8 100644
--- a/linux-headers/asm-s390/unistd.h
+++ b/linux-headers/asm-s390/unistd.h
@@ -8,405 +8,10 @@
#ifndef _ASM_S390_UNISTD_H_
#define _ASM_S390_UNISTD_H_
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_restart_syscall 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_brk 45
-#define __NR_signal 48
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_setpgid 57
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_symlink 83
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_lookup_dcookie 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_getdents 141
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188
-#define __NR_putpmsg 189
-#define __NR_vfork 190
-#define __NR_pivot_root 217
-#define __NR_mincore 218
-#define __NR_madvise 219
-#define __NR_getdents64 220
-#define __NR_readahead 222
-#define __NR_setxattr 224
-#define __NR_lsetxattr 225
-#define __NR_fsetxattr 226
-#define __NR_getxattr 227
-#define __NR_lgetxattr 228
-#define __NR_fgetxattr 229
-#define __NR_listxattr 230
-#define __NR_llistxattr 231
-#define __NR_flistxattr 232
-#define __NR_removexattr 233
-#define __NR_lremovexattr 234
-#define __NR_fremovexattr 235
-#define __NR_gettid 236
-#define __NR_tkill 237
-#define __NR_futex 238
-#define __NR_sched_setaffinity 239
-#define __NR_sched_getaffinity 240
-#define __NR_tgkill 241
-/* Number 242 is reserved for tux */
-#define __NR_io_setup 243
-#define __NR_io_destroy 244
-#define __NR_io_getevents 245
-#define __NR_io_submit 246
-#define __NR_io_cancel 247
-#define __NR_exit_group 248
-#define __NR_epoll_create 249
-#define __NR_epoll_ctl 250
-#define __NR_epoll_wait 251
-#define __NR_set_tid_address 252
-#define __NR_fadvise64 253
-#define __NR_timer_create 254
-#define __NR_timer_settime 255
-#define __NR_timer_gettime 256
-#define __NR_timer_getoverrun 257
-#define __NR_timer_delete 258
-#define __NR_clock_settime 259
-#define __NR_clock_gettime 260
-#define __NR_clock_getres 261
-#define __NR_clock_nanosleep 262
-/* Number 263 is reserved for vserver */
-#define __NR_statfs64 265
-#define __NR_fstatfs64 266
-#define __NR_remap_file_pages 267
-#define __NR_mbind 268
-#define __NR_get_mempolicy 269
-#define __NR_set_mempolicy 270
-#define __NR_mq_open 271
-#define __NR_mq_unlink 272
-#define __NR_mq_timedsend 273
-#define __NR_mq_timedreceive 274
-#define __NR_mq_notify 275
-#define __NR_mq_getsetattr 276
-#define __NR_kexec_load 277
-#define __NR_add_key 278
-#define __NR_request_key 279
-#define __NR_keyctl 280
-#define __NR_waitid 281
-#define __NR_ioprio_set 282
-#define __NR_ioprio_get 283
-#define __NR_inotify_init 284
-#define __NR_inotify_add_watch 285
-#define __NR_inotify_rm_watch 286
-#define __NR_migrate_pages 287
-#define __NR_openat 288
-#define __NR_mkdirat 289
-#define __NR_mknodat 290
-#define __NR_fchownat 291
-#define __NR_futimesat 292
-#define __NR_unlinkat 294
-#define __NR_renameat 295
-#define __NR_linkat 296
-#define __NR_symlinkat 297
-#define __NR_readlinkat 298
-#define __NR_fchmodat 299
-#define __NR_faccessat 300
-#define __NR_pselect6 301
-#define __NR_ppoll 302
-#define __NR_unshare 303
-#define __NR_set_robust_list 304
-#define __NR_get_robust_list 305
-#define __NR_splice 306
-#define __NR_sync_file_range 307
-#define __NR_tee 308
-#define __NR_vmsplice 309
-#define __NR_move_pages 310
-#define __NR_getcpu 311
-#define __NR_epoll_pwait 312
-#define __NR_utimes 313
-#define __NR_fallocate 314
-#define __NR_utimensat 315
-#define __NR_signalfd 316
-#define __NR_timerfd 317
-#define __NR_eventfd 318
-#define __NR_timerfd_create 319
-#define __NR_timerfd_settime 320
-#define __NR_timerfd_gettime 321
-#define __NR_signalfd4 322
-#define __NR_eventfd2 323
-#define __NR_inotify_init1 324
-#define __NR_pipe2 325
-#define __NR_dup3 326
-#define __NR_epoll_create1 327
-#define __NR_preadv 328
-#define __NR_pwritev 329
-#define __NR_rt_tgsigqueueinfo 330
-#define __NR_perf_event_open 331
-#define __NR_fanotify_init 332
-#define __NR_fanotify_mark 333
-#define __NR_prlimit64 334
-#define __NR_name_to_handle_at 335
-#define __NR_open_by_handle_at 336
-#define __NR_clock_adjtime 337
-#define __NR_syncfs 338
-#define __NR_setns 339
-#define __NR_process_vm_readv 340
-#define __NR_process_vm_writev 341
-#define __NR_s390_runtime_instr 342
-#define __NR_kcmp 343
-#define __NR_finit_module 344
-#define __NR_sched_setattr 345
-#define __NR_sched_getattr 346
-#define __NR_renameat2 347
-#define __NR_seccomp 348
-#define __NR_getrandom 349
-#define __NR_memfd_create 350
-#define __NR_bpf 351
-#define __NR_s390_pci_mmio_write 352
-#define __NR_s390_pci_mmio_read 353
-#define __NR_execveat 354
-#define __NR_userfaultfd 355
-#define __NR_membarrier 356
-#define __NR_recvmmsg 357
-#define __NR_sendmmsg 358
-#define __NR_socket 359
-#define __NR_socketpair 360
-#define __NR_bind 361
-#define __NR_connect 362
-#define __NR_listen 363
-#define __NR_accept4 364
-#define __NR_getsockopt 365
-#define __NR_setsockopt 366
-#define __NR_getsockname 367
-#define __NR_getpeername 368
-#define __NR_sendto 369
-#define __NR_sendmsg 370
-#define __NR_recvfrom 371
-#define __NR_recvmsg 372
-#define __NR_shutdown 373
-#define __NR_mlock2 374
-#define __NR_copy_file_range 375
-#define __NR_preadv2 376
-#define __NR_pwritev2 377
-#define __NR_s390_guarded_storage 378
-#define __NR_statx 379
-#define __NR_s390_sthyi 380
-#define NR_syscalls 381
-
-/*
- * There are some system calls that are not present on 64 bit, some
- * have a different name although they do the same (e.g. __NR_chown32
- * is __NR_chown on 64 bit).
- */
-#ifndef __s390x__
-
-#define __NR_time 13
-#define __NR_lchown 16
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_getrlimit 76
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_fchown 95
-#define __NR_ioperm 101
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR__newselect 142
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_chown 182
-#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_lchown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_chown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_fcntl64 221
-#define __NR_sendfile64 223
-#define __NR_fadvise64_64 264
-#define __NR_fstatat64 293
-
+#ifdef __s390x__
+#include <asm/unistd_64.h>
#else
-
-#define __NR_select 142
-#define __NR_getrlimit 191 /* SuS compliant getrlimit */
-#define __NR_lchown 198
-#define __NR_getuid 199
-#define __NR_getgid 200
-#define __NR_geteuid 201
-#define __NR_getegid 202
-#define __NR_setreuid 203
-#define __NR_setregid 204
-#define __NR_getgroups 205
-#define __NR_setgroups 206
-#define __NR_fchown 207
-#define __NR_setresuid 208
-#define __NR_getresuid 209
-#define __NR_setresgid 210
-#define __NR_getresgid 211
-#define __NR_chown 212
-#define __NR_setuid 213
-#define __NR_setgid 214
-#define __NR_setfsuid 215
-#define __NR_setfsgid 216
-#define __NR_newfstatat 293
-
+#include <asm/unistd_32.h>
#endif
#endif /* _ASM_S390_UNISTD_H_ */
diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h
new file mode 100644
index 0000000000..1ae66a263b
--- /dev/null
+++ b/linux-headers/asm-s390/unistd_32.h
@@ -0,0 +1,364 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_S390_UNISTD_32_H
+#define _ASM_S390_UNISTD_32_H
+
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_restart_syscall 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_setpgid 57
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_symlink 83
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_lookup_dcookie 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+#define __NR_readahead 222
+#define __NR_sendfile64 223
+#define __NR_setxattr 224
+#define __NR_lsetxattr 225
+#define __NR_fsetxattr 226
+#define __NR_getxattr 227
+#define __NR_lgetxattr 228
+#define __NR_fgetxattr 229
+#define __NR_listxattr 230
+#define __NR_llistxattr 231
+#define __NR_flistxattr 232
+#define __NR_removexattr 233
+#define __NR_lremovexattr 234
+#define __NR_fremovexattr 235
+#define __NR_gettid 236
+#define __NR_tkill 237
+#define __NR_futex 238
+#define __NR_sched_setaffinity 239
+#define __NR_sched_getaffinity 240
+#define __NR_tgkill 241
+#define __NR_io_setup 243
+#define __NR_io_destroy 244
+#define __NR_io_getevents 245
+#define __NR_io_submit 246
+#define __NR_io_cancel 247
+#define __NR_exit_group 248
+#define __NR_epoll_create 249
+#define __NR_epoll_ctl 250
+#define __NR_epoll_wait 251
+#define __NR_set_tid_address 252
+#define __NR_fadvise64 253
+#define __NR_timer_create 254
+#define __NR_timer_settime 255
+#define __NR_timer_gettime 256
+#define __NR_timer_getoverrun 257
+#define __NR_timer_delete 258
+#define __NR_clock_settime 259
+#define __NR_clock_gettime 260
+#define __NR_clock_getres 261
+#define __NR_clock_nanosleep 262
+#define __NR_fadvise64_64 264
+#define __NR_statfs64 265
+#define __NR_fstatfs64 266
+#define __NR_remap_file_pages 267
+#define __NR_mbind 268
+#define __NR_get_mempolicy 269
+#define __NR_set_mempolicy 270
+#define __NR_mq_open 271
+#define __NR_mq_unlink 272
+#define __NR_mq_timedsend 273
+#define __NR_mq_timedreceive 274
+#define __NR_mq_notify 275
+#define __NR_mq_getsetattr 276
+#define __NR_kexec_load 277
+#define __NR_add_key 278
+#define __NR_request_key 279
+#define __NR_keyctl 280
+#define __NR_waitid 281
+#define __NR_ioprio_set 282
+#define __NR_ioprio_get 283
+#define __NR_inotify_init 284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch 286
+#define __NR_migrate_pages 287
+#define __NR_openat 288
+#define __NR_mkdirat 289
+#define __NR_mknodat 290
+#define __NR_fchownat 291
+#define __NR_futimesat 292
+#define __NR_fstatat64 293
+#define __NR_unlinkat 294
+#define __NR_renameat 295
+#define __NR_linkat 296
+#define __NR_symlinkat 297
+#define __NR_readlinkat 298
+#define __NR_fchmodat 299
+#define __NR_faccessat 300
+#define __NR_pselect6 301
+#define __NR_ppoll 302
+#define __NR_unshare 303
+#define __NR_set_robust_list 304
+#define __NR_get_robust_list 305
+#define __NR_splice 306
+#define __NR_sync_file_range 307
+#define __NR_tee 308
+#define __NR_vmsplice 309
+#define __NR_move_pages 310
+#define __NR_getcpu 311
+#define __NR_epoll_pwait 312
+#define __NR_utimes 313
+#define __NR_fallocate 314
+#define __NR_utimensat 315
+#define __NR_signalfd 316
+#define __NR_timerfd 317
+#define __NR_eventfd 318
+#define __NR_timerfd_create 319
+#define __NR_timerfd_settime 320
+#define __NR_timerfd_gettime 321
+#define __NR_signalfd4 322
+#define __NR_eventfd2 323
+#define __NR_inotify_init1 324
+#define __NR_pipe2 325
+#define __NR_dup3 326
+#define __NR_epoll_create1 327
+#define __NR_preadv 328
+#define __NR_pwritev 329
+#define __NR_rt_tgsigqueueinfo 330
+#define __NR_perf_event_open 331
+#define __NR_fanotify_init 332
+#define __NR_fanotify_mark 333
+#define __NR_prlimit64 334
+#define __NR_name_to_handle_at 335
+#define __NR_open_by_handle_at 336
+#define __NR_clock_adjtime 337
+#define __NR_syncfs 338
+#define __NR_setns 339
+#define __NR_process_vm_readv 340
+#define __NR_process_vm_writev 341
+#define __NR_s390_runtime_instr 342
+#define __NR_kcmp 343
+#define __NR_finit_module 344
+#define __NR_sched_setattr 345
+#define __NR_sched_getattr 346
+#define __NR_renameat2 347
+#define __NR_seccomp 348
+#define __NR_getrandom 349
+#define __NR_memfd_create 350
+#define __NR_bpf 351
+#define __NR_s390_pci_mmio_write 352
+#define __NR_s390_pci_mmio_read 353
+#define __NR_execveat 354
+#define __NR_userfaultfd 355
+#define __NR_membarrier 356
+#define __NR_recvmmsg 357
+#define __NR_sendmmsg 358
+#define __NR_socket 359
+#define __NR_socketpair 360
+#define __NR_bind 361
+#define __NR_connect 362
+#define __NR_listen 363
+#define __NR_accept4 364
+#define __NR_getsockopt 365
+#define __NR_setsockopt 366
+#define __NR_getsockname 367
+#define __NR_getpeername 368
+#define __NR_sendto 369
+#define __NR_sendmsg 370
+#define __NR_recvfrom 371
+#define __NR_recvmsg 372
+#define __NR_shutdown 373
+#define __NR_mlock2 374
+#define __NR_copy_file_range 375
+#define __NR_preadv2 376
+#define __NR_pwritev2 377
+#define __NR_s390_guarded_storage 378
+#define __NR_statx 379
+#define __NR_s390_sthyi 380
+
+#endif /* _ASM_S390_UNISTD_32_H */
diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h
new file mode 100644
index 0000000000..8aa9d046a9
--- /dev/null
+++ b/linux-headers/asm-s390/unistd_64.h
@@ -0,0 +1,331 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_S390_UNISTD_64_H
+#define _ASM_S390_UNISTD_64_H
+
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_restart_syscall 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_brk 45
+#define __NR_signal 48
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_setpgid 57
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_symlink 83
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_lookup_dcookie 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137
+#define __NR_getdents 141
+#define __NR_select 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
+#define __NR_vfork 190
+#define __NR_getrlimit 191
+#define __NR_lchown 198
+#define __NR_getuid 199
+#define __NR_getgid 200
+#define __NR_geteuid 201
+#define __NR_getegid 202
+#define __NR_setreuid 203
+#define __NR_setregid 204
+#define __NR_getgroups 205
+#define __NR_setgroups 206
+#define __NR_fchown 207
+#define __NR_setresuid 208
+#define __NR_getresuid 209
+#define __NR_setresgid 210
+#define __NR_getresgid 211
+#define __NR_chown 212
+#define __NR_setuid 213
+#define __NR_setgid 214
+#define __NR_setfsuid 215
+#define __NR_setfsgid 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_getdents64 220
+#define __NR_readahead 222
+#define __NR_setxattr 224
+#define __NR_lsetxattr 225
+#define __NR_fsetxattr 226
+#define __NR_getxattr 227
+#define __NR_lgetxattr 228
+#define __NR_fgetxattr 229
+#define __NR_listxattr 230
+#define __NR_llistxattr 231
+#define __NR_flistxattr 232
+#define __NR_removexattr 233
+#define __NR_lremovexattr 234
+#define __NR_fremovexattr 235
+#define __NR_gettid 236
+#define __NR_tkill 237
+#define __NR_futex 238
+#define __NR_sched_setaffinity 239
+#define __NR_sched_getaffinity 240
+#define __NR_tgkill 241
+#define __NR_io_setup 243
+#define __NR_io_destroy 244
+#define __NR_io_getevents 245
+#define __NR_io_submit 246
+#define __NR_io_cancel 247
+#define __NR_exit_group 248
+#define __NR_epoll_create 249
+#define __NR_epoll_ctl 250
+#define __NR_epoll_wait 251
+#define __NR_set_tid_address 252
+#define __NR_fadvise64 253
+#define __NR_timer_create 254
+#define __NR_timer_settime 255
+#define __NR_timer_gettime 256
+#define __NR_timer_getoverrun 257
+#define __NR_timer_delete 258
+#define __NR_clock_settime 259
+#define __NR_clock_gettime 260
+#define __NR_clock_getres 261
+#define __NR_clock_nanosleep 262
+#define __NR_statfs64 265
+#define __NR_fstatfs64 266
+#define __NR_remap_file_pages 267
+#define __NR_mbind 268
+#define __NR_get_mempolicy 269
+#define __NR_set_mempolicy 270
+#define __NR_mq_open 271
+#define __NR_mq_unlink 272
+#define __NR_mq_timedsend 273
+#define __NR_mq_timedreceive 274
+#define __NR_mq_notify 275
+#define __NR_mq_getsetattr 276
+#define __NR_kexec_load 277
+#define __NR_add_key 278
+#define __NR_request_key 279
+#define __NR_keyctl 280
+#define __NR_waitid 281
+#define __NR_ioprio_set 282
+#define __NR_ioprio_get 283
+#define __NR_inotify_init 284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch 286
+#define __NR_migrate_pages 287
+#define __NR_openat 288
+#define __NR_mkdirat 289
+#define __NR_mknodat 290
+#define __NR_fchownat 291
+#define __NR_futimesat 292
+#define __NR_newfstatat 293
+#define __NR_unlinkat 294
+#define __NR_renameat 295
+#define __NR_linkat 296
+#define __NR_symlinkat 297
+#define __NR_readlinkat 298
+#define __NR_fchmodat 299
+#define __NR_faccessat 300
+#define __NR_pselect6 301
+#define __NR_ppoll 302
+#define __NR_unshare 303
+#define __NR_set_robust_list 304
+#define __NR_get_robust_list 305
+#define __NR_splice 306
+#define __NR_sync_file_range 307
+#define __NR_tee 308
+#define __NR_vmsplice 309
+#define __NR_move_pages 310
+#define __NR_getcpu 311
+#define __NR_epoll_pwait 312
+#define __NR_utimes 313
+#define __NR_fallocate 314
+#define __NR_utimensat 315
+#define __NR_signalfd 316
+#define __NR_timerfd 317
+#define __NR_eventfd 318
+#define __NR_timerfd_create 319
+#define __NR_timerfd_settime 320
+#define __NR_timerfd_gettime 321
+#define __NR_signalfd4 322
+#define __NR_eventfd2 323
+#define __NR_inotify_init1 324
+#define __NR_pipe2 325
+#define __NR_dup3 326
+#define __NR_epoll_create1 327
+#define __NR_preadv 328
+#define __NR_pwritev 329
+#define __NR_rt_tgsigqueueinfo 330
+#define __NR_perf_event_open 331
+#define __NR_fanotify_init 332
+#define __NR_fanotify_mark 333
+#define __NR_prlimit64 334
+#define __NR_name_to_handle_at 335
+#define __NR_open_by_handle_at 336
+#define __NR_clock_adjtime 337
+#define __NR_syncfs 338
+#define __NR_setns 339
+#define __NR_process_vm_readv 340
+#define __NR_process_vm_writev 341
+#define __NR_s390_runtime_instr 342
+#define __NR_kcmp 343
+#define __NR_finit_module 344
+#define __NR_sched_setattr 345
+#define __NR_sched_getattr 346
+#define __NR_renameat2 347
+#define __NR_seccomp 348
+#define __NR_getrandom 349
+#define __NR_memfd_create 350
+#define __NR_bpf 351
+#define __NR_s390_pci_mmio_write 352
+#define __NR_s390_pci_mmio_read 353
+#define __NR_execveat 354
+#define __NR_userfaultfd 355
+#define __NR_membarrier 356
+#define __NR_recvmmsg 357
+#define __NR_sendmmsg 358
+#define __NR_socket 359
+#define __NR_socketpair 360
+#define __NR_bind 361
+#define __NR_connect 362
+#define __NR_listen 363
+#define __NR_accept4 364
+#define __NR_getsockopt 365
+#define __NR_setsockopt 366
+#define __NR_getsockname 367
+#define __NR_getpeername 368
+#define __NR_sendto 369
+#define __NR_sendmsg 370
+#define __NR_recvfrom 371
+#define __NR_recvmsg 372
+#define __NR_shutdown 373
+#define __NR_mlock2 374
+#define __NR_copy_file_range 375
+#define __NR_preadv2 376
+#define __NR_pwritev2 377
+#define __NR_s390_guarded_storage 378
+#define __NR_statx 379
+#define __NR_s390_sthyi 380
+
+#endif /* _ASM_S390_UNISTD_64_H */
diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h
index 4c300f6aaa..4c58184395 100644
--- a/linux-headers/asm-x86/kvm_para.h
+++ b/linux-headers/asm-x86/kvm_para.h
@@ -25,6 +25,8 @@
#define KVM_FEATURE_STEAL_TIME 5
#define KVM_FEATURE_PV_EOI 6
#define KVM_FEATURE_PV_UNHALT 7
+#define KVM_FEATURE_PV_TLB_FLUSH 9
+#define KVM_FEATURE_ASYNC_PF_VMEXIT 10
/* The last 8 bits are used to indicate how to interpret the flags field
* in pvclock structure. If no bits are set, all flags are ignored.
@@ -51,6 +53,9 @@ struct kvm_steal_time {
__u32 pad[11];
};
+#define KVM_VCPU_PREEMPTED (1 << 0)
+#define KVM_VCPU_FLUSH_TLB (1 << 1)
+
#define KVM_CLOCK_PAIRING_WALLCLOCK 0
struct kvm_clock_pairing {
__s64 sec;
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index d92c9b2f0e..a167be89d1 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -761,6 +761,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07
#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08
#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
+#define KVM_GET_MSR_FEATURE_INDEX_LIST _IOWR(KVMIO, 0x0a, struct kvm_msr_list)
/*
* Extension capability list.
@@ -934,6 +935,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_S390_AIS_MIGRATION 150
#define KVM_CAP_PPC_GET_CPU_CHAR 151
#define KVM_CAP_S390_BPB 152
+#define KVM_CAP_GET_MSR_FEATURES 153
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1362,6 +1364,96 @@ struct kvm_s390_ucas_mapping {
/* Available with KVM_CAP_S390_CMMA_MIGRATION */
#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log)
#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log)
+/* Memory Encryption Commands */
+#define KVM_MEMORY_ENCRYPT_OP _IOWR(KVMIO, 0xba, unsigned long)
+
+struct kvm_enc_region {
+ __u64 addr;
+ __u64 size;
+};
+
+#define KVM_MEMORY_ENCRYPT_REG_REGION _IOR(KVMIO, 0xbb, struct kvm_enc_region)
+#define KVM_MEMORY_ENCRYPT_UNREG_REGION _IOR(KVMIO, 0xbc, struct kvm_enc_region)
+
+/* Secure Encrypted Virtualization command */
+enum sev_cmd_id {
+ /* Guest initialization commands */
+ KVM_SEV_INIT = 0,
+ KVM_SEV_ES_INIT,
+ /* Guest launch commands */
+ KVM_SEV_LAUNCH_START,
+ KVM_SEV_LAUNCH_UPDATE_DATA,
+ KVM_SEV_LAUNCH_UPDATE_VMSA,
+ KVM_SEV_LAUNCH_SECRET,
+ KVM_SEV_LAUNCH_MEASURE,
+ KVM_SEV_LAUNCH_FINISH,
+ /* Guest migration commands (outgoing) */
+ KVM_SEV_SEND_START,
+ KVM_SEV_SEND_UPDATE_DATA,
+ KVM_SEV_SEND_UPDATE_VMSA,
+ KVM_SEV_SEND_FINISH,
+ /* Guest migration commands (incoming) */
+ KVM_SEV_RECEIVE_START,
+ KVM_SEV_RECEIVE_UPDATE_DATA,
+ KVM_SEV_RECEIVE_UPDATE_VMSA,
+ KVM_SEV_RECEIVE_FINISH,
+ /* Guest status and debug commands */
+ KVM_SEV_GUEST_STATUS,
+ KVM_SEV_DBG_DECRYPT,
+ KVM_SEV_DBG_ENCRYPT,
+ /* Guest certificates commands */
+ KVM_SEV_CERT_EXPORT,
+
+ KVM_SEV_NR_MAX,
+};
+
+struct kvm_sev_cmd {
+ __u32 id;
+ __u64 data;
+ __u32 error;
+ __u32 sev_fd;
+};
+
+struct kvm_sev_launch_start {
+ __u32 handle;
+ __u32 policy;
+ __u64 dh_uaddr;
+ __u32 dh_len;
+ __u64 session_uaddr;
+ __u32 session_len;
+};
+
+struct kvm_sev_launch_update_data {
+ __u64 uaddr;
+ __u32 len;
+};
+
+
+struct kvm_sev_launch_secret {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+};
+
+struct kvm_sev_launch_measure {
+ __u64 uaddr;
+ __u32 len;
+};
+
+struct kvm_sev_guest_status {
+ __u32 handle;
+ __u32 policy;
+ __u32 state;
+};
+
+struct kvm_sev_dbg {
+ __u64 src_uaddr;
+ __u64 dst_uaddr;
+ __u32 len;
+};
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h
index ccd17731c6..3905492d18 100644
--- a/linux-headers/linux/psci.h
+++ b/linux-headers/linux/psci.h
@@ -88,6 +88,9 @@
(((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)
#define PSCI_VERSION_MINOR(ver) \
((ver) & PSCI_VERSION_MINOR_MASK)
+#define PSCI_VERSION(maj, min) \
+ ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \
+ ((min) & PSCI_VERSION_MINOR_MASK))
/* PSCI features decoding (>=1.0) */
#define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h
new file mode 100644
index 0000000000..33e247471a
--- /dev/null
+++ b/linux-headers/linux/psp-sev.h
@@ -0,0 +1,142 @@
+/*
+ * Userspace interface for AMD Secure Encrypted Virtualization (SEV)
+ * platform management commands.
+ *
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
+ *
+ * Author: Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * SEV spec 0.14 is available at:
+ * http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PSP_SEV_USER_H__
+#define __PSP_SEV_USER_H__
+
+#include <linux/types.h>
+
+/**
+ * SEV platform commands
+ */
+enum {
+ SEV_FACTORY_RESET = 0,
+ SEV_PLATFORM_STATUS,
+ SEV_PEK_GEN,
+ SEV_PEK_CSR,
+ SEV_PDH_GEN,
+ SEV_PDH_CERT_EXPORT,
+ SEV_PEK_CERT_IMPORT,
+
+ SEV_MAX,
+};
+
+/**
+ * SEV Firmware status code
+ */
+typedef enum {
+ SEV_RET_SUCCESS = 0,
+ SEV_RET_INVALID_PLATFORM_STATE,
+ SEV_RET_INVALID_GUEST_STATE,
+ SEV_RET_INAVLID_CONFIG,
+ SEV_RET_INVALID_LEN,
+ SEV_RET_ALREADY_OWNED,
+ SEV_RET_INVALID_CERTIFICATE,
+ SEV_RET_POLICY_FAILURE,
+ SEV_RET_INACTIVE,
+ SEV_RET_INVALID_ADDRESS,
+ SEV_RET_BAD_SIGNATURE,
+ SEV_RET_BAD_MEASUREMENT,
+ SEV_RET_ASID_OWNED,
+ SEV_RET_INVALID_ASID,
+ SEV_RET_WBINVD_REQUIRED,
+ SEV_RET_DFFLUSH_REQUIRED,
+ SEV_RET_INVALID_GUEST,
+ SEV_RET_INVALID_COMMAND,
+ SEV_RET_ACTIVE,
+ SEV_RET_HWSEV_RET_PLATFORM,
+ SEV_RET_HWSEV_RET_UNSAFE,
+ SEV_RET_UNSUPPORTED,
+ SEV_RET_MAX,
+} sev_ret_code;
+
+/**
+ * struct sev_user_data_status - PLATFORM_STATUS command parameters
+ *
+ * @major: major API version
+ * @minor: minor API version
+ * @state: platform state
+ * @flags: platform config flags
+ * @build: firmware build id for API version
+ * @guest_count: number of active guests
+ */
+struct sev_user_data_status {
+ __u8 api_major; /* Out */
+ __u8 api_minor; /* Out */
+ __u8 state; /* Out */
+ __u32 flags; /* Out */
+ __u8 build; /* Out */
+ __u32 guest_count; /* Out */
+} __attribute__((packed));
+
+/**
+ * struct sev_user_data_pek_csr - PEK_CSR command parameters
+ *
+ * @address: PEK certificate chain
+ * @length: length of certificate
+ */
+struct sev_user_data_pek_csr {
+ __u64 address; /* In */
+ __u32 length; /* In/Out */
+} __attribute__((packed));
+
+/**
+ * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters
+ *
+ * @pek_address: PEK certificate chain
+ * @pek_len: length of PEK certificate
+ * @oca_address: OCA certificate chain
+ * @oca_len: length of OCA certificate
+ */
+struct sev_user_data_pek_cert_import {
+ __u64 pek_cert_address; /* In */
+ __u32 pek_cert_len; /* In */
+ __u64 oca_cert_address; /* In */
+ __u32 oca_cert_len; /* In */
+} __attribute__((packed));
+
+/**
+ * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
+ *
+ * @pdh_address: PDH certificate address
+ * @pdh_len: length of PDH certificate
+ * @cert_chain_address: PDH certificate chain
+ * @cert_chain_len: length of PDH certificate chain
+ */
+struct sev_user_data_pdh_cert_export {
+ __u64 pdh_cert_address; /* In */
+ __u32 pdh_cert_len; /* In/Out */
+ __u64 cert_chain_address; /* In */
+ __u32 cert_chain_len; /* In/Out */
+} __attribute__((packed));
+
+/**
+ * struct sev_issue_cmd - SEV ioctl parameters
+ *
+ * @cmd: SEV commands to execute
+ * @opaque: pointer to the command structure
+ * @error: SEV FW return code on failure
+ */
+struct sev_issue_cmd {
+ __u32 cmd; /* In */
+ __u64 data; /* In */
+ __u32 error; /* Out */
+} __attribute__((packed));
+
+#define SEV_IOC_TYPE 'S'
+#define SEV_ISSUE_CMD _IOWR(SEV_IOC_TYPE, 0x0, struct sev_issue_cmd)
+
+#endif /* __PSP_USER_SEV_H */
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 4312e961ff..3a0a305c8c 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -301,6 +301,16 @@ struct vfio_region_info_cap_type {
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
+/*
+ * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
+ * which allows direct access to non-MSIX registers which happened to be within
+ * the same system page.
+ *
+ * Even though the userspace gets direct access to the MSIX data, the existing
+ * VFIO_DEVICE_SET_IRQS interface must still be used for MSIX configuration.
+ */
+#define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3
+
/**
* VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
* struct vfio_irq_info)
@@ -503,6 +513,68 @@ struct vfio_pci_hot_reset {
#define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13)
+/**
+ * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14,
+ * struct vfio_device_query_gfx_plane)
+ *
+ * Set the drm_plane_type and flags, then retrieve the gfx plane info.
+ *
+ * flags supported:
+ * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set
+ * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no
+ * support for dma-buf.
+ * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set
+ * to ask if the mdev supports region. 0 on support, -EINVAL on no
+ * support for region.
+ * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set
+ * with each call to query the plane info.
+ * - Others are invalid and return -EINVAL.
+ *
+ * Note:
+ * 1. Plane could be disabled by guest. In that case, success will be
+ * returned with zero-initialized drm_format, size, width and height
+ * fields.
+ * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available
+ *
+ * Return: 0 on success, -errno on other failure.
+ */
+struct vfio_device_gfx_plane_info {
+ __u32 argsz;
+ __u32 flags;
+#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0)
+#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1)
+#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2)
+ /* in */
+ __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */
+ /* out */
+ __u32 drm_format; /* drm format of plane */
+ __u64 drm_format_mod; /* tiled mode */
+ __u32 width; /* width of plane */
+ __u32 height; /* height of plane */
+ __u32 stride; /* stride of plane */
+ __u32 size; /* size of plane in bytes, align on page*/
+ __u32 x_pos; /* horizontal position of cursor plane */
+ __u32 y_pos; /* vertical position of cursor plane*/
+ __u32 x_hot; /* horizontal position of cursor hotspot */
+ __u32 y_hot; /* vertical position of cursor hotspot */
+ union {
+ __u32 region_index; /* region index */
+ __u32 dmabuf_id; /* dma-buf id */
+ };
+};
+
+#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14)
+
+/**
+ * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32)
+ *
+ * Return a new dma-buf file descriptor for an exposed guest framebuffer
+ * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_
+ * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer.
+ */
+
+#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15)
+
/* -------- API for Type1 VFIO IOMMU -------- */
/**
diff --git a/monitor.c b/monitor.c
index a4417f26cd..3117a3e689 100644
--- a/monitor.c
+++ b/monitor.c
@@ -983,6 +983,9 @@ static void qmp_unregister_commands_hack(void)
#endif
#ifndef TARGET_I386
qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection");
+ qmp_unregister_command(&qmp_commands, "query-sev");
+ qmp_unregister_command(&qmp_commands, "query-sev-launch-measure");
+ qmp_unregister_command(&qmp_commands, "query-sev-capabilities");
#endif
#ifndef TARGET_S390X
qmp_unregister_command(&qmp_commands, "dump-skeys");
@@ -4103,6 +4106,24 @@ void qmp_rtc_reset_reinjection(Error **errp)
{
error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
}
+
+SevInfo *qmp_query_sev(Error **errp)
+{
+ error_setg(errp, QERR_FEATURE_DISABLED, "query-sev");
+ return NULL;
+}
+
+SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
+{
+ error_setg(errp, QERR_FEATURE_DISABLED, "query-sev-launch-measure");
+ return NULL;
+}
+
+SevCapability *qmp_query_sev_capabilities(Error **errp)
+{
+ error_setg(errp, QERR_FEATURE_DISABLED, "query-sev-capabilities");
+ return NULL;
+}
#endif
#ifndef TARGET_S390X
diff --git a/qapi/misc.json b/qapi/misc.json
index bcd5d10778..6150b9a003 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -3216,3 +3216,151 @@
# Since: 2.9
##
{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
+
+
+##
+# @SevState:
+#
+# An enumeration of SEV state information used during @query-sev.
+#
+# @uninit: The guest is uninitialized.
+#
+# @launch-update: The guest is currently being launched; plaintext data and
+# register state is being imported.
+#
+# @launch-secret: The guest is currently being launched; ciphertext data
+# is being imported.
+#
+# @running: The guest is fully launched or migrated in.
+#
+# @send-update: The guest is currently being migrated out to another machine.
+#
+# @receive-update: The guest is currently being migrated from another machine.
+#
+# Since: 2.12
+##
+{ 'enum': 'SevState',
+ 'data': ['uninit', 'launch-update', 'launch-secret', 'running',
+ 'send-update', 'receive-update' ] }
+
+##
+# @SevInfo:
+#
+# Information about Secure Encrypted Virtualization (SEV) support
+#
+# @enabled: true if SEV is active
+#
+# @api-major: SEV API major version
+#
+# @api-minor: SEV API minor version
+#
+# @build-id: SEV FW build id
+#
+# @policy: SEV policy value
+#
+# @state: SEV guest state
+#
+# @handle: SEV firmware handle
+#
+# Since: 2.12
+##
+{ 'struct': 'SevInfo',
+ 'data': { 'enabled': 'bool',
+ 'api-major': 'uint8',
+ 'api-minor' : 'uint8',
+ 'build-id' : 'uint8',
+ 'policy' : 'uint32',
+ 'state' : 'SevState',
+ 'handle' : 'uint32'
+ }
+}
+
+##
+# @query-sev:
+#
+# Returns information about SEV
+#
+# Returns: @SevInfo
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev" }
+# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+# "build-id" : 0, "policy" : 0, "state" : "running",
+# "handle" : 1 } }
+#
+##
+{ 'command': 'query-sev', 'returns': 'SevInfo' }
+
+##
+# @SevLaunchMeasureInfo:
+#
+# SEV Guest Launch measurement information
+#
+# @data: the measurement value encoded in base64
+#
+# Since: 2.12
+#
+##
+{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'} }
+
+##
+# @query-sev-launch-measure:
+#
+# Query the SEV guest launch information.
+#
+# Returns: The @SevLaunchMeasureInfo for the guest
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-launch-measure" }
+# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
+#
+##
+{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo' }
+
+##
+# @SevCapability:
+#
+# The struct describes capability for a Secure Encrypted Virtualization
+# feature.
+#
+# @pdh: Platform Diffie-Hellman key (base64 encoded)
+#
+# @cert-chain: PDH certificate chain (base64 encoded)
+#
+# @cbitpos: C-bit location in page table entry
+#
+# @reduced-phys-bits: Number of physical Address bit reduction when SEV is
+# enabled
+#
+# Since: 2.12
+##
+{ 'struct': 'SevCapability',
+ 'data': { 'pdh': 'str',
+ 'cert-chain': 'str',
+ 'cbitpos': 'int',
+ 'reduced-phys-bits': 'int'} }
+
+##
+# @query-sev-capabilities:
+#
+# This command is used to get the SEV capabilities, and is supported on AMD
+# X86 platforms only.
+#
+# Returns: SevCapability objects.
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-capabilities" }
+# <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE",
+# "cbitpos": 47, "reduced-phys-bits": 5}}
+#
+##
+{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability' }
diff --git a/qemu-options.hx b/qemu-options.hx
index 6585058c6c..6113bce08a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -43,7 +43,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
" nvdimm=on|off controls NVDIMM support (default=off)\n"
" enforce-config-section=on|off enforce configuration section migration (default=off)\n"
- " s390-squash-mcss=on|off (deprecated) controls support for squashing into default css (default=off)\n",
+ " s390-squash-mcss=on|off (deprecated) controls support for squashing into default css (default=off)\n"
+ " memory-encryption=@var{} memory encryption object to use (default=none)\n",
QEMU_ARCH_ALL)
STEXI
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
@@ -110,6 +111,8 @@ code to send configuration section even if the machine-type sets the
@option{migration.send-configuration} property to @var{off}.
NOTE: this parameter is deprecated. Please use @option{-global}
@option{migration.send-configuration}=@var{on|off} instead.
+@item memory-encryption=@var{}
+Memory encryption object to use. The default is none.
@end table
ETEXI
@@ -4350,6 +4353,50 @@ contents of @code{iv.b64} to the second secret
data=$SECRET,iv=$(<iv.b64)
@end example
+@item -object sev-guest,id=@var{id},cbitpos=@var{cbitpos},reduced-phys-bits=@var{val},[sev-device=@var{string},policy=@var{policy},handle=@var{handle},dh-cert-file=@var{file},session-file=@var{file}]
+
+Create a Secure Encrypted Virtualization (SEV) guest object, which can be used
+to provide the guest memory encryption support on AMD processors.
+
+When memory encryption is enabled, one of the physical address bit (aka the
+C-bit) is utilized to mark if a memory page is protected. The @option{cbitpos}
+is used to provide the C-bit position. The C-bit position is Host family dependent
+hence user must provide this value. On EPYC, the value should be 47.
+
+When memory encryption is enabled, we loose certain bits in physical address space.
+The @option{reduced-phys-bits} is used to provide the number of bits we loose in
+physical address space. Similar to C-bit, the value is Host family dependent.
+On EPYC, the value should be 5.
+
+The @option{sev-device} provides the device file to use for communicating with
+the SEV firmware running inside AMD Secure Processor. The default device is
+'/dev/sev'. If hardware supports memory encryption then /dev/sev devices are
+created by CCP driver.
+
+The @option{policy} provides the guest policy to be enforced by the SEV firmware
+and restrict what configuration and operational commands can be performed on this
+guest by the hypervisor. The policy should be provided by the guest owner and is
+bound to the guest and cannot be changed throughout the lifetime of the guest.
+The default is 0.
+
+If guest @option{policy} allows sharing the key with another SEV guest then
+@option{handle} can be use to provide handle of the guest from which to share
+the key.
+
+The @option{dh-cert-file} and @option{session-file} provides the guest owner's
+Public Diffie-Hillman key defined in SEV spec. The PDH and session parameters
+are used for establishing a cryptographic session with the guest owner to
+negotiate keys used for attestation. The file must be encoded in base64.
+
+e.g to launch a SEV guest
+@example
+ # $QEMU \
+ ......
+ -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \
+ -machine ...,memory-encryption=sev0
+ .....
+
+@end example
@end table
ETEXI
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index be065704df..e152417936 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -56,6 +56,7 @@ cp_portable() {
-e 's/__bitwise//' \
-e 's/__attribute__((packed))/QEMU_PACKED/' \
-e 's/__inline__/inline/' \
+ -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \
-e '/sys\/ioctl.h/d' \
-e 's/SW_MAX/SW_MAX_/' \
-e 's/atomic_t/int/' \
@@ -99,6 +100,8 @@ for arch in $ARCHLIST; do
mkdir -p "$output/include/standard-headers/asm-$arch"
if [ $arch = s390 ]; then
cp_portable "$tmpdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/"
+ cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-s390/"
+ cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-s390/"
fi
if [ $arch = arm ]; then
cp "$tmpdir/include/asm/unistd-eabi.h" "$output/linux-headers/asm-arm/"
@@ -118,7 +121,7 @@ done
rm -rf "$output/linux-headers/linux"
mkdir -p "$output/linux-headers/linux"
for header in kvm.h kvm_para.h vfio.h vfio_ccw.h vhost.h \
- psci.h userfaultfd.h; do
+ psci.h psp-sev.h userfaultfd.h; do
cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux"
done
rm -rf "$output/linux-headers/asm-generic"
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index f5c6ef20a7..04678f5503 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -5,7 +5,9 @@ obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
obj-$(CONFIG_KVM) += kvm.o hyperv.o
+obj-$(CONFIG_SEV) += sev.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+obj-$(call lnot,$(CONFIG_SEV)) += sev-stub.o
# HAX support
ifdef CONFIG_WIN32
obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ec1efd3a3c..6bb4ce8719 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -26,6 +26,7 @@
#include "sysemu/hvf.h"
#include "sysemu/cpus.h"
#include "kvm_i386.h"
+#include "sev_i386.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
@@ -3672,6 +3673,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = 0;
*edx = 0;
break;
+ case 0x8000001F:
+ *eax = sev_enabled() ? 0x2 : 0;
+ *ebx = sev_get_cbit_position();
+ *ebx |= sev_get_reduced_phys_bits() << 6;
+ *ecx = 0;
+ *edx = 0;
+ break;
default:
/* reserved values: zero */
*eax = 0;
@@ -3705,6 +3713,7 @@ static void x86_cpu_reset(CPUState *s)
cpu_x86_update_cr0(env, 0x60000010);
env->a20_mask = ~0x0;
env->smbase = 0x30000;
+ env->msr_smi_count = 0;
env->idt.limit = 0xffff;
env->gdt.limit = 0xffff;
@@ -4101,6 +4110,11 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
}
+
+ /* SEV requires CPUID[0x8000001F] */
+ if (sev_enabled()) {
+ x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
+ }
}
/* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 0c3f51445e..2e2bab5ff3 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1,3 +1,4 @@
+
/*
* i386 virtual CPU header
*
@@ -359,6 +360,7 @@ typedef enum X86Seg {
#define MSR_P6_PERFCTR0 0xc1
#define MSR_IA32_SMBASE 0x9e
+#define MSR_SMI_COUNT 0x34
#define MSR_MTRRcap 0xfe
#define MSR_MTRRcap_VCNT 8
#define MSR_MTRRcap_FIXRANGE_SUPPORT (1 << 8)
@@ -1142,6 +1144,7 @@ typedef struct CPUX86State {
uint64_t pat;
uint32_t smbase;
+ uint64_t msr_smi_count;
uint32_t pkru;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index d996cca68b..d23fff12f5 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -92,6 +92,7 @@ static bool has_msr_hv_stimer;
static bool has_msr_hv_frequencies;
static bool has_msr_xss;
static bool has_msr_spec_ctrl;
+static bool has_msr_smi_count;
static uint32_t has_architectural_pmu_version;
static uint32_t num_architectural_pmu_gp_counters;
@@ -1151,6 +1152,9 @@ static int kvm_get_supported_msrs(KVMState *s)
case MSR_IA32_SMBASE:
has_msr_smbase = true;
break;
+ case MSR_SMI_COUNT:
+ has_msr_smi_count = true;
+ break;
case MSR_IA32_MISC_ENABLE:
has_msr_misc_enable = true;
break;
@@ -1660,6 +1664,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (has_msr_smbase) {
kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, env->smbase);
}
+ if (has_msr_smi_count) {
+ kvm_msr_entry_add(cpu, MSR_SMI_COUNT, env->msr_smi_count);
+ }
if (has_msr_bndcfgs) {
kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs);
}
@@ -2025,6 +2032,9 @@ static int kvm_get_msrs(X86CPU *cpu)
if (has_msr_smbase) {
kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, 0);
}
+ if (has_msr_smi_count) {
+ kvm_msr_entry_add(cpu, MSR_SMI_COUNT, 0);
+ }
if (has_msr_feature_control) {
kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0);
}
@@ -2265,6 +2275,9 @@ static int kvm_get_msrs(X86CPU *cpu)
case MSR_IA32_SMBASE:
env->smbase = msrs[i].data;
break;
+ case MSR_SMI_COUNT:
+ env->msr_smi_count = msrs[i].data;
+ break;
case MSR_IA32_FEATURE_CONTROL:
env->msr_ia32_feature_control = msrs[i].data;
break;
diff --git a/target/i386/machine.c b/target/i386/machine.c
index c05fe6fb1a..bd2d82e91b 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -395,6 +395,25 @@ static const VMStateDescription vmstate_msr_tsc_adjust = {
}
};
+static bool msr_smi_count_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return env->msr_smi_count != 0;
+}
+
+static const VMStateDescription vmstate_msr_smi_count = {
+ .name = "cpu/msr_smi_count",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = msr_smi_count_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.msr_smi_count, X86CPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static bool tscdeadline_needed(void *opaque)
{
X86CPU *cpu = opaque;
@@ -989,6 +1008,7 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_avx512,
&vmstate_xss,
&vmstate_tsc_khz,
+ &vmstate_msr_smi_count,
#ifdef TARGET_X86_64
&vmstate_pkru,
#endif
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 75429129fd..011419eba2 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -29,7 +29,11 @@
#include "qapi/qmp/qdict.h"
#include "hw/i386/pc.h"
#include "sysemu/kvm.h"
+#include "sysemu/sev.h"
#include "hmp.h"
+#include "qapi/error.h"
+#include "sev_i386.h"
+#include "qapi/qapi-commands-misc.h"
static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
@@ -661,3 +665,65 @@ void hmp_info_io_apic(Monitor *mon, const QDict *qdict)
ioapic_dump_state(mon, qdict);
}
}
+
+SevInfo *qmp_query_sev(Error **errp)
+{
+ SevInfo *info;
+
+ info = sev_get_info();
+ if (!info) {
+ error_setg(errp, "SEV feature is not available");
+ return NULL;
+ }
+
+ return info;
+}
+
+void hmp_info_sev(Monitor *mon, const QDict *qdict)
+{
+ SevInfo *info = sev_get_info();
+
+ if (info && info->enabled) {
+ monitor_printf(mon, "handle: %d\n", info->handle);
+ monitor_printf(mon, "state: %s\n", SevState_str(info->state));
+ monitor_printf(mon, "build: %d\n", info->build_id);
+ monitor_printf(mon, "api version: %d.%d\n",
+ info->api_major, info->api_minor);
+ monitor_printf(mon, "debug: %s\n",
+ info->policy & SEV_POLICY_NODBG ? "off" : "on");
+ monitor_printf(mon, "key-sharing: %s\n",
+ info->policy & SEV_POLICY_NOKS ? "off" : "on");
+ } else {
+ monitor_printf(mon, "SEV is not enabled\n");
+ }
+}
+
+SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
+{
+ char *data;
+ SevLaunchMeasureInfo *info;
+
+ data = sev_get_launch_measurement();
+ if (!data) {
+ error_setg(errp, "Measurement is not available");
+ return NULL;
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->data = data;
+
+ return info;
+}
+
+SevCapability *qmp_query_sev_capabilities(Error **errp)
+{
+ SevCapability *data;
+
+ data = sev_get_capabilities();
+ if (!data) {
+ error_setg(errp, "SEV feature is not available");
+ return NULL;
+ }
+
+ return data;
+}
diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
new file mode 100644
index 0000000000..59a003a4eb
--- /dev/null
+++ b/target/i386/sev-stub.c
@@ -0,0 +1,51 @@
+/*
+ * QEMU SEV stub
+ *
+ * Copyright Advanced Micro Devices 2018
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sev_i386.h"
+
+SevInfo *sev_get_info(void)
+{
+ return NULL;
+}
+
+bool sev_enabled(void)
+{
+ return false;
+}
+
+uint64_t sev_get_me_mask(void)
+{
+ return ~0;
+}
+
+uint32_t sev_get_cbit_position(void)
+{
+ return 0;
+}
+
+uint32_t sev_get_reduced_phys_bits(void)
+{
+ return 0;
+}
+
+char *sev_get_launch_measurement(void)
+{
+ return NULL;
+}
+
+SevCapability *sev_get_capabilities(void)
+{
+ return NULL;
+}
diff --git a/target/i386/sev.c b/target/i386/sev.c
new file mode 100644
index 0000000000..019d84cef2
--- /dev/null
+++ b/target/i386/sev.c
@@ -0,0 +1,811 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016-2018
+ *
+ * Author:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <linux/kvm.h>
+#include <linux/psp-sev.h>
+
+#include <sys/ioctl.h>
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+#include "sysemu/kvm.h"
+#include "sev_i386.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+#include "migration/blocker.h"
+
+#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
+#define DEFAULT_SEV_DEVICE "/dev/sev"
+
+static SEVState *sev_state;
+static Error *sev_mig_blocker;
+
+static const char *const sev_fw_errlist[] = {
+ "",
+ "Platform state is invalid",
+ "Guest state is invalid",
+ "Platform configuration is invalid",
+ "Buffer too small",
+ "Platform is already owned",
+ "Certificate is invalid",
+ "Policy is not allowed",
+ "Guest is not active",
+ "Invalid address",
+ "Bad signature",
+ "Bad measurement",
+ "Asid is already owned",
+ "Invalid ASID",
+ "WBINVD is required",
+ "DF_FLUSH is required",
+ "Guest handle is invalid",
+ "Invalid command",
+ "Guest is active",
+ "Hardware error",
+ "Hardware unsafe",
+ "Feature not supported",
+ "Invalid parameter"
+};
+
+#define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
+
+static int
+sev_ioctl(int fd, int cmd, void *data, int *error)
+{
+ int r;
+ struct kvm_sev_cmd input;
+
+ memset(&input, 0x0, sizeof(input));
+
+ input.id = cmd;
+ input.sev_fd = fd;
+ input.data = (__u64)(unsigned long)data;
+
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
+
+ if (error) {
+ *error = input.error;
+ }
+
+ return r;
+}
+
+static int
+sev_platform_ioctl(int fd, int cmd, void *data, int *error)
+{
+ int r;
+ struct sev_issue_cmd arg;
+
+ arg.cmd = cmd;
+ arg.data = (unsigned long)data;
+ r = ioctl(fd, SEV_ISSUE_CMD, &arg);
+ if (error) {
+ *error = arg.error;
+ }
+
+ return r;
+}
+
+static const char *
+fw_error_to_str(int code)
+{
+ if (code < 0 || code >= SEV_FW_MAX_ERROR) {
+ return "unknown error";
+ }
+
+ return sev_fw_errlist[code];
+}
+
+static bool
+sev_check_state(SevState state)
+{
+ assert(sev_state);
+ return sev_state->state == state ? true : false;
+}
+
+static void
+sev_set_guest_state(SevState new_state)
+{
+ assert(new_state < SEV_STATE__MAX);
+ assert(sev_state);
+
+ trace_kvm_sev_change_state(SevState_str(sev_state->state),
+ SevState_str(new_state));
+ sev_state->state = new_state;
+}
+
+static void
+sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
+{
+ int r;
+ struct kvm_enc_region range;
+
+ range.addr = (__u64)(unsigned long)host;
+ range.size = size;
+
+ trace_kvm_memcrypt_register_region(host, size);
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
+ if (r) {
+ error_report("%s: failed to register region (%p+%#zx) error '%s'",
+ __func__, host, size, strerror(errno));
+ exit(1);
+ }
+}
+
+static void
+sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
+{
+ int r;
+ struct kvm_enc_region range;
+
+ range.addr = (__u64)(unsigned long)host;
+ range.size = size;
+
+ trace_kvm_memcrypt_unregister_region(host, size);
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
+ if (r) {
+ error_report("%s: failed to unregister region (%p+%#zx)",
+ __func__, host, size);
+ }
+}
+
+static struct RAMBlockNotifier sev_ram_notifier = {
+ .ram_block_added = sev_ram_block_added,
+ .ram_block_removed = sev_ram_block_removed,
+};
+
+static void
+qsev_guest_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_guest_get_session_file(Object *obj, Error **errp)
+{
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+ return s->session_file ? g_strdup(s->session_file) : NULL;
+}
+
+static void
+qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
+{
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+ s->session_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
+{
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+ return g_strdup(s->dh_cert_file);
+}
+
+static void
+qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
+{
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
+
+ s->dh_cert_file = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_sev_device(Object *obj, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ return g_strdup(sev->sev_device);
+}
+
+static void
+qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ sev->sev_device = g_strdup(value);
+}
+
+static void
+qsev_guest_class_init(ObjectClass *oc, void *data)
+{
+ object_class_property_add_str(oc, "sev-device",
+ qsev_guest_get_sev_device,
+ qsev_guest_set_sev_device,
+ NULL);
+ object_class_property_set_description(oc, "sev-device",
+ "SEV device to use", NULL);
+ object_class_property_add_str(oc, "dh-cert-file",
+ qsev_guest_get_dh_cert_file,
+ qsev_guest_set_dh_cert_file,
+ NULL);
+ object_class_property_set_description(oc, "dh-cert-file",
+ "guest owners DH certificate (encoded with base64)", NULL);
+ object_class_property_add_str(oc, "session-file",
+ qsev_guest_get_session_file,
+ qsev_guest_set_session_file,
+ NULL);
+ object_class_property_set_description(oc, "session-file",
+ "guest owners session parameters (encoded with base64)", NULL);
+}
+
+static void
+qsev_guest_set_handle(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, name, &value, errp);
+ sev->handle = value;
+}
+
+static void
+qsev_guest_set_policy(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, name, &value, errp);
+ sev->policy = value;
+}
+
+static void
+qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, name, &value, errp);
+ sev->cbitpos = value;
+}
+
+static void
+qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+ uint32_t value;
+
+ visit_type_uint32(v, name, &value, errp);
+ sev->reduced_phys_bits = value;
+}
+
+static void
+qsev_guest_get_policy(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint32_t value;
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ value = sev->policy;
+ visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_handle(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint32_t value;
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ value = sev->handle;
+ visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint32_t value;
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ value = sev->cbitpos;
+ visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint32_t value;
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ value = sev->reduced_phys_bits;
+ visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qsev_guest_init(Object *obj)
+{
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+ sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
+ sev->policy = DEFAULT_GUEST_POLICY;
+ object_property_add(obj, "policy", "uint32", qsev_guest_get_policy,
+ qsev_guest_set_policy, NULL, NULL, NULL);
+ object_property_add(obj, "handle", "uint32", qsev_guest_get_handle,
+ qsev_guest_set_handle, NULL, NULL, NULL);
+ object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos,
+ qsev_guest_set_cbitpos, NULL, NULL, NULL);
+ object_property_add(obj, "reduced-phys-bits", "uint32",
+ qsev_guest_get_reduced_phys_bits,
+ qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL);
+}
+
+/* sev guest info */
+static const TypeInfo qsev_guest_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_QSEV_GUEST_INFO,
+ .instance_size = sizeof(QSevGuestInfo),
+ .instance_finalize = qsev_guest_finalize,
+ .class_size = sizeof(QSevGuestInfoClass),
+ .class_init = qsev_guest_class_init,
+ .instance_init = qsev_guest_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static QSevGuestInfo *
+lookup_sev_guest_info(const char *id)
+{
+ Object *obj;
+ QSevGuestInfo *info;
+
+ obj = object_resolve_path_component(object_get_objects_root(), id);
+ if (!obj) {
+ return NULL;
+ }
+
+ info = (QSevGuestInfo *)
+ object_dynamic_cast(obj, TYPE_QSEV_GUEST_INFO);
+ if (!info) {
+ return NULL;
+ }
+
+ return info;
+}
+
+bool
+sev_enabled(void)
+{
+ return sev_state ? true : false;
+}
+
+uint64_t
+sev_get_me_mask(void)
+{
+ return sev_state ? sev_state->me_mask : ~0;
+}
+
+uint32_t
+sev_get_cbit_position(void)
+{
+ return sev_state ? sev_state->cbitpos : 0;
+}
+
+uint32_t
+sev_get_reduced_phys_bits(void)
+{
+ return sev_state ? sev_state->reduced_phys_bits : 0;
+}
+
+SevInfo *
+sev_get_info(void)
+{
+ SevInfo *info;
+
+ info = g_new0(SevInfo, 1);
+ info->enabled = sev_state ? true : false;
+
+ if (info->enabled) {
+ info->api_major = sev_state->api_major;
+ info->api_minor = sev_state->api_minor;
+ info->build_id = sev_state->build_id;
+ info->policy = sev_state->policy;
+ info->state = sev_state->state;
+ info->handle = sev_state->handle;
+ }
+
+ return info;
+}
+
+static int
+sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
+ size_t *cert_chain_len)
+{
+ guchar *pdh_data, *cert_chain_data;
+ struct sev_user_data_pdh_cert_export export = {};
+ int err, r;
+
+ /* query the certificate length */
+ r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
+ if (r < 0) {
+ if (err != SEV_RET_INVALID_LEN) {
+ error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
+ r, err, fw_error_to_str(err));
+ return 1;
+ }
+ }
+
+ pdh_data = g_new(guchar, export.pdh_cert_len);
+ cert_chain_data = g_new(guchar, export.cert_chain_len);
+ export.pdh_cert_address = (unsigned long)pdh_data;
+ export.cert_chain_address = (unsigned long)cert_chain_data;
+
+ r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
+ if (r < 0) {
+ error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
+ r, err, fw_error_to_str(err));
+ goto e_free;
+ }
+
+ *pdh = pdh_data;
+ *pdh_len = export.pdh_cert_len;
+ *cert_chain = cert_chain_data;
+ *cert_chain_len = export.cert_chain_len;
+ return 0;
+
+e_free:
+ g_free(pdh_data);
+ g_free(cert_chain_data);
+ return 1;
+}
+
+SevCapability *
+sev_get_capabilities(void)
+{
+ SevCapability *cap;
+ guchar *pdh_data, *cert_chain_data;
+ size_t pdh_len = 0, cert_chain_len = 0;
+ uint32_t ebx;
+ int fd;
+
+ fd = open(DEFAULT_SEV_DEVICE, O_RDWR);
+ if (fd < 0) {
+ error_report("%s: Failed to open %s '%s'", __func__,
+ DEFAULT_SEV_DEVICE, strerror(errno));
+ return NULL;
+ }
+
+ if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
+ &cert_chain_data, &cert_chain_len)) {
+ return NULL;
+ }
+
+ cap = g_new0(SevCapability, 1);
+ cap->pdh = g_base64_encode(pdh_data, pdh_len);
+ cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len);
+
+ host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
+ cap->cbitpos = ebx & 0x3f;
+
+ /*
+ * When SEV feature is enabled, we loose one bit in guest physical
+ * addressing.
+ */
+ cap->reduced_phys_bits = 1;
+
+ g_free(pdh_data);
+ g_free(cert_chain_data);
+
+ close(fd);
+ return cap;
+}
+
+static int
+sev_read_file_base64(const char *filename, guchar **data, gsize *len)
+{
+ gsize sz;
+ gchar *base64;
+ GError *error = NULL;
+
+ if (!g_file_get_contents(filename, &base64, &sz, &error)) {
+ error_report("failed to read '%s' (%s)", filename, error->message);
+ return -1;
+ }
+
+ *data = g_base64_decode(base64, len);
+ return 0;
+}
+
+static int
+sev_launch_start(SEVState *s)
+{
+ gsize sz;
+ int ret = 1;
+ int fw_error;
+ QSevGuestInfo *sev = s->sev_info;
+ struct kvm_sev_launch_start *start;
+ guchar *session = NULL, *dh_cert = NULL;
+
+ start = g_new0(struct kvm_sev_launch_start, 1);
+
+ start->handle = object_property_get_int(OBJECT(sev), "handle",
+ &error_abort);
+ start->policy = object_property_get_int(OBJECT(sev), "policy",
+ &error_abort);
+ if (sev->session_file) {
+ if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
+ return 1;
+ }
+ start->session_uaddr = (unsigned long)session;
+ start->session_len = sz;
+ }
+
+ if (sev->dh_cert_file) {
+ if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
+ return 1;
+ }
+ start->dh_uaddr = (unsigned long)dh_cert;
+ start->dh_len = sz;
+ }
+
+ trace_kvm_sev_launch_start(start->policy, session, dh_cert);
+ ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
+ if (ret < 0) {
+ error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
+ return 1;
+ }
+
+ object_property_set_int(OBJECT(sev), start->handle, "handle",
+ &error_abort);
+ sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE);
+ s->handle = start->handle;
+ s->policy = start->policy;
+
+ g_free(start);
+ g_free(session);
+ g_free(dh_cert);
+
+ return 0;
+}
+
+static int
+sev_launch_update_data(uint8_t *addr, uint64_t len)
+{
+ int ret, fw_error;
+ struct kvm_sev_launch_update_data update;
+
+ if (!addr || !len) {
+ return 1;
+ }
+
+ update.uaddr = (__u64)(unsigned long)addr;
+ update.len = len;
+ trace_kvm_sev_launch_update_data(addr, len);
+ ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
+ &update, &fw_error);
+ if (ret) {
+ error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
+ }
+
+ return ret;
+}
+
+static void
+sev_launch_get_measure(Notifier *notifier, void *unused)
+{
+ int ret, error;
+ guchar *data;
+ SEVState *s = sev_state;
+ struct kvm_sev_launch_measure *measurement;
+
+ if (!sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
+ return;
+ }
+
+ measurement = g_new0(struct kvm_sev_launch_measure, 1);
+
+ /* query the measurement blob length */
+ ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE,
+ measurement, &error);
+ if (!measurement->len) {
+ error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
+ __func__, ret, error, fw_error_to_str(errno));
+ goto free_measurement;
+ }
+
+ data = g_new0(guchar, measurement->len);
+ measurement->uaddr = (unsigned long)data;
+
+ /* get the measurement blob */
+ ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE,
+ measurement, &error);
+ if (ret) {
+ error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
+ __func__, ret, error, fw_error_to_str(errno));
+ goto free_data;
+ }
+
+ sev_set_guest_state(SEV_STATE_LAUNCH_SECRET);
+
+ /* encode the measurement value and emit the event */
+ s->measurement = g_base64_encode(data, measurement->len);
+ trace_kvm_sev_launch_measurement(s->measurement);
+
+free_data:
+ g_free(data);
+free_measurement:
+ g_free(measurement);
+}
+
+char *
+sev_get_launch_measurement(void)
+{
+ if (sev_state &&
+ sev_state->state >= SEV_STATE_LAUNCH_SECRET) {
+ return g_strdup(sev_state->measurement);
+ }
+
+ return NULL;
+}
+
+static Notifier sev_machine_done_notify = {
+ .notify = sev_launch_get_measure,
+};
+
+static void
+sev_launch_finish(SEVState *s)
+{
+ int ret, error;
+ Error *local_err = NULL;
+
+ trace_kvm_sev_launch_finish();
+ ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error);
+ if (ret) {
+ error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
+ __func__, ret, error, fw_error_to_str(error));
+ exit(1);
+ }
+
+ sev_set_guest_state(SEV_STATE_RUNNING);
+
+ /* add migration blocker */
+ error_setg(&sev_mig_blocker,
+ "SEV: Migration is not implemented");
+ ret = migrate_add_blocker(sev_mig_blocker, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ error_free(sev_mig_blocker);
+ exit(1);
+ }
+}
+
+static void
+sev_vm_state_change(void *opaque, int running, RunState state)
+{
+ SEVState *s = opaque;
+
+ if (running) {
+ if (!sev_check_state(SEV_STATE_RUNNING)) {
+ sev_launch_finish(s);
+ }
+ }
+}
+
+void *
+sev_guest_init(const char *id)
+{
+ SEVState *s;
+ char *devname;
+ int ret, fw_error;
+ uint32_t ebx;
+ uint32_t host_cbitpos;
+ struct sev_user_data_status status = {};
+
+ s = g_new0(SEVState, 1);
+ s->sev_info = lookup_sev_guest_info(id);
+ if (!s->sev_info) {
+ error_report("%s: '%s' is not a valid '%s' object",
+ __func__, id, TYPE_QSEV_GUEST_INFO);
+ goto err;
+ }
+
+ sev_state = s;
+ s->state = SEV_STATE_UNINIT;
+
+ host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
+ host_cbitpos = ebx & 0x3f;
+
+ s->cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL);
+ if (host_cbitpos != s->cbitpos) {
+ error_report("%s: cbitpos check failed, host '%d' requested '%d'",
+ __func__, host_cbitpos, s->cbitpos);
+ goto err;
+ }
+
+ s->reduced_phys_bits = object_property_get_int(OBJECT(s->sev_info),
+ "reduced-phys-bits", NULL);
+ if (s->reduced_phys_bits < 1) {
+ error_report("%s: reduced_phys_bits check failed, it should be >=1,"
+ "' requested '%d'", __func__, s->reduced_phys_bits);
+ goto err;
+ }
+
+ s->me_mask = ~(1UL << s->cbitpos);
+
+ devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL);
+ s->sev_fd = open(devname, O_RDWR);
+ if (s->sev_fd < 0) {
+ error_report("%s: Failed to open %s '%s'", __func__,
+ devname, strerror(errno));
+ goto err;
+ }
+ g_free(devname);
+
+ ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status,
+ &fw_error);
+ if (ret) {
+ error_report("%s: failed to get platform status ret=%d"
+ "fw_error='%d: %s'", __func__, ret, fw_error,
+ fw_error_to_str(fw_error));
+ goto err;
+ }
+ s->build_id = status.build;
+ s->api_major = status.api_major;
+ s->api_minor = status.api_minor;
+
+ trace_kvm_sev_init();
+ ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error);
+ if (ret) {
+ error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
+ goto err;
+ }
+
+ ret = sev_launch_start(s);
+ if (ret) {
+ error_report("%s: failed to create encryption context", __func__);
+ goto err;
+ }
+
+ ram_block_notifier_add(&sev_ram_notifier);
+ qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
+ qemu_add_vm_change_state_handler(sev_vm_state_change, s);
+
+ return s;
+err:
+ g_free(sev_state);
+ sev_state = NULL;
+ return NULL;
+}
+
+int
+sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
+{
+ assert(handle);
+
+ /* if SEV is in update state then encrypt the data else do nothing */
+ if (sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
+ return sev_launch_update_data(ptr, len);
+ }
+
+ return 0;
+}
+
+static void
+sev_register_types(void)
+{
+ type_register_static(&qsev_guest_info);
+}
+
+type_init(sev_register_types);
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
new file mode 100644
index 0000000000..b8622dfb1e
--- /dev/null
+++ b/target/i386/sev_i386.h
@@ -0,0 +1,88 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016-2018
+ *
+ * Authors:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_SEV_I386_H
+#define QEMU_SEV_I386_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "sysemu/kvm.h"
+#include "sysemu/sev.h"
+#include "qemu/error-report.h"
+#include "qapi/qapi-commands-misc.h"
+
+#define SEV_POLICY_NODBG 0x1
+#define SEV_POLICY_NOKS 0x2
+#define SEV_POLICY_ES 0x4
+#define SEV_POLICY_NOSEND 0x8
+#define SEV_POLICY_DOMAIN 0x10
+#define SEV_POLICY_SEV 0x20
+
+#define TYPE_QSEV_GUEST_INFO "sev-guest"
+#define QSEV_GUEST_INFO(obj) \
+ OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
+
+extern bool sev_enabled(void);
+extern uint64_t sev_get_me_mask(void);
+extern SevInfo *sev_get_info(void);
+extern uint32_t sev_get_cbit_position(void);
+extern uint32_t sev_get_reduced_phys_bits(void);
+extern char *sev_get_launch_measurement(void);
+extern SevCapability *sev_get_capabilities(void);
+
+typedef struct QSevGuestInfo QSevGuestInfo;
+typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+
+/**
+ * QSevGuestInfo:
+ *
+ * The QSevGuestInfo object is used for creating a SEV guest.
+ *
+ * # $QEMU \
+ * -object sev-guest,id=sev0 \
+ * -machine ...,memory-encryption=sev0
+ */
+struct QSevGuestInfo {
+ Object parent_obj;
+
+ char *sev_device;
+ uint32_t policy;
+ uint32_t handle;
+ char *dh_cert_file;
+ char *session_file;
+ uint32_t cbitpos;
+ uint32_t reduced_phys_bits;
+};
+
+struct QSevGuestInfoClass {
+ ObjectClass parent_class;
+};
+
+struct SEVState {
+ QSevGuestInfo *sev_info;
+ uint8_t api_major;
+ uint8_t api_minor;
+ uint8_t build_id;
+ uint32_t policy;
+ uint64_t me_mask;
+ uint32_t cbitpos;
+ uint32_t reduced_phys_bits;
+ uint32_t handle;
+ int sev_fd;
+ SevState state;
+ gchar *measurement;
+};
+
+typedef struct SEVState SEVState;
+
+#endif
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 3153fd4454..6a19a69af5 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -5,3 +5,13 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %"
kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
+
+# target/i386/sev.c
+kvm_sev_init(void) ""
+kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%zu"
+kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%zu"
+kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
+kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
+kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
+kvm_sev_launch_measurement(const char *value) "data %s"
+kvm_sev_launch_finish(void) ""
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index 22445d9ec2..7470c6b754 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -204,6 +204,11 @@ static bool query_is_blacklisted(const char *cmd)
"query-gic-capabilities", /* arm */
/* Success depends on target-specific build configuration: */
"query-pci", /* CONFIG_PCI */
+ /* Success depends on launching SEV guest */
+ "query-sev-launch-measure",
+ /* Success depends on Host or Hypervisor SEV support */
+ "query-sev",
+ "query-sev-capabilities",
NULL
};
int i;