All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD)
@ 2016-09-22 14:51 Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs Brijesh Singh
                   ` (17 more replies)
  0 siblings, 18 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

This RFC series provides support for AMD's new Secure Encrypted 
Virtualization (SEV) feature. This RFC is based KVM RFC [1].

SEV is an extension to the AMD-V architecture which supports running
multiple VMs under the control of a hypervisor. The SEV feature allows
the memory contents of a virtual machine (VM) to be transparently encrypted
with a key unique to the guest VM. The memory controller contains a
high performance encryption engine which can be programmed with multiple
keys for use by a different VMs in the system. The programming and
management of these keys is handled by the AMD Secure Processor firmware
which exposes a commands for these tasks.

SEV is designed to protect guest VMs from a benign but vulnerable
(i.e. not fully malicious) hypervisor. In particular, it reduces the attack
surface of guest VMs and can prevent certain types of VM-escape bugs
(e.g. hypervisor read-anywhere) from being used to steal guest data.

The KVM RFC introduced a new ioctl (KVM_SEV_ISSUE_CMD) which can be
used by qemu to enable SEV for secure guest and assist performing common
hypervisor activities such as a launching, running, snapshooting, migration
and debugging a guests data.


The following links provide additional details:

AMD Memory Encryption whitepaper:
 
http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf

AMD64 Architecture Programmer's Manual:
    http://support.amd.com/TechDocs/24593.pdf
    SME is section 7.10
    SEV is section 15.34

Secure Encrypted Virutualization Key Management:
http://support.amd.com/TechDocs/55766_SEV-KM API_Spec.pdf

KVM Forum slides:
http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf

KVM RFC link:

[1] http://marc.info/?l=kvm&m=147191038624432&w=2

Video of the KVM Forum Talk:
https://www.youtube.com/watch?v=RcvQ1xN55Ew

---

The patches are based on (d75aa43 Update version for v2.7.0-rc4 release)

Changes since v1:
- Added Documentation
- Added security-policy object.
- Drop sev config parsing support and create new objects to get/set SEV
  specific parameters
- Added sev-guest-info object.
- Added sev-launch-info object.
- Added kvm_memory_encrytion_* APIs. The idea behind this was to allow adding
  a non SEV memory encrytion object without modifying interfaces.
- Drop patch to load OS image at fixed location.
- updated LAUNCH_FINISH command structure. Now the structure contains
  just 'measurement' field. Other fields are not used and will also be removed
  from newer SEV firmware API spec.

TODO:
- investigate the possibilty of adding SEV support in UEFI BIOS.
- implement RECEIVE_START, RECEIVE_UPDATE and RECEIVE_FINISH commands
- implement SEND_START, SEND_UPDATE and SEND_FINISH commands
- implement  SEV guest migration and snapshotting support
- virtio support in SEV guest

Brijesh Singh (16):
      memattrs: add debug attrs
      exec: add guest RAM read and write ops
      exec: add debug version of physical memory read and write apis
      monitor: use debug version of memory access apis
      core: add new security-policy object
      sev: add Secure Encrypted Virtulization (SEV) support
      hmp: display memory encryption support in 'info kvm'
      core: loader: create memory encryption context before copying data
      sev: add LAUNCH_START command
      sev: add LAUNCH_UPDATE command
      sev: add LAUNCH_FINISH command
      sev: add DEBUG_DECRYPT command
      sev: add DEBUG_ENCRYPT command
      i386: set memory encryption ops for PC.BIOS and PC.RAM regions
      target-i386: add cpuid Fn8000_001f
      i386: clear C-bit in SEV guest page table walk


 Makefile.target                  |    2 
 cpus.c                           |    2 
 disas.c                          |    2 
 docs/amd-memory-encryption.txt   |  260 ++++++++
 exec.c                           |   96 +++
 hmp.c                            |    2 
 hw/core/Makefile.objs            |    1 
 hw/core/loader.c                 |   13 
 hw/core/machine.c                |   22 +
 hw/core/security-policy.c        |  166 +++++
 hw/i386/pc.c                     |    7 
 hw/i386/pc_sysfw.c               |    4 
 include/exec/cpu-common.h        |   17 +
 include/exec/memattrs.h          |    4 
 include/exec/memory.h            |   25 +
 include/hw/boards.h              |    1 
 include/sysemu/kvm.h             |    6 
 include/sysemu/security-policy.h |   75 ++
 include/sysemu/sev.h             |  208 +++++++
 kvm-all.c                        |   71 ++
 monitor.c                        |    2 
 qapi-schema.json                 |    7 
 qemu-options.hx                  |  127 ++++
 qmp.c                            |    1 
 sev.c                            | 1176 ++++++++++++++++++++++++++++++++++++++
 target-i386/cpu.c                |   10 
 target-i386/helper.c             |   37 +
 target-i386/monitor.c            |   51 +-
 28 files changed, 2356 insertions(+), 39 deletions(-)
 create mode 100644 docs/amd-memory-encryption.txt
 create mode 100644 hw/core/security-policy.c
 create mode 100644 include/sysemu/security-policy.h
 create mode 100644 include/sysemu/sev.h
 create mode 100644 sev.c

-- 

Brijesh Singh

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops Brijesh Singh
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

Add a new memory debug attribute, this attribute should be set when
memory read or write access is performed for debugging purposes.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/exec/memattrs.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index e601061..b802073 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
     unsigned int user:1;
     /* Requester ID (for MSI for example) */
     unsigned int requester_id:16;
+    /* Memory access for debug purposes */
+    unsigned int debug:1;
 } MemTxAttrs;
 
 /* Bus masters which don't specify any attributes will get this,
@@ -46,4 +48,6 @@ typedef struct MemTxAttrs {
  */
 #define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = 1 })
 
+/* Access the guest memory for debug purposes */
+#define MEMTXATTRS_DEBUG ((MemTxAttrs) { .debug = 1 })
 #endif

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 15:22   ` Paolo Bonzini
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis Brijesh Singh
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

In current implementation, read and write of the guest RAM is
performed using using memcpy(). This patch adds support to register
a callback which can override the memcpy() with something else.

This feature will be used in Secure Encrypted Virtualization (SEV)
guests in which read and write of guest memory should be performed
using the SEV commands.

a typical usage:

mem_read(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
mem_write(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);

MemoryRegionRAMReadWriteOps ops;
ops.read = mem_read;
ops.write = mem_write;

memory_region_init_ram(mem, NULL, "memory", size, NULL);
memory_region_set_ram_ops(mem, ops);

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 exec.c                    |   57 ++++++++++++++++++++++++++++++++-------------
 include/exec/cpu-common.h |    2 +-
 include/exec/memory.h     |   25 ++++++++++++++++++++
 3 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/exec.c b/exec.c
index 8ffde75..0989933 100644
--- a/exec.c
+++ b/exec.c
@@ -2715,11 +2715,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
 
 enum write_rom_type {
     WRITE_DATA,
+    READ_DATA,
     FLUSH_CACHE,
 };
 
-static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
-    hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
+static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
+    hwaddr addr, uint8_t *buf, int len, MemTxAttrs attrs,
+    enum write_rom_type type)
 {
     hwaddr l;
     uint8_t *ptr;
@@ -2733,13 +2735,33 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
 
         if (!(memory_region_is_ram(mr) ||
               memory_region_is_romd(mr))) {
-            l = memory_access_size(mr, l, addr1);
+            /* Pass MMIO down to address address_space_rw */
+            switch (type) {
+            case READ_DATA:
+            case WRITE_DATA:
+                address_space_rw(as, addr, attrs, buf, l,
+                                 type == WRITE_DATA);
+                break;
+            case FLUSH_CACHE:
+                break;
+            }
         } else {
             /* ROM/RAM case */
             ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
             switch (type) {
+            case READ_DATA:
+                if (mr->ram_ops) {
+                    mr->ram_ops->read(buf, ptr, l, attrs);
+                } else {
+                    memcpy(buf, ptr, l);
+                }
+                break;
             case WRITE_DATA:
-                memcpy(ptr, buf, l);
+                if (mr->ram_ops) {
+                    mr->ram_ops->write(ptr, buf, l, attrs);
+                } else {
+                    memcpy(ptr, buf, l);
+                }
                 invalidate_and_set_dirty(mr, addr1, l);
                 break;
             case FLUSH_CACHE:
@@ -2756,9 +2778,10 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
 
 /* used for ROM loading : can write in RAM and ROM */
 void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
-                                   const uint8_t *buf, int len)
+                                   uint8_t *buf, int len)
 {
-    cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
+    cpu_physical_memory_rw_debug_internal(as, addr, buf, len,
+            MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
 }
 
 void cpu_flush_icache_range(hwaddr start, int len)
@@ -2773,8 +2796,10 @@ void cpu_flush_icache_range(hwaddr start, int len)
         return;
     }
 
-    cpu_physical_memory_write_rom_internal(&address_space_memory,
-                                           start, NULL, len, FLUSH_CACHE);
+    cpu_physical_memory_rw_debug_internal(&address_space_memory,
+                                           start, NULL, len,
+                                           MEMTXATTRS_UNSPECIFIED,
+                                           FLUSH_CACHE);
 }
 
 typedef struct {
@@ -3597,6 +3622,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
     int l;
     hwaddr phys_addr;
     target_ulong page;
+    int type = is_write ? WRITE_DATA : READ_DATA;
 
     while (len > 0) {
         int asidx;
@@ -3605,6 +3631,10 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
         page = addr & TARGET_PAGE_MASK;
         phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs);
         asidx = cpu_asidx_from_attrs(cpu, attrs);
+
+        /* set debug attribute */
+        attrs.debug = 1;
+
         /* if no physical page mapped, return an error */
         if (phys_addr == -1)
             return -1;
@@ -3612,14 +3642,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
         if (l > len)
             l = len;
         phys_addr += (addr & ~TARGET_PAGE_MASK);
-        if (is_write) {
-            cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as,
-                                          phys_addr, buf, l);
-        } else {
-            address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
-                             MEMTXATTRS_UNSPECIFIED,
-                             buf, l, 0);
-        }
+        cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
+                                               phys_addr, buf, l, attrs,
+                                               type);
         len -= l;
         buf += l;
         addr += l;
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 952bcfe..520dae0 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -104,7 +104,7 @@ void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
 void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
 
 void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
-                                   const uint8_t *buf, int len);
+                                   uint8_t *buf, int len);
 void cpu_flush_icache_range(hwaddr start, int len);
 
 extern struct MemoryRegion io_mem_rom;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3e4d416..80af3b0 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -146,6 +146,18 @@ struct MemoryRegionOps {
     const MemoryRegionMmio old_mmio;
 };
 
+/* Memory Region RAM callback */
+typedef struct MemoryRegionRAMReadWriteOps MemoryRegionRAMReadWriteOps;
+
+struct MemoryRegionRAMReadWriteOps {
+    /* Write data into guest memory */
+    int (*write) (uint8_t *dest, const uint8_t *src,
+                  uint32_t len, MemTxAttrs attrs);
+    /* Read data from guest memory */
+    int (*read) (uint8_t *dest, const uint8_t *src,
+                 uint32_t len, MemTxAttrs attrs);
+};
+
 typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps;
 
 struct MemoryRegionIOMMUOps {
@@ -179,6 +191,7 @@ struct MemoryRegion {
     RAMBlock *ram_block;
     Object *owner;
     const MemoryRegionIOMMUOps *iommu_ops;
+    const MemoryRegionRAMReadWriteOps *ram_ops;
 
     const MemoryRegionOps *ops;
     void *opaque;
@@ -506,6 +519,18 @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
 }
 
 /**
+ * memory_region_set_ram_ops: Set the Read/Write ops for accessing the RAM
+ *
+ * @mr: the #MemoryRegion to be initialized
+ * @ops: a function that will be used to read/write @target region
+ */
+static inline void memory_region_set_ram_ops(MemoryRegion *mr,
+                               const MemoryRegionRAMReadWriteOps *ops)
+{
+    mr->ram_ops = ops;
+}
+
+/**
  * memory_region_init_iommu: Initialize a memory region that translates
  * addresses
  *

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 15:21   ` Paolo Bonzini
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis Brijesh Singh
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The patch adds the following new APIs:
- cpu_physical_memory_read_debug
- cpu_physical_memory_write_debug
- cpu_physical_memory_rw_debug
- ldl_phys_debug
- ldq_phys_debug

The idea behind this patch is that if all the qemu monitor memory dumps
and gdbserver accesses are done through these common APIs then in future
we can define some kind of global debug policy to control debug behavior.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 exec.c                    |   32 ++++++++++++++++++++++++++++++++
 include/exec/cpu-common.h |   15 +++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/exec.c b/exec.c
index 0989933..9d0128e 100644
--- a/exec.c
+++ b/exec.c
@@ -3105,6 +3105,30 @@ uint32_t ldl_phys(AddressSpace *as, hwaddr addr)
     return address_space_ldl(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
 }
 
+uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr)
+{
+    MemTxAttrs attrs = MEMTXATTRS_DEBUG;
+    int asidx = cpu_asidx_from_attrs(cpu, attrs);
+    uint32_t val;
+
+    cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
+                                          addr, (void *) &val,
+                                          4, attrs, READ_DATA);
+    return tswap32(val);
+}
+
+uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr)
+{
+    MemTxAttrs attrs = MEMTXATTRS_DEBUG;
+    int asidx = cpu_asidx_from_attrs(cpu, attrs);
+    uint64_t val;
+
+    cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
+                                          addr, (void *) &val,
+                                          8, attrs, READ_DATA);
+    return val;
+}
+
 uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr)
 {
     return address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
@@ -3615,6 +3639,14 @@ void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val)
     address_space_stq_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
 }
 
+void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
+                                  int len, int is_write)
+{
+    cpu_physical_memory_rw_debug_internal(&address_space_memory, addr,
+                                          buf, len, MEMTXATTRS_DEBUG,
+                                          is_write ? WRITE_DATA : READ_DATA);
+}
+
 /* virtual memory access for debug (includes writing to ROM) */
 int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
                         uint8_t *buf, int len, int is_write)
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 520dae0..90598d4 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -61,6 +61,8 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
 
 void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
                             int len, int is_write);
+void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
+                                  int len, int is_write);
 static inline void cpu_physical_memory_read(hwaddr addr,
                                             void *buf, int len)
 {
@@ -71,6 +73,19 @@ static inline void cpu_physical_memory_write(hwaddr addr,
 {
     cpu_physical_memory_rw(addr, (void *)buf, len, 1);
 }
+static inline void cpu_physical_memory_read_debug(hwaddr addr,
+                                                  void *buf, int len)
+{
+    cpu_physical_memory_rw_debug(addr, buf, len, 0);
+}
+static inline void cpu_physical_memory_write_debug(hwaddr addr,
+                                                   const void *buf, int len)
+{
+    cpu_physical_memory_rw_debug(addr, (void *)buf, len, 1);
+}
+uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr);
+uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr);
+
 void *cpu_physical_memory_map(hwaddr addr,
                               hwaddr *plen,
                               int is_write);

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (2 preceding siblings ...)
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 15:18   ` Paolo Bonzini
  2016-09-22 19:24   ` Michael S. Tsirkin
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 05/16] core: add new security-policy object Brijesh Singh
                   ` (13 subsequent siblings)
  17 siblings, 2 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

updates hmp monitor to use debug version of memory access apis when
accessing the guest memory.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 cpus.c                |    2 +-
 disas.c               |    2 +-
 monitor.c             |    2 +-
 target-i386/helper.c  |   14 +++++++-------
 target-i386/monitor.c |   18 ++++++++++--------
 5 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/cpus.c b/cpus.c
index 84c3520..48dc4d1 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1725,7 +1725,7 @@ void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
         l = sizeof(buf);
         if (l > size)
             l = size;
-        cpu_physical_memory_read(addr, buf, l);
+        cpu_physical_memory_read_debug(addr, buf, l);
         if (fwrite(buf, 1, l, f) != l) {
             error_setg(errp, QERR_IO_ERROR);
             goto exit;
diff --git a/disas.c b/disas.c
index 05a7a12..382cc2c 100644
--- a/disas.c
+++ b/disas.c
@@ -356,7 +356,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
     CPUDebug *s = container_of(info, CPUDebug, info);
 
     if (monitor_disas_is_physical) {
-        cpu_physical_memory_read(memaddr, myaddr, length);
+        cpu_physical_memory_read_debug(memaddr, myaddr, length);
     } else {
         cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
     }
diff --git a/monitor.c b/monitor.c
index 5c00373..4773ee1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1299,7 +1299,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
         if (l > line_size)
             l = line_size;
         if (is_physical) {
-            cpu_physical_memory_read(addr, buf, l);
+            cpu_physical_memory_read_debug(addr, buf, l);
         } else {
             if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) {
                 monitor_printf(mon, " Cannot access memory\n");
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 1c250b8..88fa4fa 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1034,13 +1034,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             }
             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pml4e = x86_ldq_phys(cs, pml4e_addr);
+            pml4e = ldq_phys_debug(cs, pml4e_addr);
             if (!(pml4e & PG_PRESENT_MASK)) {
                 return -1;
             }
             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
                          (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
-            pdpe = x86_ldq_phys(cs, pdpe_addr);
+            pdpe = ldq_phys_debug(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 return -1;
             }
@@ -1055,14 +1055,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         {
             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                 env->a20_mask;
-            pdpe = x86_ldq_phys(cs, pdpe_addr);
+            pdpe = ldq_phys_debug(cs, pdpe_addr);
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
         }
 
         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
                     (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
-        pde = x86_ldq_phys(cs, pde_addr);
+        pde = ldq_phys_debug(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK)) {
             return -1;
         }
@@ -1075,7 +1075,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pte_addr = ((pde & PG_ADDRESS_MASK) +
                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
             page_size = 4096;
-            pte = x86_ldq_phys(cs, pte_addr);
+            pte = ldq_phys_debug(cs, pte_addr);
         }
         if (!(pte & PG_PRESENT_MASK)) {
             return -1;
@@ -1085,7 +1085,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
         /* page directory entry */
         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
-        pde = x86_ldl_phys(cs, pde_addr);
+        pde = ldl_phys_debug(cs, pde_addr);
         if (!(pde & PG_PRESENT_MASK))
             return -1;
         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
@@ -1094,7 +1094,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         } else {
             /* page directory entry */
             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
-            pte = x86_ldl_phys(cs, pte_addr);
+            pte = ldl_phys_debug(cs, pte_addr);
             if (!(pte & PG_PRESENT_MASK)) {
                 return -1;
             }
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index fccfe40..47d3c2d 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -130,12 +130,12 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
 
     pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
     for (l1 = 0; l1 < 512; l1++) {
-        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
+        cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
         pml4e = le64_to_cpu(pml4e);
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
+                cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
                 pdpe = le64_to_cpu(pdpe);
                 if (pdpe & PG_PRESENT_MASK) {
                     if (pdpe & PG_PSE_MASK) {
@@ -145,7 +145,8 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
+                            cpu_physical_memory_read_debug(pd_addr + l3 * 8,
+                                    &pde, 8);
                             pde = le64_to_cpu(pde);
                             if (pde & PG_PRESENT_MASK) {
                                 if (pde & PG_PSE_MASK) {
@@ -156,7 +157,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
                                 } else {
                                     pt_addr = pde & 0x3fffffffff000ULL;
                                     for (l4 = 0; l4 < 512; l4++) {
-                                        cpu_physical_memory_read(pt_addr
+                                        cpu_physical_memory_read_debug(pt_addr
                                                                  + l4 * 8,
                                                                  &pte, 8);
                                         pte = le64_to_cpu(pte);
@@ -335,13 +336,13 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 512; l1++) {
-        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
+        cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
         pml4e = le64_to_cpu(pml4e);
         end = l1 << 39;
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
+                cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
                 pdpe = le64_to_cpu(pdpe);
                 end = (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -353,7 +354,8 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
+                            cpu_physical_memory_read_debug(pd_addr + l3 * 8,
+                                    &pde, 8);
                             pde = le64_to_cpu(pde);
                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
                             if (pde & PG_PRESENT_MASK) {
@@ -365,7 +367,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
                                 } else {
                                     pt_addr = pde & 0x3fffffffff000ULL;
                                     for (l4 = 0; l4 < 512; l4++) {
-                                        cpu_physical_memory_read(pt_addr
+                                        cpu_physical_memory_read_debug(pt_addr
                                                                  + l4 * 8,
                                                                  &pte, 8);
                                         pte = le64_to_cpu(pte);

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 05/16] core: add new security-policy object
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (3 preceding siblings ...)
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The object can be used to define global security policy for the guest.

object provides two properties:

- debug: can be used to disable the guest memory access from hypervisor.

  e.g if guest owner does not want qemu monitor to debug or dump
  guest memory then it can do so using the below command.

  # $QEMU \
    -object security-policy,debug=false,id=mypolicy \
    -machine ...,security-policy=mypolicy

- memory-encryption: if guest supports memory encryption then property
  should be set to memory encryption object id.

   e.g to launch a encrypted guest

   # $QEMU \
     -object sev-guest,launch-id=unencrypted,id=sev-guest \
     -object security-policy,id=memory-encryption=sev-guest,id=mypolicy \
     -machine ...,security-policy=mypolicy

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 exec.c                           |    7 ++
 hw/core/Makefile.objs            |    1 
 hw/core/machine.c                |   22 +++++
 hw/core/security-policy.c        |  166 ++++++++++++++++++++++++++++++++++++++
 include/hw/boards.h              |    1 
 include/sysemu/security-policy.h |   75 +++++++++++++++++
 qemu-options.hx                  |   21 +++++
 7 files changed, 293 insertions(+)
 create mode 100644 hw/core/security-policy.c
 create mode 100644 include/sysemu/security-policy.h

diff --git a/exec.c b/exec.c
index 9d0128e..2aad84a 100644
--- a/exec.c
+++ b/exec.c
@@ -42,6 +42,7 @@
 #include "exec/memory.h"
 #include "exec/ioport.h"
 #include "sysemu/dma.h"
+#include "sysemu/security-policy.h"
 #include "exec/address-spaces.h"
 #include "sysemu/xen-mapcache.h"
 #include "trace.h"
@@ -2728,6 +2729,12 @@ static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
     hwaddr addr1;
     MemoryRegion *mr;
 
+    if (attrs.debug &&
+        !security_policy_debug_allowed(current_machine->security_policy)) {
+        fprintf(stderr, "WARNING: debug is disabled\n");
+        return;
+    }
+
     rcu_read_lock();
     while (len > 0) {
         l = len;
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index cfd4840..f230b74 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -16,4 +16,5 @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
+common-obj-$(CONFIG_SOFTMMU) += security-policy.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
diff --git a/hw/core/machine.c b/hw/core/machine.c
index e5a456f..a63d1c9 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -332,6 +332,22 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
     return ms->enforce_config_section;
 }
 
+static char *machine_get_security_policy(Object *obj, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+
+    return g_strdup(ms->security_policy);
+}
+
+static void machine_set_security_policy(Object *obj,
+                                        const char *value, Error **errp)
+{
+    MachineState *ms = MACHINE(obj);
+
+    g_free(ms->security_policy);
+    ms->security_policy = g_strdup(value);
+}
+
 static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
     error_report("Option '-device %s' cannot be handled by this machine",
@@ -494,6 +510,12 @@ static void machine_initfn(Object *obj)
     object_property_set_description(obj, "enforce-config-section",
                                     "Set on to enforce configuration section migration",
                                     NULL);
+    object_property_add_str(obj, "security-policy",
+                            machine_get_security_policy,
+                            machine_set_security_policy, NULL);
+    object_property_set_description(obj, "security-policy",
+                                    "Set the security policy for the machine",
+                                    NULL);
 
     /* Register notifier when init is done for sysbus sanity checks */
     ms->sysbus_notifier.notify = machine_init_notify;
diff --git a/hw/core/security-policy.c b/hw/core/security-policy.c
new file mode 100644
index 0000000..92689ff
--- /dev/null
+++ b/hw/core/security-policy.c
@@ -0,0 +1,166 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ *      Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+#include "trace.h"
+
+#include "sysemu/security-policy.h"
+
+static SecurityPolicy *
+find_security_policy_obj(const char *name)
+{
+    Object *obj;
+    SecurityPolicy *policy;
+
+    if (!name) {
+        return NULL;
+    }
+
+    obj = object_resolve_path_component(
+        object_get_objects_root(), name);
+    if (!obj) {
+        return NULL;
+    }
+
+    policy = (SecurityPolicy *)
+        object_dynamic_cast(obj,
+                            TYPE_SECURITY_POLICY);
+    if (!policy) {
+        return NULL;
+    }
+
+    return policy;
+}
+
+bool
+security_policy_debug_allowed(const char *secure_policy_id)
+{
+    SecurityPolicy *policy = find_security_policy_obj(secure_policy_id);
+
+    /* if id is not a valid security policy then we return true */
+    return policy ? policy->debug : true;
+}
+
+char *
+security_policy_get_memory_encryption_id(const char *secure_policy_id)
+{
+    SecurityPolicy *policy = find_security_policy_obj(secure_policy_id);
+
+    return policy ? g_strdup(policy->memory_encryption) : NULL;
+}
+
+static bool
+security_policy_prop_get_debug(Object *obj,
+                               Error **errp G_GNUC_UNUSED)
+{
+    SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+    return policy->debug;
+}
+
+
+static void
+security_policy_prop_set_debug(Object *obj,
+                               bool value,
+                               Error **errp G_GNUC_UNUSED)
+{
+    SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+    policy->debug = value;
+}
+
+static char *
+sev_launch_get_memory_encryption(Object *obj, Error **errp)
+{
+    SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+    return g_strdup(policy->memory_encryption);
+}
+
+static void
+sev_launch_set_memory_encryption(Object *obj, const char *value,
+                                 Error **errp)
+{
+    SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+    policy->memory_encryption = g_strdup(value);
+}
+
+static void
+security_policy_init(Object *obj)
+{
+    SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+    policy->debug = true;
+}
+
+static void
+security_policy_finalize(Object *obj)
+{
+}
+
+static void
+security_policy_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_bool(oc, "debug",
+                                   security_policy_prop_get_debug,
+                                   security_policy_prop_set_debug,
+                                   NULL);
+    object_class_property_set_description(oc, "debug",
+            "Set on/off if debugging is allowed on this guest (default on)",
+            NULL);
+    object_class_property_add_str(oc, "memory-encryption",
+                                  sev_launch_get_memory_encryption,
+                                  sev_launch_set_memory_encryption,
+                                  NULL);
+    object_class_property_set_description(oc, "memory-encryption",
+            "Set memory encryption object id (if supported by hardware)",
+            NULL);
+}
+
+static const TypeInfo security_policy_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_SECURITY_POLICY,
+    .instance_size = sizeof(SecurityPolicy),
+    .instance_init = security_policy_init,
+    .instance_finalize = security_policy_finalize,
+    .class_size = sizeof(SecurityPolicyClass),
+    .class_init = security_policy_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+
+static void
+security_policy_register_types(void)
+{
+    type_register_static(&security_policy_info);
+}
+
+
+type_init(security_policy_register_types);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3e69eca..18ca525 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -143,6 +143,7 @@ struct MachineState {
     /*< public >*/
 
     char *accel;
+    char *security_policy;
     bool kernel_irqchip_allowed;
     bool kernel_irqchip_required;
     bool kernel_irqchip_split;
diff --git a/include/sysemu/security-policy.h b/include/sysemu/security-policy.h
new file mode 100644
index 0000000..6d3789d
--- /dev/null
+++ b/include/sysemu/security-policy.h
@@ -0,0 +1,75 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ *      Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SECURITY_POLICY_H
+#define SECURITY_POLICY_H
+
+#include "qom/object.h"
+
+#define TYPE_SECURITY_POLICY "security-policy"
+#define SECURITY_POLICY(obj)                  \
+    OBJECT_CHECK(SecurityPolicy, (obj), TYPE_SECURITY_POLICY)
+
+typedef struct SecurityPolicy SecurityPolicy;
+typedef struct SecurityPolicyClass SecurityPolicyClass;
+
+/**
+ * SecurityPolicy:
+ *
+ * The SecurityPolicy object provides method to define
+ * various security releated policies for guest machine.
+ *
+ * e.g
+ * When launching QEMU, user can create a security policy
+ * to disallow memory dump and debug of guest
+ *
+ *  # $QEMU \
+ *      -object security-policy,id=mypolicy,debug=off \
+ *      -machine ...,security-policy=mypolicy
+ *
+ * If hardware supports memory encryption then user can set
+ * encryption policy of guest
+ *
+ * # $QEMU \
+ *    -object encrypt-policy,key=xxx,flags=xxxx,id=encrypt \
+ *    -object security-policy,debug=off,memory-encryption=encrypt,id=mypolicy \
+ *    -machine ...,security-policy=mypolicy
+ *
+ */
+
+struct SecurityPolicy {
+    Object parent_obj;
+
+    bool debug;
+    char *memory_encryption;
+};
+
+
+struct SecurityPolicyClass {
+    ObjectClass parent_class;
+};
+
+bool security_policy_debug_allowed(const char *name);
+char *security_policy_get_memory_encryption_id(const char *name);
+
+#endif /* SECURITY_POLICY_H */
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8..b90d6da 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3964,6 +3964,27 @@ contents of @code{iv.b64} to the second secret
          data=$SECRET,iv=$(<iv.b64)
 @end example
 
+@item -object security-policy,id=@var{id}[,debug=@var{bool}][,memory-encryption=@var{string}]
+
+Create a security policy object, which can be used to define guest security.
+The id parameter is a unique ID that will be used to reference this object when
+security-policy is applied via -machine argument.
+
+The 'debug' parameter can be defined to tell whether the debugging or memory
+dump is allowed through qemu monitor console.
+
+e.g to disable the guest memory dump
+@example
+ # $QEMU \
+     -object security-policy,id=secure0,debug=off \
+     -machine ...,security-policy=secure0
+@end example
+
+if hardware support guest memory encrytion, then 'memory-encryption' parameter
+can be set to the unquie ID of memory encryption object.
+
+On AMD processor, memory encryption is supported via 'sev-guest-info' object.
+
 @end table
 
 ETEXI

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (4 preceding siblings ...)
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 05/16] core: add new security-policy object Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 15:12   ` Paolo Bonzini
  2016-09-22 19:51   ` Michael S. Tsirkin
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm' Brijesh Singh
                   ` (11 subsequent siblings)
  17 siblings, 2 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

This patch adds the initial support required to integrate Secure
Encrypted Virtualization (SEV) feature. SEV is an extension to the
existing AMD-V technology found on AMD processors. The SEV feature
allows the memory contents of a virtual machine to be transparently
encrypted with a key unique to the guest VM.

In QEMU command line, SEV can be enabled via memory-encryption property
defined in security-policy object.

The patch adds the following new objects to pass various SEV specific
parameters required to launch and migrate the SEV guest.

- sev-launch-info: provides the properties to set/get parameters required
  to launch unencrypted SEV guest.

  In this mode the OS images (kernel, initrd and  bios) provides by guest
  owner are unencrypted. The SEV guest boot process would encrypt the
  images using the guest owner's key.

  to launch unencrypted SEV guest:
 # $QEMU \
    -object sev-launch-info,id=launch0,flags.ks=off \
    -object sev-guest-info,id,sev0,launch=launch0 \
    -object security-policy,id=secure0,memory-encryption=sev0 \
    -machine ....,security-policy=secure0

- sev-receive-info: provides the properties to set/get parameters required
  to launch encrypted SEV guest.

  In this mode the boot images received from the guest owner are
  pre-encrypted with owners transport keys. The SEV guest boot process
  would re-encrypt the images using guest owner's key.

  to launch encrypted SEV guest:

 # $QEMU \
    -object sev-receive-info,id=launch0,flags.ks=off \
    -object sev-guest-info,id=sev0,launch=launch0 \
    -object security-policy,id=secure0,memory-encryption=sev0 \
    -machine ....,security-policy=secure0

- sev-policy-info: provides properties to get/set SEV specific policy
  parameters required by SEV launch and migrate objects.

  e.g to disable key share during encrypted launch.
  # $QEMU \
    -object sev-policy-info,id=policy0,ks=off \
    -object sev-launch-info,id=sev0,policy=policy0 \
    .....

   sev-policy should be provided by the guest owner.

- sev-guest-info: provides properties to set SEV guest launch object id
  used during guest launch.

  to use encrypted guest launch
  # $QEMU \
     -object sev-receive-info,id=launch0 \
     -object sev-send-info,id=send0 \
     -object sev-guest-info,id=sev0,launch=launch0,send=send0 \
     .....


Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 Makefile.target                |    2 
 docs/amd-memory-encryption.txt |  260 ++++++++++
 include/sysemu/kvm.h           |    6 
 include/sysemu/sev.h           |  208 ++++++++
 kvm-all.c                      |   71 +++
 qemu-options.hx                |  106 ++++
 sev.c                          | 1074 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 1725 insertions(+), 2 deletions(-)
 create mode 100644 docs/amd-memory-encryption.txt
 create mode 100644 include/sysemu/sev.h
 create mode 100644 sev.c

diff --git a/Makefile.target b/Makefile.target
index a440bcb..74ad204 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -136,7 +136,7 @@ ifdef CONFIG_SOFTMMU
 obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
 obj-y += qtest.o bootdevice.o
 obj-y += hw/
-obj-$(CONFIG_KVM) += kvm-all.o
+obj-$(CONFIG_KVM) += kvm-all.o sev.o
 obj-y += memory.o cputlb.o
 obj-y += memory_mapping.o
 obj-y += dump.o
diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
new file mode 100644
index 0000000..ab2fdfb
--- /dev/null
+++ b/docs/amd-memory-encryption.txt
@@ -0,0 +1,260 @@
+Secure Encrypted Virtalization (SEV) is a feature found on AMD processors.
+
+SEV feature allows the memory contents of a virtual machine (VM) to be
+transparently encrypted with a key unique to the guest VM. The memory
+controller contains a high performance encryption engine which can be
+programmed with multiple keys for used by different VMs in the system.
+The programming and management of these keys is handled by the AMD Platform
+Secure Processor (PSP) firmware which exposes commands for these tasks. The
+SEV commands can be send via KVM_SEV_ISSUE_CMD ioctl.
+
+SEV is capable of supporting both light-weight virtual containers as well as
+conventional VM within an enterprise cloud environment. In either case,
+there are two parties concerned in the deloplyment of SEV guest: the guest
+owner and the platform owner. For example, in a cloud envrionment, the
+platform owner would be cloud vendor and the guest owner would be the user
+that wishes to run their workload in the cloud.
+
+Guest owners wish to protect the confidentiality of the data running within
+their guests. While they trust the platform owner to provide the infrastrcuture
+to run their guest, they benefit from reducing their risk exposure to
+vulnerablities within that infrastruture. The SEV feature encrypts the content
+of the memory of the guest and provides additional assurance that it was
+encrypted properly. The encryption of memory places an additional burden
+on attackers within the operational envrionment who may have already obtained
+some illicit access to the guest's memory through a vulnerability in the
+hypervisor or other supporting enterprise softwares.
+
+Platform owners wish to provide such protection to guest owners, but also must
+manage the computing resources efficiently and effectively. Resource allocation
+need to be fluid and their customers data must be safely backed up in case
+of failure. The SEV feature has been developed to be sensitive to this
+requirement; it integrates into the conventional guest life cycle surrounding
+guest launching, migration, and snapshotting.
+
+The following links provide additional detail:
+
+AMD Memory Encryption whitepaper:
+   http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryptio \
+n_Whitepaper_v7-Public.pdf
+
+Secure Encrypted Virutualization Key Management:
+http://support.amd.com/TechDocs/55766_SEV-KM API_Spec.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
+
+1. API description
+-----------------
+
+SEV provides the following command via KVM_SEV_ISSUE_CMD ioctl to launch,
+migrate and snapshot a SEV-enabled guest.
+
+1.0 LAUNCH_START (KVM_SEV_LAUNCH_START)
+
+The command is used to prepare a guest for the transition into SEV-enabled
+mode.
+
+Parameters: struct kvm_sev_launch_start
+Returns: 0 on success; -1 on error.
+
+/* for LAUNCH_START */
+struct kvm_sev_launch_start {
+    /* If KS is set; share key with guest reference by this handle */
+    u32 handle;
+
+    /* Bit 0 (KS) key sharing is enabled */
+    u32 flags;
+
+    /* Guest launch policy (see 1.5 for details)
+    u32 policy;
+
+    /* The Qx and Qy parameter of the owner's ECDH public key */
+    u8 dh_pub_qx[32], dh_pub_qy[32];
+
+    /* A nonce generated by the guest owner */
+    u8 nonce[16];
+}
+
+The firmware creates a new launch context and generate a new VM Encryption Key
+(VEK) - a 128-bit AES-128 key used to encrypt the memory of the guest. The key
+is loaded into memory controller by the firmware.
+
+1.1 LAUNCH_UPDATE (KVM_SEV_LAUNCH_UPDATE)
+
+The command is used to encrypt the guest memory region specified using the VEK
+loaded during LAUNCH_START.
+
+Parameters: struct kvm_sev_launch_update
+Returns: 0 on success; -1 on error
+
+/* for LAUNCH_UPDATE */
+struct kvm_sev_launch_update {
+    /* host virtual address to encrypt */
+    u64 address;
+
+    /* length of memory region to encrypt */
+    u32 len;
+}
+
+The firmware will perform the inline encryption of memory region and launch
+measurement will be updated with the contents of the memor region.
+
+1.2 LAUNCH_FINISH (KVM_SEV_LAUNCH_FINISH)
+
+The command is used to finalize the SEV guest launch process and get the
+measurement of encrypted contents.
+
+Parameters: struct kvm_sev_launch_update
+Returns: 0 on success; -1 on error
+
+/* for LAUNCH_FINISH */
+struct kvm_sev_launch_finish {
+    /* contains measurement of memory encrypted via LAUNCH_UPDATE */
+    u8 measurement[32];
+}
+
+After hypervisor has finished encrypting the guest's memory (via LAUNCH_UPDATE),
+the hypervisor concludes the launch operation. The measurement value returned
+from the LAUNCH_FINISH command can be handed to the guest owner to verify that
+guest is launched successfully.
+
+1.3 GUEST_STATUS (KVM_SEV_GUEST_STATUS)
+
+The command returns the current SEV guest status.
+
+Parameters: struct kvm_sev_guest_status
+Returns: 0 on success; -1 on error
+
+/* for GUEST_STATUS */
+struct kvm_sev_guest_status {
+    /* guest handle */
+    u32 handle;
+
+    /* guest policy */
+    u32 policy;
+
+    /* guest state (see state enum) */
+    u8 state;
+};
+
+/* for SEV guest state */
+GuestState {
+    STATE_INVALID = 0,
+    STATE_LAUNCHING,
+    STATE_RECEIVING,
+    STATE_SENDING,
+    STATE_RUNNING,
+};
+
+1.4 DBG_DECRYPT (KVM_SEV_DBG_DECRYPT)
+
+The command is used to decrypt a page of guest memory for debug.
+
+Parameters: struct kvm_sev_dbg_decrypt
+Returns: 0 on success; -1 on error
+
+/* DGB_DECRYPT */
+struct kvm_sev_dbg_decrypt {
+    /*  virtual address of memory region to debug from */
+    u64 src_address;
+
+    /*  virtual address of memory region to write decrypted contents into */
+    u64 dst_address;
+
+    /* length of memory region */
+    u32 length;
+}
+
+1.4 DBG_ENCRYPT (KVM_SEV_DBG_ENCRYPT)
+
+The command is used to encrypt a page of guest memory for debug.
+
+Parameters: struct kvm_sev_dbg_encrypt
+Returns: 0 on success; -1 on error
+
+/* DGB_ENCRYPT */
+struct kvm_sev_dbg_encrypt {
+    /*  virtual address of memory region to debug from */
+    u64 src_address;
+
+    /*  virtual address of memory region to write encrypted contents into */
+    u64 dst_address;
+
+    /* length of memory region */
+    u32 length;
+}
+
+1.5 SEV Policy
+
+Firmware maintain a guest policy provided by the guest owner. This policy is
+enforced by the firmware and restricts what configuration and operational
+command can be performed on the SEV guest by the hypervisor. For instance,
+if debug is off then hypervisor will not able to decrypt guest memory using
+DBG_DECRYPT commands.
+
+The policy is 4-byte structure with the following field
+
+Bit 0 (debug) - Debugging of the guest is disallowed when set
+Bit 1 (ks) - Sharing keys with other guests is disallowed when set
+Bit 2 (reserved) - must be set to 1
+Bit 3 (nosend) - Sending the guest to another platform is disallowed when set
+Bit 4 (domain) - The guest must not be transmitted to another platform that is not in the domain when set
+Bit 5 (sev) - The guest must not be transmitted to another platform that is not SEV capable when set.
+Bit 15:6 (reserved)
+Bit 16:24 (fw_major) - The guest must not be transmitted to another platform that is not SEV capable when set.
+Bit 25:31 (fw_minor) - The guest must not be transmitted to another platform that is not SEV capable when set.
+
+2. QEMU command line
+--------------------
+
+SEV support can be enabled through 'memory-encryption' parameters defined in
+security-policy object. 
+
+The following objects can be used to provide SEV guest parameters.
+
+2.0 sev-launch-info
+
+The object can be used to provide various parameters required to launch an
+unencrypted SEV guest. A unencrypted guest means that OS images (bios, kernel
+and initrd) received from guest owner are unencrypted and SEV guest should
+encrypt it using the LAUNCH command.
+
+e.g to launch an unencrypted SEV guest
+
+# $QEMU \
+    -object sev-launch-info,id=launch0,flags.ks=off,dh-pub-qx=zzzz \
+    -object sev-guest-info,id=sev0,launch=launch0 \
+    -object security-policy,id=secure0,memory-encryption=sev0 \
+    -machine ...,security-policy=secure0
+
+2.1 sev-policy-info
+
+The object can be used to provide the guest policy for sev-launch-info object
+
+e.g to launch a unencrypted SEV guest which does not allow the guest to be
+send to another platform (i.e disable migration)
+
+# $QEMU \
+    -object sev-policy-info,id=policy0,nosend=on \
+    -object sev-launch-info,id=launch0,policy=policy0 \
+    ....
+
+2.2 sev-guest-info
+
+The object provides the properties to set the SEV guest launch and send id to
+use during SEV guest creation and migration.
+
+e.g to use sev-launch-info object id during SEV guest creation
+
+# $QEMU \
+    -object sev-launch-info,id=launch0 \
+    -object sev-guest-info,id=sev0,launch=launch0 \
+    -object security-policy,id=secure0,memory-encryption=sev0 \
+    ....
+
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c9c2436..16c14f4 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -56,6 +56,7 @@ extern bool kvm_ioeventfd_any_length_allowed;
 
 #if defined CONFIG_KVM || !defined NEED_CPU_H
 #define kvm_enabled()           (kvm_allowed)
+
 /**
  * kvm_irqchip_in_kernel:
  *
@@ -217,6 +218,11 @@ int kvm_has_intx_set_mask(void);
 int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
 int kvm_destroy_vcpu(CPUState *cpu);
+bool kvm_memory_encryption_enabled(void);
+int kvm_memory_encryption_start(void);
+int kvm_memory_encryption_finish(void);
+void *kvm_memory_encryption_get_handle(void);
+void kvm_memory_encryption_set_memory_region(MemoryRegion *mr);
 
 #ifdef NEED_CPU_H
 #include "cpu.h"
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
new file mode 100644
index 0000000..534390b
--- /dev/null
+++ b/include/sysemu/sev.h
@@ -0,0 +1,208 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016
+ *
+ * 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 <linux/kvm.h>
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "sysemu/kvm.h"
+
+#define TYPE_QSEV_GUEST_INFO "sev-guest-info"
+#define QSEV_GUEST_INFO(obj)                  \
+    OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
+
+typedef struct QSevGuestInfo QSevGuestInfo;
+typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+
+/**
+ * QSevGuestInfo:
+ *
+ * The QSevGuestInfo object provides the guest launch and migration ID
+ * when memory encryption support is enabled in security-policy.
+ *
+ * The QSevGuestInfo object provides two properties:
+ * - launch: should be set to SEV guest launch object ID
+ * - send: should be set to SEV guest send object ID
+ *
+ * e.g to launch a unencrypted SEV guest
+ *
+ * # $QEMU -object sev-launch-info,id=launch0,flags.ks=off \
+ *         -object sev-migrate-send,id=send0 \
+ *         -object sev-guest-info,id=sev0,launch=launch0 send=send0 \
+ *         -object security-policy,id=secure0,memory-encryption=sev0 \
+ *         -machine ...security-policy=secure0
+ */
+struct QSevGuestInfo {
+    Object parent_obj;
+
+    char *launch;
+    char *send;
+};
+
+struct QSevGuestInfoClass {
+    ObjectClass parent_class;
+};
+
+#define TYPE_QSEV_POLICY_INFO "sev-policy-info"
+#define QSEV_POLICY_INFO(obj)                  \
+    OBJECT_CHECK(QSevPolicyInfo, (obj), TYPE_QSEV_POLICY_INFO)
+
+typedef struct QSevPolicyInfo QSevPolicyInfo;
+typedef struct QSevPolicyInfoClass QSevPolicyInfoClass;
+
+/**
+ * QSevPolicyInfo:
+ *
+ * The QSevPolicyInfo object provides the SEV guest policy parameters used
+ * in launch and send commands.
+ *
+ * # $QEMU -object sev-policy-info,id=policy0,debug=on,ks=on,nosend=off \
+ *         -object sev-launch-info,id=launch0,flag.ks=on,policy=policy0\
+ *         ....
+ */
+struct QSevPolicyInfo {
+    Object parent_obj;
+    bool debug;
+    bool ks;
+    bool nosend;
+    bool domain;
+    bool sev;
+    uint8_t fw_major;
+    uint8_t fw_minor;
+};
+
+struct QSevPolicyInfoClass {
+    ObjectClass parent_class;
+};
+
+#define TYPE_QSEV_LAUNCH_INFO "sev-launch-info"
+#define QSEV_LAUNCH_INFO(obj)                  \
+    OBJECT_CHECK(QSevLaunchInfo, (obj), TYPE_QSEV_LAUNCH_INFO)
+
+typedef struct QSevLaunchInfo QSevLaunchInfo;
+typedef struct QSevLaunchInfoClass QSevLaunchInfoClass;
+
+/**
+ * QSevLaunchInfo:
+ *
+ * The QSevLaunchInfo object provides parameters to launch an unencrypted
+ * sev guest. A unencrypted guest launch means that the guest owners
+ * provided OS images (kernel, initrd and bios) are unencrypted and SEV
+ * would encrypt the images using guest owner's key creating using the
+ * launch parameters.
+ *
+ * # $QEMU -object sev-policy,debug=on,ks=on,nosend=off,id=policy1 \
+ *         -object sev-launch-info,flag.ks=on,policy=policy1,id=sev \
+ *         -object sev-guest-info,launch=sev,id=secure-guest \
+ *         ....
+ */
+struct QSevLaunchInfo {
+    Object parent_obj;
+    uint32_t handle;
+    bool flags_ks;
+    char *policy_id;
+    uint8_t nonce[16];
+    uint8_t dh_pub_qx[32];
+    uint8_t dh_pub_qy[32];
+};
+
+struct QSevLaunchInfoClass {
+    ObjectClass parent_class;
+};
+
+#define TYPE_QSEV_RECEIVE_INFO "sev-receive-info"
+#define QSEV_RECEIVE_INFO(obj)                  \
+    OBJECT_CHECK(QSevReceiveInfo, (obj), TYPE_QSEV_RECEIVE_INFO)
+
+typedef struct QSevReceiveInfo QSevReceiveInfo;
+typedef struct QSevReceiveInfoClass QSevReceiveInfoClass;
+
+/**
+ * QSevReceiveInfo:
+ *
+ * The QSevReceiveInfo object provides parameters to launch a pre-encrypted
+ * sev guest or receive the guest during migration. In this mode the images
+ * received from the remote is encrypted using transport key, SEV guest would
+ * re-encrypt the data using the owner's key creating using the parameters
+ * specified in this object.
+ *
+ * # $QEMU \
+ *         -object sev-receive-info,id=launch0,wrapped-tek=xxxx,ten=xxxx \
+ *         -object sev-guest,sev=0,launch=launch0 \
+ *         .....
+ *
+ */
+
+struct QSevReceiveInfo {
+    Object parent_obj;
+    uint32_t handle;
+    bool flags_ks;
+    char *policy_id;
+    uint8_t nonce[16];
+    uint8_t dh_pub_qx[32];
+    uint8_t dh_pub_qy[32];
+    uint8_t policy_measure[32];
+    uint8_t wrapped_tek[24];
+    uint8_t wrapped_tik[24];
+    uint8_t ten[24];
+};
+
+struct QSevReceiveInfoClass {
+    ObjectClass parent_class;
+};
+
+enum SevLaunchMode {
+    SEV_LAUNCH_INVALID = 0,
+    SEV_LAUNCH_UNENCRYPTED,
+    SEV_LAUNCH_ENCRYPTED
+};
+
+enum SevState {
+    SEV_STATE_INVALID = 0,
+    SEV_STATE_LAUNCHING,
+    SEV_STATE_RECEIVING,
+    SEV_STATE_SENDING,
+    SEV_STATE_RUNNING
+};
+
+struct SEVState {
+    char *launch_id;
+    char *sev_info_id;
+
+    uint8_t mode;
+    uint8_t state;
+    struct kvm_sev_launch_start *launch_start;
+    struct kvm_sev_launch_update *launch_update;
+    struct kvm_sev_launch_finish *launch_finish;
+    struct kvm_sev_receive_start *recv_start;
+    struct kvm_sev_receive_update *recv_update;
+    struct kvm_sev_receive_finish *recv_finish;
+    struct kvm_sev_send_start *send_start;
+    struct kvm_sev_send_update *send_update;
+    struct kvm_sev_send_finish *send_finish;
+};
+
+typedef struct SEVState SEVState;
+
+bool sev_enabled(void);
+bool has_sev_guest_policy(const char *keyid);
+void *sev_guest_init(const char *keyid);
+int sev_guest_launch_start(void *handle);
+int sev_guest_launch_finish(void *handle);
+void sev_guest_set_ops(void *handle, MemoryRegion *mr);
+
+#endif
+
diff --git a/kvm-all.c b/kvm-all.c
index ebf35b0..bb5da88 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -36,6 +36,8 @@
 #include "qemu/event_notifier.h"
 #include "trace.h"
 #include "hw/irq.h"
+#include "sysemu/security-policy.h"
+#include "sysemu/sev.h"
 
 #include "hw/boards.h"
 
@@ -101,6 +103,12 @@ struct KVMState
 #endif
     KVMMemoryListener memory_listener;
     QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
+
+    /* memory encryption support */
+    void *mem_encrypt_handle;
+    int (*mem_encrypt_start)(void *handle);
+    int (*mem_encrypt_finish)(void *handle);
+    void (*mem_encrypt_ops)(void *handle, MemoryRegion *mr);
 };
 
 KVMState *kvm_state;
@@ -126,6 +134,42 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = {
     KVM_CAP_LAST_INFO
 };
 
+bool kvm_memory_encryption_enabled(void)
+{
+    return kvm_state->mem_encrypt_handle ? true : false;
+}
+
+int kvm_memory_encryption_start(void)
+{
+    if (kvm_state->mem_encrypt_start) {
+        return kvm_state->mem_encrypt_start(kvm_state->mem_encrypt_handle);
+    }
+
+    return -1;
+}
+
+int kvm_memory_encryption_finish(void)
+{
+    if (kvm_state->mem_encrypt_finish) {
+        return kvm_state->mem_encrypt_finish(kvm_state->mem_encrypt_handle);
+    }
+
+    return -1;
+}
+
+void kvm_memory_encryption_set_memory_region(MemoryRegion *mr)
+{
+    if (kvm_state->mem_encrypt_ops) {
+        return kvm_state->mem_encrypt_ops(kvm_state->mem_encrypt_handle,
+                                          mr);
+    }
+}
+
+void *kvm_memory_encryption_get_handle(void)
+{
+    return kvm_state->mem_encrypt_handle;
+}
+
 int kvm_get_max_memslots(void)
 {
     KVMState *s = KVM_STATE(current_machine->accelerator);
@@ -1745,6 +1789,33 @@ static int kvm_init(MachineState *ms)
 
     kvm_state = s;
 
+    if (ms->security_policy) {
+        char *id;
+
+        /* if security-policy is enabled  then check whether memory encryption
+         * property is defined. If so, enable hardware memory encryption.
+         */
+        id = security_policy_get_memory_encryption_id(ms->security_policy);
+        if (id) {
+
+            /* check if its SEV guest policy */
+            if (has_sev_guest_policy(id)) {
+                kvm_state->mem_encrypt_handle = sev_guest_init(id);
+                if (!kvm_state->mem_encrypt_handle) {
+                    fprintf(stderr,
+                            "failed to initialize Secure Encrypted"
+                            " Virutalization (SEV) guest\n");
+                    goto err;
+                }
+                kvm_state->mem_encrypt_start = sev_guest_launch_start;
+                kvm_state->mem_encrypt_finish = sev_guest_launch_finish;
+                kvm_state->mem_encrypt_ops = sev_guest_set_ops;
+            }
+
+            g_free(id);
+        }
+    }
+
     if (kvm_eventfds_allowed) {
         s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add;
         s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del;
diff --git a/qemu-options.hx b/qemu-options.hx
index b90d6da..7362452 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3985,7 +3985,111 @@ can be set to the unquie ID of memory encryption object.
 
 On AMD processor, memory encryption is supported via 'sev-guest-info' object.
 
-@end table
+@item -object sev-guest-info,id=@var{id},launch=@var{id}[,send=@var{id}]
+
+Create a Secure Encrypted Virtualization (SEV) guest object, which be used to
+provide the memory encryption support on AMD processors. The id paramerter is
+a unique ID that should be used in security-policy object when creating the
+SEV-enabled guest. 
+
+When creating a SEV guest, 'launch' parameter should be set to the unquire ID
+from SEV launch object.
+
+e.g to launch a SEV guest
+@example
+ # $QEMU \
+     -object sev-launch-info,id=launch0 \
+     -object sev-guest-info,id=sev0,launch=launch0 \
+     -object security-policy,id=secure0-guest,memory-encryption=sev0 \
+     -machine ...,security-policy=secure0
+@end example
+
+@item -object sev-launch-info,id=@var{id}[,flags.ks=@var{bool}][,policy=@var{id}][,nonce=@var{string}][,dh-pub-qx=@var{string}][,dh-pub-qy=@var{string}][,handle=@var{int}]
+
+Create a SEV launch info object, which can be used to pass various parameters
+required to transition an unencrypted guest into SEV-enabled mode.
+The id parameter is a unique ID that should be used in sev-guest-info object
+when creating a unencrypted SEV guest.
+
+The 'flags.ks' parameter should be set when guest owner has requested the key
+sharing with other guests.
+
+The 'nonce' parameter should be set with a nonce generated by guest owner.
+
+The 'dh-pub-qx' and 'dh-pub-qy' parameters should be set with guest owners
+ECDH public key.
+
+The 'policy' parameter should be set to unique ID created from 'sev-policy-info'.
+
+e.g to launch a unencrypted SEV guest
+@example
+ # $QEMU \
+     -object sev-launch-info,id=launch0,flags.ks=off,nonce=xxxx \
+     -object sev-guest-info,id=sev0,launch=launch0 \
+@end example
+
+@item -object sev-receive-info,id=@var{id},measurement=@var{string}[,flags.ks=@var{bool}][,policy=@var{id}][,nonce=@var{string}][,dh-pub-qx=@var{string}][,dh-pub-qy=@var{string}][,handle=@var{int}][,wrapped-tek=@var{string}][,wrapped-tik=@var{string}][,ten=@var{string}]
+
+Create a SEV guest receive info object, which can be used to pass various
+parameters required to receive a encrypted guest. The object can be used for
+both when launching a pre-encrypted guest or receiving a migration.
+The id parameter is a unique ID that should be used in sev-guest-info object
+when creating a encrypted SEV guest.
+
+The 'flags.ks' parameter should be set when guest owner has requested the key
+sharing with other guests.
+
+The 'nonce' parameter should be set with a nonce generated by guest owner.
+
+The 'dh-pub-qx' and 'dh-pub-qy' parameters should be set with guest owners
+ECDH public key.
+
+The 'policy' parameter should be set to unique ID created from 'sev-policy-info.
+
+The 'wrapped-tek' parameter should be set with transport encryption key.
+
+The 'wrapped-tik' parameter should be set with transport identity key.
+
+The 'ten' parameter should be set with transport encryption nonce.
+
+The 'measurement' should be set with measurement of transported guest.
+
+e.g to launch a encrypted SEV guest
+@example
+ # $QEMU \
+     -object sev-receive-info,id=launch0,flags.ks=off,nonce=xxxx \
+     -object sev-guest-info,id=sev0,launch=launch0 \
+@end example
+
+@item -object sev-policy-info,id=@var{id}[,debug=@var{bool}][,ks=@var{bool}][,nosend=@var{bool}][,domain=@var{bool}][,sev=@var{bool}][,fw-major=@var{int}][,fw-minor=@var{int}]
+
+Create SEV guest policy object, which can be used to pass the guest policy
+during SEV guest creation and migration. The id parameter is a unqiue ID that
+should be used in SEV launch and send objects.
+
+The SEV guest policy should be provided by the guest owner.
+
+debug: should be set if guest owner allows the debugging
+
+ks: should be set when guest owner allows sharing the key with other guest
+
+nosend: should be set when guest owner does not allow the platform to be
+        migrated to remote location.
+
+domain: should be set when guest owner does not allow platform to be transmitted
+        to another location that is not in the domain.
+
+sev: should be set when guest should not be transmitted to non SEV platform.
+
+fw_major/minor: guest should not be transmitted to another platform with a
+  lower firmware version.
+
+e.g to create a policy
+@example
+  # $QEMU \
+      -object sev-policy-info,id=policy0,debug=on,ks=off \
+      -object sev-launch-info,id=launch0,policy=policy0 \
+@end example
 
 ETEXI
 
diff --git a/sev.c b/sev.c
new file mode 100644
index 0000000..226ad76
--- /dev/null
+++ b/sev.c
@@ -0,0 +1,1074 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016
+ *
+ * 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 "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+#include "sysemu/kvm.h"
+#include "sysemu/sev.h"
+#include "trace.h"
+
+#define DEBUG_SEV
+#ifdef DEBUG_SEV
+#define DPRINTF(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+static MemoryRegionRAMReadWriteOps sev_ops;
+static bool sev_allowed;
+
+static void
+DPRINTF_U8_PTR(const char *msg, uint8_t *ptr, int count)
+{
+    int i;
+
+    DPRINTF("%s = ", msg);
+    for (i = 0; i < count; i++) {
+        DPRINTF("%02hhx", ptr[i]);
+    }
+    DPRINTF("\n");
+}
+
+static void
+str_to_uint8_ptr(const char *str, uint8_t *ptr, int count)
+{
+    int i = 0;
+
+    while (*str && i != count) {
+        sscanf(str, "%2hhx", &ptr[i]);
+        str += 2;
+        i++;
+    }
+}
+
+static char *
+uint8_ptr_to_str(uint8_t *ptr, int count)
+{
+    char *str = g_malloc0(count);
+
+    return memcpy(str, ptr, count);
+}
+
+static Object *
+get_object_by_id(const char *id)
+{
+    Object *obj;
+
+    obj = object_resolve_path_component(
+        object_get_objects_root(), id);
+    if (!obj) {
+        return NULL;
+    }
+
+    return obj;
+
+}
+
+static bool
+qsev_policy_get_debug(Object *obj, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    return policy->debug;
+}
+
+static void
+qsev_policy_set_debug(Object *obj, bool value, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    policy->debug = value;
+}
+
+static bool
+qsev_policy_get_ks(Object *obj, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    return policy->ks;
+}
+
+static void
+qsev_policy_set_ks(Object *obj, bool value, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    policy->ks = value;
+}
+
+static bool
+qsev_policy_get_nosend(Object *obj, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    return policy->nosend;
+}
+
+static void
+qsev_policy_set_nosend(Object *obj, bool value, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    policy->nosend = value;
+}
+
+static bool
+qsev_policy_get_domain(Object *obj, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    return policy->domain;
+}
+
+static void
+qsev_policy_set_domain(Object *obj, bool value, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    policy->domain = value;
+}
+
+static bool
+qsev_policy_get_sev(Object *obj, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    return policy->sev;
+}
+
+static void
+qsev_policy_set_sev(Object *obj, bool value, Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+
+    policy->sev = value;
+}
+
+static void
+qsev_policy_get_fw_major(Object *obj, Visitor *v,
+                         const char *name, void *opaque,
+                         Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+    uint8_t value = policy->fw_major;
+
+    visit_type_uint8(v, name, &value, errp);
+}
+
+static void
+qsev_policy_set_fw_major(Object *obj, Visitor *v,
+                         const char *name, void *opaque,
+                         Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+    Error *error = NULL;
+    uint8_t value;
+
+    visit_type_uint8(v, name, &value, &error);
+    if (error) {
+        return;
+    }
+
+    policy->fw_major = value;
+}
+
+static void
+qsev_policy_get_fw_minor(Object *obj, Visitor *v,
+                         const char *name, void *opaque,
+                         Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+    uint8_t value = policy->fw_minor;
+
+    visit_type_uint8(v, name, &value, errp);
+}
+
+static void
+qsev_policy_set_fw_minor(Object *obj, Visitor *v,
+                         const char *name, void *opaque,
+                         Error **errp)
+{
+    QSevPolicyInfo *policy = QSEV_POLICY_INFO(obj);
+    Error *error = NULL;
+    uint8_t value;
+
+    visit_type_uint8(v, name, &value, &error);
+    if (error) {
+        return;
+    }
+
+    policy->fw_minor = value;
+}
+
+static void
+qsev_policy_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_bool(oc, "debug",
+                                   qsev_policy_get_debug,
+                                   qsev_policy_set_debug,
+                                   NULL);
+    object_class_property_set_description(oc, "debug",
+            "Set on/off if debugging is allowed on this guest",
+            NULL);
+
+    object_class_property_add_bool(oc, "ks",
+                                   qsev_policy_get_ks,
+                                   qsev_policy_set_ks,
+                                   NULL);
+    object_class_property_set_description(oc, "ks",
+            "Set on/off if guest is allowed to share key with others.",
+            NULL);
+
+    object_class_property_add_bool(oc, "nosend",
+                                   qsev_policy_get_nosend,
+                                   qsev_policy_set_nosend,
+                                   NULL);
+    object_class_property_set_description(oc, "nosend",
+            "Set on/off if sending guest to anoter platform is allowed",
+            NULL);
+
+    object_class_property_add_bool(oc, "domain",
+                                   qsev_policy_get_domain,
+                                   qsev_policy_set_domain,
+                                   NULL);
+    object_class_property_set_description(oc, "domain",
+            "Set on/off if guest should not be transmitted to another platform that is not in the same domain.",
+            NULL);
+
+    object_class_property_add_bool(oc, "sev",
+                                   qsev_policy_get_sev,
+                                   qsev_policy_set_sev,
+                                   NULL);
+    object_class_property_set_description(oc, "domain",
+            "Set on/off if guest should not be transmitted to another non SEV platform",
+            NULL);
+
+    object_class_property_add(oc, "fw_major", "uint8",
+                                   qsev_policy_get_fw_major,
+                                   qsev_policy_set_fw_major,
+                                   NULL, NULL, NULL);
+    object_class_property_set_description(oc, "fw_major",
+            "guest must not be transmitted to another platform with a lower firmware version",
+            NULL);
+    object_class_property_add(oc, "fw_minor", "uint8",
+                                   qsev_policy_get_fw_minor,
+                                   qsev_policy_set_fw_minor,
+                                   NULL, NULL, NULL);
+    object_class_property_set_description(oc, "fw_minor",
+            "guest must not be transmitted to another platform with a lower firmware version",
+            NULL);
+}
+
+static void
+qsev_policy_finalize(Object *obj)
+{
+}
+
+static QSevPolicyInfo *
+lookup_sev_policy_info(const char *id)
+{
+    QSevPolicyInfo *policy;
+    Object *obj = get_object_by_id(id);
+
+    if (!obj) {
+        return NULL;
+    }
+
+    policy = (QSevPolicyInfo *)
+        object_dynamic_cast(obj,
+                            TYPE_QSEV_POLICY_INFO);
+    if (!policy) {
+        return NULL;
+    }
+
+    return policy;
+}
+
+static uint32_t
+sev_policy_get_value(const char *id)
+{
+    uint32_t val = 0;
+    QSevPolicyInfo *policy = lookup_sev_policy_info(id);
+
+    if (!policy) {
+        return 0;
+    }
+
+    val = policy->debug;
+    val |= policy->ks << 1;
+    val |= (1 << 2);
+    val |= policy->nosend << 3;
+    val |= policy->domain << 4;
+    val |= policy->sev << 5;
+    val |= policy->fw_major << 16;
+    val |= policy->fw_minor << 24;
+
+    return val;
+}
+
+/* qsev policy */
+static const TypeInfo qsev_policy_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_POLICY_INFO,
+    .instance_size = sizeof(QSevPolicyInfo),
+    .instance_finalize = qsev_policy_finalize,
+    .class_size = sizeof(QSevPolicyInfoClass),
+    .class_init = qsev_policy_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static char *
+qsev_guest_get_launch_id(Object *obj, Error **errp)
+{
+    QSevGuestInfo *sev_info = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(sev_info->launch);
+}
+
+static void
+qsev_guest_set_launch_id(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *sev_info = QSEV_GUEST_INFO(obj);
+
+    sev_info->launch = g_strdup(value);
+}
+
+static char *
+qsev_guest_get_send_id(Object *obj, Error **errp)
+{
+    QSevGuestInfo *sev_info = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(sev_info->send);
+}
+
+static void
+qsev_guest_set_send_id(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *sev_info = QSEV_GUEST_INFO(obj);
+
+    sev_info->send = g_strdup(value);
+}
+
+static void
+qsev_guest_finalize(Object *obj)
+{
+    QSevGuestInfo *sev_info = QSEV_GUEST_INFO(obj);
+
+    g_free(sev_info->launch);
+    g_free(sev_info->send);
+}
+
+static void
+qsev_guest_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_str(oc, "launch",
+                                  qsev_guest_get_launch_id,
+                                  qsev_guest_set_launch_id,
+                                  NULL);
+    object_class_property_set_description(oc, "launch",
+            "Set the launch object id to use", NULL);
+    object_class_property_add_str(oc, "send",
+                                  qsev_guest_get_send_id,
+                                  qsev_guest_set_send_id,
+                                  NULL);
+    object_class_property_set_description(oc, "send",
+            "Set the send object id to use when migrating the guest", NULL);
+}
+
+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;
+}
+
+static uint8_t
+sev_guest_info_get_mode(const char *id)
+{
+    uint8_t ret = SEV_LAUNCH_INVALID;
+    Object *obj;
+
+    obj = get_object_by_id(id);
+    if (object_dynamic_cast(obj, TYPE_QSEV_LAUNCH_INFO)) {
+        ret = SEV_LAUNCH_UNENCRYPTED;
+    } else if (object_dynamic_cast(obj, TYPE_QSEV_RECEIVE_INFO)) {
+        ret = SEV_LAUNCH_ENCRYPTED;
+    }
+
+    return ret;
+}
+
+/* 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,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+qsev_launch_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_launch_get_policy_id(Object *obj, Error **errp)
+{
+    QSevLaunchInfo *sev_info = QSEV_LAUNCH_INFO(obj);
+
+    return g_strdup(sev_info->policy_id);
+}
+
+static void
+qsev_launch_set_policy_id(Object *obj, const char *value, Error **errp)
+{
+    QSevLaunchInfo *sev_info = QSEV_LAUNCH_INFO(obj);
+
+    sev_info->policy_id = g_strdup(value);
+}
+
+static bool
+qsev_launch_get_flags_ks(Object *obj, Error **errp)
+{
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    return launch->flags_ks;
+}
+
+static void
+qsev_launch_set_flags_ks(Object *obj, bool value, Error **errp)
+{
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    launch->flags_ks = value;
+}
+
+static char *
+qsev_launch_get_nonce(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str = uint8_ptr_to_str(launch->nonce, sizeof(launch->nonce));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_launch_set_nonce(Object *obj, const char *value, Error **errp)
+{
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str_to_uint8_ptr(value, launch->nonce, sizeof(launch->nonce));
+}
+
+static char *
+qsev_launch_get_dh_pub_qx(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str = uint8_ptr_to_str(launch->dh_pub_qx, sizeof(launch->dh_pub_qx));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_launch_set_dh_pub_qx(Object *obj, const char *value, Error **errp)
+{
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str_to_uint8_ptr(value, launch->dh_pub_qx,
+                     sizeof(launch->dh_pub_qx));
+}
+
+static char *
+qsev_launch_get_dh_pub_qy(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str = uint8_ptr_to_str(launch->dh_pub_qy, sizeof(launch->dh_pub_qy));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_launch_set_dh_pub_qy(Object *obj, const char *value, Error **errp)
+{
+    QSevLaunchInfo *launch = QSEV_LAUNCH_INFO(obj);
+
+    str_to_uint8_ptr(value, launch->dh_pub_qy,
+                     sizeof(launch->dh_pub_qy));
+}
+
+static void
+qsev_launch_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_bool(oc, "flags.ks",
+                                   qsev_launch_get_flags_ks,
+                                   qsev_launch_set_flags_ks,
+                                   NULL);
+    object_class_property_set_description(oc, "flags.ks",
+            "Set on/off if key sharing with other guests is allowed",
+            NULL);
+
+    object_class_property_add_str(oc, "policy",
+                                  qsev_launch_get_policy_id,
+                                  qsev_launch_set_policy_id,
+                                  NULL);
+    object_class_property_set_description(oc, "policy",
+            "Set the guest owner's sev-policy id", NULL);
+
+    object_class_property_add_str(oc, "nonce",
+                                  qsev_launch_get_nonce,
+                                  qsev_launch_set_nonce,
+                                  NULL);
+    object_class_property_set_description(oc, "nonce",
+            "a nonce provided by guest owner", NULL);
+
+    object_class_property_add_str(oc, "dh-pub-qx",
+                                  qsev_launch_get_dh_pub_qx,
+                                  qsev_launch_set_dh_pub_qx,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-pub-qx",
+            "Qx parameter of owner's ECDH public key", NULL);
+
+    object_class_property_add_str(oc, "dh-pub-qy",
+                                  qsev_launch_get_dh_pub_qy,
+                                  qsev_launch_set_dh_pub_qy,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-pub-qy",
+            "Qy parameter of owner's ECDH public key", NULL);
+}
+
+static uint8_t
+sev_launch_info_get_flags(QSevLaunchInfo *launch)
+{
+    uint8_t flags = launch->flags_ks;
+
+    return flags;
+}
+
+static QSevLaunchInfo *
+lookup_sev_launch_info(const char *id)
+{
+    Object *obj;
+    QSevLaunchInfo *info;
+
+    obj = object_resolve_path_component(
+        object_get_objects_root(), id);
+    if (!obj) {
+        return NULL;
+    }
+
+    info = (QSevLaunchInfo *)
+            object_dynamic_cast(obj, TYPE_QSEV_LAUNCH_INFO);
+    if (!info) {
+        return NULL;
+    }
+
+    return info;
+}
+
+static int
+sev_launch_info_get_params(const char *id,
+                           struct kvm_sev_launch_start **s,
+                           struct kvm_sev_launch_update **u,
+                           struct kvm_sev_launch_finish **f)
+{
+    QSevLaunchInfo *info;
+    struct kvm_sev_launch_start *start;
+    struct kvm_sev_launch_finish *finish;
+
+    info = lookup_sev_launch_info(id);
+    if (!info) {
+        return -1;
+    }
+
+    start = g_malloc0(sizeof(*start));
+    start->flags = sev_launch_info_get_flags(info);
+    start->policy = sev_policy_get_value(info->policy_id);
+    memcpy(start->nonce, info->nonce, sizeof(info->nonce));
+    memcpy(start->dh_pub_qx, info->dh_pub_qx, sizeof(info->dh_pub_qx));
+    memcpy(start->dh_pub_qy, info->dh_pub_qy, sizeof(info->dh_pub_qy));
+
+    finish = g_malloc0(sizeof(*finish));
+
+    DPRINTF("sev-launch\n");
+    DPRINTF(" flags: %#x\n", start->flags);
+    DPRINTF(" policy: %#x\n", start->policy);
+    DPRINTF_U8_PTR(" dh_pub_qx", start->dh_pub_qx, sizeof(start->dh_pub_qx));
+    DPRINTF_U8_PTR(" dh_pub_qy", start->dh_pub_qy, sizeof(start->dh_pub_qy));
+    DPRINTF_U8_PTR(" nonce", start->nonce, sizeof(start->nonce));
+
+    *s = start;
+    *u = g_malloc(sizeof(struct kvm_sev_launch_update));
+    *f = finish;
+
+    return 0;
+}
+
+/* unencrypted guest launch */
+static const TypeInfo qsev_launch_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_LAUNCH_INFO,
+    .instance_size = sizeof(QSevLaunchInfo),
+    .instance_finalize = qsev_launch_finalize,
+    .class_size = sizeof(QSevLaunchInfoClass),
+    .class_init = qsev_launch_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+qsev_receive_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_receive_get_policy_id(Object *obj, Error **errp)
+{
+    QSevReceiveInfo *sev_info = QSEV_RECEIVE_INFO(obj);
+
+    return g_strdup(sev_info->policy_id);
+}
+
+static void
+qsev_receive_set_policy_id(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *sev_info = QSEV_RECEIVE_INFO(obj);
+
+    sev_info->policy_id = g_strdup(value);
+}
+
+static bool
+qsev_receive_get_flags_ks(Object *obj, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    return receive->flags_ks;
+}
+
+static void
+qsev_receive_set_flags_ks(Object *obj, bool value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    receive->flags_ks = value;
+}
+
+static char *
+qsev_receive_get_nonce(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->nonce, sizeof(receive->nonce));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_nonce(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->nonce, sizeof(receive->nonce));
+}
+
+static char *
+qsev_receive_get_dh_pub_qx(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->dh_pub_qx, sizeof(receive->dh_pub_qx));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_dh_pub_qx(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->dh_pub_qx,
+                     sizeof(receive->dh_pub_qx));
+}
+
+static char *
+qsev_receive_get_dh_pub_qy(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->dh_pub_qy, sizeof(receive->dh_pub_qy));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_dh_pub_qy(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->dh_pub_qy,
+                     sizeof(receive->dh_pub_qy));
+}
+
+static char *
+qsev_receive_get_ten(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->ten, sizeof(receive->ten));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_ten(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->ten,
+                     sizeof(receive->ten));
+}
+
+static char *
+qsev_receive_get_wrapped_tik(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->wrapped_tik, sizeof(receive->wrapped_tik));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_wrapped_tik(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->wrapped_tik,
+                     sizeof(receive->wrapped_tik));
+}
+
+static char *
+qsev_receive_get_wrapped_tek(Object *obj, Error **errp)
+{
+    char *value, *str;
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str = uint8_ptr_to_str(receive->wrapped_tek, sizeof(receive->wrapped_tek));
+    value = g_strdup(str);
+    g_free(str);
+
+    return value;
+}
+
+static void
+qsev_receive_set_wrapped_tek(Object *obj, const char *value, Error **errp)
+{
+    QSevReceiveInfo *receive = QSEV_RECEIVE_INFO(obj);
+
+    str_to_uint8_ptr(value, receive->wrapped_tek,
+                     sizeof(receive->wrapped_tek));
+}
+
+static void
+qsev_receive_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_bool(oc, "flags.ks",
+                                   qsev_receive_get_flags_ks,
+                                   qsev_receive_set_flags_ks,
+                                   NULL);
+    object_class_property_set_description(oc, "flags.ks",
+            "Set on/off if key sharing with other guests is allowed",
+            NULL);
+
+    object_class_property_add_str(oc, "policy",
+                                  qsev_receive_get_policy_id,
+                                  qsev_receive_set_policy_id,
+                                  NULL);
+    object_class_property_set_description(oc, "policy",
+            "Set the guest origin sev-policy id", NULL);
+
+    object_class_property_add_str(oc, "nonce",
+                                  qsev_receive_get_nonce,
+                                  qsev_receive_set_nonce,
+                                  NULL);
+    object_class_property_set_description(oc, "nonce",
+            "a nonce provided by origin", NULL);
+
+    object_class_property_add_str(oc, "dh-pub-qx",
+                                  qsev_receive_get_dh_pub_qx,
+                                  qsev_receive_set_dh_pub_qx,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-pub-qx",
+            "Qx parameter of origin ECDH public key", NULL);
+
+    object_class_property_add_str(oc, "dh-pub-qy",
+                                  qsev_receive_get_dh_pub_qy,
+                                  qsev_receive_set_dh_pub_qy,
+                                  NULL);
+    object_class_property_set_description(oc, "dh-pub-qy",
+            "Qy parameter of origin ECDH public key", NULL);
+
+    object_class_property_add_str(oc, "ten",
+                                  qsev_receive_get_ten,
+                                  qsev_receive_set_ten,
+                                  NULL);
+    object_class_property_set_description(oc, "ten",
+            "Set transport encryption nonce", NULL);
+
+    object_class_property_add_str(oc, "wrapped-tik",
+                                  qsev_receive_get_wrapped_tik,
+                                  qsev_receive_set_wrapped_tik,
+                                  NULL);
+    object_class_property_set_description(oc, "wrapped-tik",
+            "The wrapped transport identity key", NULL);
+
+    object_class_property_add_str(oc, "wrapped-tek",
+                                  qsev_receive_get_wrapped_tek,
+                                  qsev_receive_set_wrapped_tek,
+                                  NULL);
+    object_class_property_set_description(oc, "wrapped-tek",
+            "The wrapped transport encryption key", NULL);
+}
+
+/* pre-encrypted guest launch */
+static const TypeInfo qsev_receive_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_RECEIVE_INFO,
+    .instance_size = sizeof(QSevReceiveInfo),
+    .instance_finalize = qsev_receive_finalize,
+    .class_size = sizeof(QSevReceiveInfoClass),
+    .class_init = qsev_receive_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static int
+sev_launch_start(SEVState *s)
+{
+    int ret;
+
+    ret = sev_launch_info_get_params(s->launch_id, &s->launch_start,
+                                     &s->launch_update, &s->launch_finish);
+    if (ret < 0) {
+        return -1;
+    }
+
+    // add the command to launch guest in next patches
+    return 0;
+}
+
+static int
+sev_launch_finish(SEVState *s)
+{
+    // add the command to finalize the launch in next patches
+    return 0;
+}
+
+/**
+ * Function returns 'true' if id is a valid QSevGuestInfo object.
+ */
+bool
+has_sev_guest_policy(const char *id)
+{
+    return lookup_sev_guest_info(id) ? true : false;
+}
+
+void *
+sev_guest_init(const char *id)
+{
+    int ret;
+    SEVState *s;
+    QSevGuestInfo *sev_info;
+
+    s = g_malloc0(sizeof(SEVState));
+    if (!s) {
+        return NULL;
+    }
+
+    sev_info = lookup_sev_guest_info(id);
+    if (!sev_info) {
+        fprintf(stderr, "'%s' not a valid '%s' object\n",
+                id, TYPE_QSEV_GUEST_INFO);
+        goto err;
+    }
+
+    s->mode = sev_guest_info_get_mode(sev_info->launch);
+    if (s->mode == SEV_LAUNCH_INVALID) {
+        fprintf(stderr, "'%s' invalid sev launch id\n", sev_info->launch);
+        goto err;
+    }
+
+    s->sev_info_id = g_strdup(id);
+    s->launch_id = g_strdup(sev_info->launch);
+
+    /* now launch the guest */
+    ret = sev_guest_launch_start(s);
+    if (ret < 0) {
+        goto err;
+    }
+
+    sev_allowed = true;
+    return s;
+err:
+    g_free(s);
+
+    return NULL;
+}
+
+int
+sev_guest_launch_start(void *handle)
+{
+    SEVState *s = (SEVState *)handle;
+
+    if (s->state == SEV_STATE_RUNNING) {
+        return 0;
+    }
+
+    if (s->mode == SEV_LAUNCH_UNENCRYPTED) {
+        return sev_launch_start(s);
+    } else if (s->mode == SEV_LAUNCH_ENCRYPTED) {
+        // use receive_info commands
+    }
+
+    return -1;
+}
+
+int
+sev_guest_launch_finish(void *handle)
+{
+    SEVState *s = (SEVState *)handle;
+
+    if (s->state == SEV_STATE_RUNNING) {
+        return 0;
+    }
+
+    if (s->state == SEV_STATE_LAUNCHING) {
+        return sev_launch_finish(s);
+        // use launch_finish commands
+    } else if (s->state == SEV_STATE_RECEIVING) {
+        // use receive_finish commands
+    } else {
+        return -1;
+    }
+
+    return -1;
+}
+
+static int
+sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
+{
+    SEVState *s = kvm_memory_encryption_get_handle();
+
+    assert(s != NULL);
+
+    // fill in the code in next patches
+    return 0;
+}
+
+static int
+sev_mem_read(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
+{
+    SEVState *s = kvm_memory_encryption_get_handle();
+
+    assert(s != NULL);
+
+    // fill in the code in next patches
+    return 0;
+}
+
+void
+sev_guest_set_ops(void *handle, MemoryRegion *mr)
+{
+    SEVState *s = (SEVState *)handle;
+
+    assert(s != NULL);
+
+    sev_ops.read = sev_mem_read;
+    sev_ops.write = sev_mem_write;
+
+    memory_region_set_ram_ops(mr, &sev_ops);
+}
+
+bool
+sev_enabled(void)
+{
+    return sev_allowed;
+}
+
+static void
+sev_policy_register_types(void)
+{
+    type_register_static(&qsev_guest_info);
+    type_register_static(&qsev_policy_info);
+    type_register_static(&qsev_launch_info);
+    type_register_static(&qsev_receive_info);
+}
+
+type_init(sev_policy_register_types);

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm'
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (5 preceding siblings ...)
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
@ 2016-09-22 14:52 ` Brijesh Singh
  2016-09-22 15:32   ` Eric Blake
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 08/16] core: loader: create memory encryption context before copying data Brijesh Singh
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

update 'info kvm' to display the memory encryption support.

(qemu) info kvm
kvm support: enabled
memory encryption: disabled

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 hmp.c            |    2 ++
 qapi-schema.json |    7 +++++--
 qmp.c            |    1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hmp.c b/hmp.c
index cc2056e..11e4005 100644
--- a/hmp.c
+++ b/hmp.c
@@ -81,6 +81,8 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "kvm support: ");
     if (info->present) {
         monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
+        monitor_printf(mon, "memory encryption: %s\n",
+                       info->mem_encryption ? "enabled" : "disabled");
     } else {
         monitor_printf(mon, "not compiled\n");
     }
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723..ce7b7e9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -99,9 +99,12 @@
 #
 # @present: true if KVM acceleration is built into this executable
 #
-# Since: 0.14.0
+# @mem_encryption: true if Memory Encryption is active
+#
+# Since: 2.8.0
 ##
-{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
+{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool',
+            'mem_encryption' : 'bool'} }
 
 ##
 # @query-kvm:
diff --git a/qmp.c b/qmp.c
index b6d531e..62f3e60 100644
--- a/qmp.c
+++ b/qmp.c
@@ -77,6 +77,7 @@ KvmInfo *qmp_query_kvm(Error **errp)
 
     info->enabled = kvm_enabled();
     info->present = kvm_available();
+    info->mem_encryption = kvm_memory_encryption_enabled();
 
     return info;
 }

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 08/16] core: loader: create memory encryption context before copying data
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (6 preceding siblings ...)
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm' Brijesh Singh
@ 2016-09-22 14:53 ` Brijesh Singh
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 09/16] sev: add LAUNCH_START command Brijesh Singh
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

During system boot, rom_reset copies bios binary from internal PC.BIOS
ROM to guest RAM (PC.RAM).

If memory encryption is enabled then we need to ensure that encryption
context is created before we start the copy process. When encryption is
enabled any data copy from PC.BIOS ROM to guest RAM will go through the
encryption routines which will encrypt the data as it copies into guest
memory. Similarly after we are done with copying destory the encryption
context.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 hw/core/loader.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index 53e0e41..6e0be34 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -55,6 +55,7 @@
 #include "exec/address-spaces.h"
 #include "hw/boards.h"
 #include "qemu/cutils.h"
+#include "sysemu/kvm.h"
 
 #include <zlib.h>
 
@@ -997,6 +998,13 @@ static void rom_reset(void *unused)
 {
     Rom *rom;
 
+    /* create the memory encryption context before we copy any data
+     * from internal ROM to guest RAM.
+     */
+    if (kvm_memory_encryption_enabled()) {
+        kvm_memory_encryption_start();
+    }
+
     QTAILQ_FOREACH(rom, &roms, next) {
         if (rom->fw_file) {
             continue;
@@ -1024,6 +1032,11 @@ static void rom_reset(void *unused)
          */
         cpu_flush_icache_range(rom->addr, rom->datasize);
     }
+
+    /* delete the memory encryption context after we are done with copying */
+    if (kvm_memory_encryption_enabled()) {
+        kvm_memory_encryption_finish();
+    }
 }
 
 int rom_check_and_register_reset(void)

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 09/16] sev: add LAUNCH_START command
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (7 preceding siblings ...)
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 08/16] core: loader: create memory encryption context before copying data Brijesh Singh
@ 2016-09-22 14:53 ` Brijesh Singh
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 10/16] sev: add LAUNCH_UPDATE command Brijesh Singh
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The command is used to prepare a guest for the transition into
SEV-enabled mode.

Command uses the parameters specified in 'sev-launch-info' object, see
doc/amd-memory-encryption.txt for parameter details. The command creates
a new VM Encryption Key (VEK) and cryptographic context. The key created
during launch start process will be used to encrypt the guest memory.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 sev.c |   30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/sev.c b/sev.c
index 226ad76..ead7c5a 100644
--- a/sev.c
+++ b/sev.c
@@ -910,17 +910,45 @@ static const TypeInfo qsev_receive_info = {
 };
 
 static int
+sev_ioctl(int cmd, void *data)
+{
+    int ret;
+    struct kvm_sev_issue_cmd input;
+
+    input.cmd = cmd;
+    input.opaque = (__u64)data;
+    ret = kvm_vm_ioctl(kvm_state, KVM_SEV_ISSUE_CMD, &input);
+    if (ret) {
+        fprintf(stderr, "sev_ioctl failed cmd=%#x, ret=%d(%#010x)\n",
+                cmd, ret, input.ret_code);
+        return ret;
+    }
+
+    return 0;
+}
+
+static int
 sev_launch_start(SEVState *s)
 {
     int ret;
 
+    if (s->state == SEV_STATE_LAUNCHING) {
+        return 0;
+    }
+
     ret = sev_launch_info_get_params(s->launch_id, &s->launch_start,
                                      &s->launch_update, &s->launch_finish);
     if (ret < 0) {
         return -1;
     }
 
-    // add the command to launch guest in next patches
+    ret = sev_ioctl(KVM_SEV_LAUNCH_START, s->launch_start);
+    if (ret < 0) {
+        return -1;
+    }
+
+    s->state = SEV_STATE_LAUNCHING;
+    DPRINTF("SEV: LAUNCH_START\n");
     return 0;
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 10/16] sev: add LAUNCH_UPDATE command
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (8 preceding siblings ...)
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 09/16] sev: add LAUNCH_START command Brijesh Singh
@ 2016-09-22 14:53 ` Brijesh Singh
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 11/16] sev: add LAUNCH_FINISH command Brijesh Singh
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The command is used to encrypt a guest memory region using the VM Encryption
Key (VEK) created by LAUNCH_START command. The firmware will also update
the measurement with the contents of the memory region. This measurement
can be retrieved by calling LAUNCH_FINISH command.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 sev.c |   25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/sev.c b/sev.c
index ead7c5a..dcd7c48 100644
--- a/sev.c
+++ b/sev.c
@@ -959,6 +959,25 @@ sev_launch_finish(SEVState *s)
     return 0;
 }
 
+static int
+sev_launch_update(SEVState *s, uint8_t *addr, uint32_t len)
+{
+    int ret;
+    struct kvm_sev_launch_update *data = s->launch_update;
+
+    assert(s->state == SEV_STATE_LAUNCHING);
+    data->address = (__u64)addr;
+    data->length = len;
+
+    ret = sev_ioctl(KVM_SEV_LAUNCH_UPDATE, data);
+    if (ret) {
+        return ret;
+    }
+
+    DPRINTF("SEV: LAUNCH_UPDATE %#lx+%#x\n", (unsigned long)addr, len);
+    return 0;
+}
+
 /**
  * Function returns 'true' if id is a valid QSevGuestInfo object.
  */
@@ -1056,7 +1075,11 @@ sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 
     assert(s != NULL);
 
-    // fill in the code in next patches
+    if (s->state == SEV_STATE_LAUNCHING) {
+        memcpy(dst, src, len);
+        return sev_launch_update(s, dst, len);
+    }
+
     return 0;
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 11/16] sev: add LAUNCH_FINISH command
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (9 preceding siblings ...)
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 10/16] sev: add LAUNCH_UPDATE command Brijesh Singh
@ 2016-09-22 14:53 ` Brijesh Singh
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 12/16] sev: add DEBUG_DECRYPT command Brijesh Singh
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The command is used to finalize the SEV guest launch process.

The command returns a measurement value of the data encrypted through
the LAUNCH_UPDATE command. This measurement can be handed to the guest
owner to verify that the guest was launched into SEV-enabled mode.

User can retrieve the measurement via 'measurement' property defined
in 'sev-launch-info' object.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 sev.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/sev.c b/sev.c
index dcd7c48..21c491c 100644
--- a/sev.c
+++ b/sev.c
@@ -955,7 +955,21 @@ sev_launch_start(SEVState *s)
 static int
 sev_launch_finish(SEVState *s)
 {
-    // add the command to finalize the launch in next patches
+    int ret;
+    struct kvm_sev_launch_finish *finish = s->launch_finish;
+
+    assert(s->state == SEV_STATE_LAUNCHING);
+
+    ret = sev_ioctl(KVM_SEV_LAUNCH_FINISH, finish);
+    if (ret) {
+        return -1;
+    }
+
+    DPRINTF("SEV: LAUNCH_FINISH ");
+    DPRINTF_U8_PTR(" measurement", finish->measurement,
+                   sizeof(finish->measurement));
+
+    s->state = SEV_STATE_RUNNING;
     return 0;
 }
 
@@ -1058,7 +1072,6 @@ sev_guest_launch_finish(void *handle)
 
     if (s->state == SEV_STATE_LAUNCHING) {
         return sev_launch_finish(s);
-        // use launch_finish commands
     } else if (s->state == SEV_STATE_RECEIVING) {
         // use receive_finish commands
     } else {

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 12/16] sev: add DEBUG_DECRYPT command
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (10 preceding siblings ...)
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 11/16] sev: add LAUNCH_FINISH command Brijesh Singh
@ 2016-09-22 14:53 ` Brijesh Singh
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 13/16] sev: add DEBUG_ENCRYPT command Brijesh Singh
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The command is used to decrypt a page of guest memory for debug.

See docs/amd-memory-encryption.txt for command parameters detail.

The command will be used by qemu monitor dump and gdbserver to access
the guest memory for debug purposes. A typical usage look like:

cpu_physical_memory_rw_debug
  cpu_physical_memory_rw_debug_internal
    sev_debug_decrypt

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 sev.c |   22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/sev.c b/sev.c
index 21c491c..c0f6ae4 100644
--- a/sev.c
+++ b/sev.c
@@ -1082,6 +1082,24 @@ sev_guest_launch_finish(void *handle)
 }
 
 static int
+sev_debug_decrypt(SEVState *s, uint8_t *dst, const uint8_t *src, uint32_t len)
+{
+    int ret;
+    struct kvm_sev_dbg_decrypt *dbg;
+
+    dbg = g_malloc0(sizeof(*dbg));
+    dbg->src_addr = (unsigned long)src;
+    dbg->dst_addr = (unsigned long)dst;
+    dbg->length = len;
+
+    ret = sev_ioctl(KVM_SEV_DBG_DECRYPT, dbg);
+    DPRINTF("SEV: DBG_DECRYPT src %#lx dst %#lx len %#x\n",
+            (uint64_t)src, (uint64_t)dst, len);
+    g_free(dbg);
+    return ret;
+}
+
+static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
     SEVState *s = kvm_memory_encryption_get_handle();
@@ -1102,9 +1120,9 @@ sev_mem_read(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
     SEVState *s = kvm_memory_encryption_get_handle();
 
     assert(s != NULL);
+    assert(attrs.debug || s->state != SEV_STATE_RUNNING);
 
-    // fill in the code in next patches
-    return 0;
+    return sev_debug_decrypt(s, dst, src, len);
 }
 
 void

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 13/16] sev: add DEBUG_ENCRYPT command
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (11 preceding siblings ...)
  2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 12/16] sev: add DEBUG_DECRYPT command Brijesh Singh
@ 2016-09-22 14:54 ` Brijesh Singh
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 14/16] i386: set memory encryption ops for PC.BIOS and PC.RAM regions Brijesh Singh
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

The command is used to encrypt a region of guest memory for debug.

See docs/amd-memory-encryption.txt for command parameters detail

The command will be used by gdbserver when writing the data into guest
memory for debug purposes (e.g setting breakpoint)

A typical usage looks like:
cpu_memory_rw_debug
  cpu_physical_memory_rw_debug_internal
    sev_debug_encrypt

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 sev.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/sev.c b/sev.c
index c0f6ae4..8a07c0d 100644
--- a/sev.c
+++ b/sev.c
@@ -1100,18 +1100,38 @@ sev_debug_decrypt(SEVState *s, uint8_t *dst, const uint8_t *src, uint32_t len)
 }
 
 static int
+sev_debug_encrypt(SEVState *s, uint8_t *dst, const uint8_t *src, uint32_t len)
+{
+    int ret;
+    struct kvm_sev_dbg_encrypt *dbg;
+
+    dbg = g_malloc0(sizeof(*dbg));
+    dbg->src_addr = (unsigned long)src;
+    dbg->dst_addr = (unsigned long)dst;
+    dbg->length = len;
+
+    ret = sev_ioctl(KVM_SEV_DBG_ENCRYPT, dbg);
+    DPRINTF("SEV: debug encrypt src %#lx dst %#lx len %#x\n",
+            (unsigned long)src, (unsigned long)dst, len);
+    g_free(dbg);
+
+    return ret;
+}
+
+static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
     SEVState *s = kvm_memory_encryption_get_handle();
 
     assert(s != NULL);
+    assert(attrs.debug || s->state != SEV_STATE_RUNNING);
 
     if (s->state == SEV_STATE_LAUNCHING) {
         memcpy(dst, src, len);
         return sev_launch_update(s, dst, len);
     }
 
-    return 0;
+    return sev_debug_encrypt(s, dst, src, len);
 }
 
 static int

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 14/16] i386: set memory encryption ops for PC.BIOS and PC.RAM regions
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (12 preceding siblings ...)
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 13/16] sev: add DEBUG_ENCRYPT command Brijesh Singh
@ 2016-09-22 14:54 ` Brijesh Singh
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 15/16] target-i386: add cpuid Fn8000_001f Brijesh Singh
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

If guest is launched with memory encryption enabled then register
BIOS and PC.RAM memory regions with memory encryption handler.

Registering PC.BIOS memory region will ensure that memory encryption
routines will be used when rom_reset copies the BIOS image into guest memory.

A typical sequence look like:
qemy_system_reset
  rom_reset
    cpu_physical_memory_write_rom
      cpu_phyiscal_memory_rw_debug_internal
        memory_encryption->write


Similarly registering PC.RAM region will ensure that any debug or dump
accesses from qemu monitor will go through the memory encryption routines
to decrypt/encrypt the contents.

A sequence looks like:
cpu_phyiscal_memory_rw_debug
  cpu_phyiscal_memory_rw_debug_internal
    memory_encryption->write

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 hw/i386/pc.c       |    7 +++++++
 hw/i386/pc_sysfw.c |    4 ++++
 2 files changed, 11 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 022dd1b..64bedd3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1387,6 +1387,13 @@ void pc_memory_init(PCMachineState *pcms,
         e820_add_entry(0x100000000ULL, pcms->above_4g_mem_size, E820_RAM);
     }
 
+    /* if memory encryption is enabled then set the memory encryption
+     * ops so that any read and write to guest RAM from hypervisor will
+     * go through encryption routines. */
+    if (kvm_memory_encryption_enabled()) {
+        kvm_memory_encryption_set_memory_region(ram);
+    }
+
     if (!pcmc->has_reserved_memory &&
         (machine->ram_slots ||
          (machine->maxram_size > machine->ram_size))) {
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index f915ad0..5fa40e8 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -208,6 +208,9 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
     }
     g_free(filename);
 
+    if (kvm_memory_encryption_enabled()) {
+        kvm_memory_encryption_set_memory_region(bios);
+    }
     /* map the last 128KB of the BIOS in ISA space */
     isa_bios_size = bios_size;
     if (isa_bios_size > (128 * 1024)) {
@@ -228,6 +231,7 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
     memory_region_add_subregion(rom_memory,
                                 (uint32_t)(-bios_size),
                                 bios);
+
 }
 
 void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 15/16] target-i386: add cpuid Fn8000_001f
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (13 preceding siblings ...)
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 14/16] i386: set memory encryption ops for PC.BIOS and PC.RAM regions Brijesh Singh
@ 2016-09-22 14:54 ` Brijesh Singh
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 16/16] i386: clear C-bit in SEV guest page table walk Brijesh Singh
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

Fn8000_001f cpuid provides the memory encryption (aka C-bit)

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 target-i386/cpu.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6a1afab..43e698b 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -22,6 +22,7 @@
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "sysemu/kvm.h"
+#include "sysemu/sev.h"
 #include "sysemu/cpus.h"
 #include "kvm_i386.h"
 
@@ -2192,6 +2193,10 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
     char host_vendor[CPUID_VENDOR_SZ + 1];
     FeatureWord w;
 
+    if (sev_enabled()) {
+        def->xlevel = MAX(0x8000001f, def->xlevel);
+    }
+
     object_property_set_int(OBJECT(cpu), def->level, "level", errp);
     object_property_set_int(OBJECT(cpu), def->family, "family", errp);
     object_property_set_int(OBJECT(cpu), def->model, "model", errp);
@@ -2625,6 +2630,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             *edx = 0;
         }
         break;
+    case 0x8000001F:
+        if (sev_enabled()) {
+            host_cpuid(index, 0, eax, ebx, ecx, edx);
+        }
+        break;
     case 0xC0000000:
         *eax = env->cpuid_xlevel2;
         *ebx = 0;

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [RFC PATCH v2 16/16] i386: clear C-bit in SEV guest page table walk
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (14 preceding siblings ...)
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 15/16] target-i386: add cpuid Fn8000_001f Brijesh Singh
@ 2016-09-22 14:54 ` Brijesh Singh
  2016-09-22 15:53 ` [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) no-reply
  2016-09-22 15:54 ` no-reply
  17 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 14:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

In SEV-enabled guest the physical addresses in page table will
have C-bit set, we need to clear the C-bit when walking the page table.
The C-bit position should be available in cpuid Fn8000_001f[EBX]

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 target-i386/helper.c  |   35 +++++++++++++++++++++++++++++------
 target-i386/monitor.c |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 88fa4fa..b8e9c7b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -21,6 +21,7 @@
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "sysemu/kvm.h"
+#include "sysemu/sev.h"
 #include "kvm_i386.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/sysemu.h"
@@ -1006,6 +1007,22 @@ do_check_protect_pse36:
     return 1;
 }
 
+static uint64_t get_me_mask(void)
+{
+    uint64_t me_mask = 0;
+
+    /* In SEV guest page tables addresses will have memory encryption bit set,
+     * C-bit should be cleared while doing the page table walk.
+     */
+    if (sev_enabled()) {
+        uint32_t pos;
+        pos = kvm_arch_get_supported_cpuid(kvm_state, 0x8000001f, 0, R_EBX);
+        me_mask = (1UL << pos);
+    }
+
+    return ~me_mask;
+}
+
 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     X86CPU *cpu = X86_CPU(cs);
@@ -1014,6 +1031,12 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     uint64_t pte;
     uint32_t page_offset;
     int page_size;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
+
+    /* In SEV guest, CR3 will have memory encryption bit set, clear it */
+    env->cr[3] &= me_mask;
 
     if (!(env->cr[0] & CR0_PG_MASK)) {
         pte = addr & env->a20_mask;
@@ -1034,13 +1057,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             }
             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
                 env->a20_mask;
-            pml4e = ldq_phys_debug(cs, pml4e_addr);
+            pml4e = ldq_phys_debug(cs, pml4e_addr) & me_mask;
             if (!(pml4e & PG_PRESENT_MASK)) {
                 return -1;
             }
             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
                          (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
-            pdpe = ldq_phys_debug(cs, pdpe_addr);
+            pdpe = ldq_phys_debug(cs, pdpe_addr) & me_mask;
             if (!(pdpe & PG_PRESENT_MASK)) {
                 return -1;
             }
@@ -1055,14 +1078,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         {
             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
                 env->a20_mask;
-            pdpe = ldq_phys_debug(cs, pdpe_addr);
+            pdpe = ldq_phys_debug(cs, pdpe_addr) & me_mask;
             if (!(pdpe & PG_PRESENT_MASK))
                 return -1;
         }
 
         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
                     (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
-        pde = ldq_phys_debug(cs, pde_addr);
+        pde = ldq_phys_debug(cs, pde_addr) & me_mask;
         if (!(pde & PG_PRESENT_MASK)) {
             return -1;
         }
@@ -1075,7 +1098,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             pte_addr = ((pde & PG_ADDRESS_MASK) +
                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
             page_size = 4096;
-            pte = ldq_phys_debug(cs, pte_addr);
+            pte = ldq_phys_debug(cs, pte_addr) & me_mask;
         }
         if (!(pte & PG_PRESENT_MASK)) {
             return -1;
@@ -1094,7 +1117,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
         } else {
             /* page directory entry */
             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
-            pte = ldl_phys_debug(cs, pte_addr);
+            pte = ldl_phys_debug(cs, pte_addr) & me_mask;
             if (!(pte & PG_PRESENT_MASK)) {
                 return -1;
             }
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index 47d3c2d..0fe0c03 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -27,6 +27,7 @@
 #include "monitor/hmp-target.h"
 #include "hw/i386/pc.h"
 #include "sysemu/kvm.h"
+#include "sysemu/sev.h"
 #include "hmp.h"
 
 
@@ -54,6 +55,22 @@ static void print_pte(Monitor *mon, hwaddr addr,
                    pte & PG_RW_MASK ? 'W' : '-');
 }
 
+static uint64_t get_me_mask(void)
+{
+    uint64_t me_mask = 0;
+
+    /* In SEV guest page tables addresses will have memory encryption bit set,
+     * C-bit should be cleared while doing the page table walk.
+     */
+    if (sev_enabled()) {
+        uint32_t pos;
+        pos = kvm_arch_get_supported_cpuid(kvm_state, 0x8000001f, 0, R_EBX);
+        me_mask = (1UL << pos);
+    }
+
+    return ~me_mask;
+}
+
 static void tlb_info_32(Monitor *mon, CPUArchState *env)
 {
     unsigned int l1, l2;
@@ -127,15 +144,21 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
     uint64_t l1, l2, l3, l4;
     uint64_t pml4e, pdpe, pde, pte;
     uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
+    pml4_addr &= me_mask;
     for (l1 = 0; l1 < 512; l1++) {
         cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
+        pml4e &= me_mask;
         pml4e = le64_to_cpu(pml4e);
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
                 cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
+                pdpe &= me_mask;
                 pdpe = le64_to_cpu(pdpe);
                 if (pdpe & PG_PRESENT_MASK) {
                     if (pdpe & PG_PSE_MASK) {
@@ -147,6 +170,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
                         for (l3 = 0; l3 < 512; l3++) {
                             cpu_physical_memory_read_debug(pd_addr + l3 * 8,
                                     &pde, 8);
+                            pde &= me_mask;
                             pde = le64_to_cpu(pde);
                             if (pde & PG_PRESENT_MASK) {
                                 if (pde & PG_PSE_MASK) {
@@ -160,6 +184,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
                                         cpu_physical_memory_read_debug(pt_addr
                                                                  + l4 * 8,
                                                                  &pte, 8);
+                                        pte &= me_mask;
                                         pte = le64_to_cpu(pte);
                                         if (pte & PG_PRESENT_MASK) {
                                             print_pte(mon, (l1 << 39) +
@@ -331,18 +356,24 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
     uint64_t l1, l2, l3, l4;
     uint64_t pml4e, pdpe, pde, pte;
     uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
+    pml4_addr &= me_mask;
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 512; l1++) {
         cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
+        pml4e &= me_mask;
         pml4e = le64_to_cpu(pml4e);
         end = l1 << 39;
         if (pml4e & PG_PRESENT_MASK) {
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
                 cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
+                pdpe &= me_mask;
                 pdpe = le64_to_cpu(pdpe);
                 end = (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -356,6 +387,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
                         for (l3 = 0; l3 < 512; l3++) {
                             cpu_physical_memory_read_debug(pd_addr + l3 * 8,
                                     &pde, 8);
+                            pde &= me_mask;
                             pde = le64_to_cpu(pde);
                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
                             if (pde & PG_PRESENT_MASK) {
@@ -370,6 +402,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
                                         cpu_physical_memory_read_debug(pt_addr
                                                                  + l4 * 8,
                                                                  &pte, 8);
+                                        pte &= me_mask;
                                         pte = le64_to_cpu(pte);
                                         end = (l1 << 39) + (l2 << 30) +
                                             (l3 << 21) + (l4 << 12);

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
@ 2016-09-22 15:12   ` Paolo Bonzini
  2016-09-22 21:12     ` Brijesh Singh
  2016-09-22 19:51   ` Michael S. Tsirkin
  1 sibling, 1 reply; 29+ messages in thread
From: Paolo Bonzini @ 2016-09-22 15:12 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, rth



On 22/09/2016 16:52, Brijesh Singh wrote:
>   to launch unencrypted SEV guest:
>  # $QEMU \
>     -object sev-launch-info,id=launch0,flags.ks=off \
>     -object sev-guest-info,id,sev0,launch=launch0 \
>     -object security-policy,id=secure0,memory-encryption=sev0 \
>     -machine ....,security-policy=secure0
> 
> - sev-receive-info: provides the properties to set/get parameters required
>   to launch encrypted SEV guest.
> 
>   In this mode the boot images received from the guest owner are
>   pre-encrypted with owners transport keys. The SEV guest boot process
>   would re-encrypt the images using guest owner's key.
> 
>   to launch encrypted SEV guest:
> 
>  # $QEMU \
>     -object sev-receive-info,id=launch0,flags.ks=off \
>     -object sev-guest-info,id=sev0,launch=launch0 \
>     -object security-policy,id=secure0,memory-encryption=sev0 \
>     -machine ....,security-policy=secure0
> 
> - sev-policy-info: provides properties to get/set SEV specific policy
>   parameters required by SEV launch and migrate objects.
> 
>   e.g to disable key share during encrypted launch.
>   # $QEMU \
>     -object sev-policy-info,id=policy0,ks=off \
>     -object sev-launch-info,id=sev0,policy=policy0 \
>     .....
> 
>    sev-policy should be provided by the guest owner.
> 
> - sev-guest-info: provides properties to set SEV guest launch object id
>   used during guest launch.
> 
>   to use encrypted guest launch
>   # $QEMU \
>      -object sev-receive-info,id=launch0 \
>      -object sev-send-info,id=send0 \
>      -object sev-guest-info,id=sev0,launch=launch0,send=send0 \
>      .....
> 

References to other objects should be implemented as link properties
(e.g. with type 'link<sev-guest-info>').  Then QOM takes care of filling
in a QSEVGuestInfo* with the pointer to an object with the right id.

There is some redundancy (e.g. "flags.ks" in launch/receive vs. "ks" in
policy).  Can you document the full model in
docs/amd-memory-encryption.txt?  It's not necessary to include the
kernel API documentation.

Paolo

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis Brijesh Singh
@ 2016-09-22 15:18   ` Paolo Bonzini
  2016-09-22 19:24   ` Michael S. Tsirkin
  1 sibling, 0 replies; 29+ messages in thread
From: Paolo Bonzini @ 2016-09-22 15:18 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, rth



On 22/09/2016 16:52, Brijesh Singh wrote:
> diff --git a/target-i386/monitor.c b/target-i386/monitor.c
> index fccfe40..47d3c2d 100644
> --- a/target-i386/monitor.c
> +++ b/target-i386/monitor.c
> @@ -130,12 +130,12 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
>  
>      pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
>      for (l1 = 0; l1 < 512; l1++) {
> -        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
> +        cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
>          pml4e = le64_to_cpu(pml4e);
>          if (pml4e & PG_PRESENT_MASK) {
>              pdp_addr = pml4e & 0x3fffffffff000ULL;
>              for (l2 = 0; l2 < 512; l2++) {
> -                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
> +                cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
>                  pdpe = le64_to_cpu(pdpe);
>                  if (pdpe & PG_PRESENT_MASK) {
>                      if (pdpe & PG_PSE_MASK) {

Please use ldq_phys_debug instead here and in mem_info_64.

Paolo

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis Brijesh Singh
@ 2016-09-22 15:21   ` Paolo Bonzini
  0 siblings, 0 replies; 29+ messages in thread
From: Paolo Bonzini @ 2016-09-22 15:21 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, rth



On 22/09/2016 16:52, Brijesh Singh wrote:
> The patch adds the following new APIs:
> - cpu_physical_memory_read_debug
> - cpu_physical_memory_write_debug
> - cpu_physical_memory_rw_debug
> - ldl_phys_debug
> - ldq_phys_debug
> 
> The idea behind this patch is that if all the qemu monitor memory dumps
> and gdbserver accesses are done through these common APIs then in future
> we can define some kind of global debug policy to control debug behavior.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> ---
>  exec.c                    |   32 ++++++++++++++++++++++++++++++++
>  include/exec/cpu-common.h |   15 +++++++++++++++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/exec.c b/exec.c
> index 0989933..9d0128e 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -3105,6 +3105,30 @@ uint32_t ldl_phys(AddressSpace *as, hwaddr addr)
>      return address_space_ldl(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
>  }
>  
> +uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr)
> +{
> +    MemTxAttrs attrs = MEMTXATTRS_DEBUG;
> +    int asidx = cpu_asidx_from_attrs(cpu, attrs);
> +    uint32_t val;
> +
> +    cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
> +                                          addr, (void *) &val,
> +                                          4, attrs, READ_DATA);
> +    return tswap32(val);
> +}
> +
> +uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr)
> +{
> +    MemTxAttrs attrs = MEMTXATTRS_DEBUG;
> +    int asidx = cpu_asidx_from_attrs(cpu, attrs);
> +    uint64_t val;
> +
> +    cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
> +                                          addr, (void *) &val,
> +                                          8, attrs, READ_DATA);
> +    return val;
> +}
> +
>  uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr)
>  {
>      return address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
> @@ -3615,6 +3639,14 @@ void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val)
>      address_space_stq_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
>  }
>  
> +void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
> +                                  int len, int is_write)
> +{
> +    cpu_physical_memory_rw_debug_internal(&address_space_memory, addr,
> +                                          buf, len, MEMTXATTRS_DEBUG,
> +                                          is_write ? WRITE_DATA : READ_DATA);
> +}
> +
>  /* virtual memory access for debug (includes writing to ROM) */
>  int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>                          uint8_t *buf, int len, int is_write)
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index 520dae0..90598d4 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -61,6 +61,8 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
>  
>  void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
>                              int len, int is_write);
> +void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
> +                                  int len, int is_write);
>  static inline void cpu_physical_memory_read(hwaddr addr,
>                                              void *buf, int len)
>  {
> @@ -71,6 +73,19 @@ static inline void cpu_physical_memory_write(hwaddr addr,
>  {
>      cpu_physical_memory_rw(addr, (void *)buf, len, 1);
>  }
> +static inline void cpu_physical_memory_read_debug(hwaddr addr,
> +                                                  void *buf, int len)
> +{
> +    cpu_physical_memory_rw_debug(addr, buf, len, 0);
> +}
> +static inline void cpu_physical_memory_write_debug(hwaddr addr,
> +                                                   const void *buf, int len)
> +{
> +    cpu_physical_memory_rw_debug(addr, (void *)buf, len, 1);
> +}
> +uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr);
> +uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr);
> +
>  void *cpu_physical_memory_map(hwaddr addr,
>                                hwaddr *plen,
>                                int is_write);
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops Brijesh Singh
@ 2016-09-22 15:22   ` Paolo Bonzini
  0 siblings, 0 replies; 29+ messages in thread
From: Paolo Bonzini @ 2016-09-22 15:22 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, rth



On 22/09/2016 16:52, Brijesh Singh wrote:
>  void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
> -                                   const uint8_t *buf, int len)
> +                                   uint8_t *buf, int len)

The const is correct, please cast it away below.

>  {
> -    cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
> +    cpu_physical_memory_rw_debug_internal(as, addr, buf, len,
> +            MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
>  }


>  struct MemoryRegionIOMMUOps {
> @@ -179,6 +191,7 @@ struct MemoryRegion {
>      RAMBlock *ram_block;
>      Object *owner;
>      const MemoryRegionIOMMUOps *iommu_ops;
> +    const MemoryRegionRAMReadWriteOps *ram_ops;
>  
>      const MemoryRegionOps *ops;
>      void *opaque;

The beginning of MemoryRegion is packed to fit in a cache line, please
move this towards the end.

Also please change ram_ops to ram_debug_ops.  Otherwise looks good.

Paolo

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm'
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm' Brijesh Singh
@ 2016-09-22 15:32   ` Eric Blake
  0 siblings, 0 replies; 29+ messages in thread
From: Eric Blake @ 2016-09-22 15:32 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth

[-- Attachment #1: Type: text/plain, Size: 1237 bytes --]

On 09/22/2016 09:52 AM, Brijesh Singh wrote:
> update 'info kvm' to display the memory encryption support.
> 
> (qemu) info kvm
> kvm support: enabled
> memory encryption: disabled
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---

> +++ b/qapi-schema.json
> @@ -99,9 +99,12 @@
>  #
>  # @present: true if KVM acceleration is built into this executable
>  #
> -# Since: 0.14.0
> +# @mem_encryption: true if Memory Encryption is active
> +#
> +# Since: 2.8.0

Not quite right.  The KvmInfo struct is still since 0.14.0, only the
mem_encryption member is new.  And new members should be spelled with
'-' rather than '_', if there is no other '_' in the struct.

So you want:

# @present: true if KVM acceleration is built into this executable
#
# @mem-encryption: true if Memory Encryption is active (since 2.8)
#
# Since: 0.14.0

>  ##
> -{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
> +{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool',
> +            'mem_encryption' : 'bool'} }

and with the corresponding spelling fix here.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD)
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (15 preceding siblings ...)
  2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 16/16] i386: clear C-bit in SEV guest page table walk Brijesh Singh
@ 2016-09-22 15:53 ` no-reply
  2016-09-22 15:54 ` no-reply
  17 siblings, 0 replies; 29+ messages in thread
From: no-reply @ 2016-09-22 15:53 UTC (permalink / raw)
  To: brijesh.singh
  Cc: famz, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth

Hi,

Your series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 147455590865.8519.11191009507297313736.stgit@brijesh-build-machine
Subject: [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD)

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
make J=8 docker-test-quick@centos6
make J=8 docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/147455590865.8519.11191009507297313736.stgit@brijesh-build-machine -> patchew/147455590865.8519.11191009507297313736.stgit@brijesh-build-machine
Switched to a new branch 'test'
850cc25 i386: clear C-bit in SEV guest page table walk
118801a target-i386: add cpuid Fn8000_001f
0a1150c i386: set memory encryption ops for PC.BIOS and PC.RAM regions
cc8e566 sev: add DEBUG_ENCRYPT command
7a078d0 sev: add DEBUG_DECRYPT command
86d0fa9 sev: add LAUNCH_FINISH command
2fab8c2 sev: add LAUNCH_UPDATE command
1786fb6 sev: add LAUNCH_START command
0b20533 core: loader: create memory encryption context before copying data
9d4475b hmp: display memory encryption support in 'info kvm'
a3a62fd sev: add Secure Encrypted Virtulization (SEV) support
405efda core: add new security-policy object
3d2db73 monitor: use debug version of memory access apis
bcb1584 exec: add debug version of physical memory read and write apis
ef720ae exec: add guest RAM read and write ops
bcdc107 memattrs: add debug attrs

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf'
  BUILD centos6
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY RUNNER
  RUN test-quick in centos6
No C++ compiler available; disabling C++ specific optional code
Install prefix    /tmp/qemu-test/src/tests/docker/install
BIOS directory    /tmp/qemu-test/src/tests/docker/install/share/qemu
binary directory  /tmp/qemu-test/src/tests/docker/install/bin
library directory /tmp/qemu-test/src/tests/docker/install/lib
module directory  /tmp/qemu-test/src/tests/docker/install/lib/qemu
libexec directory /tmp/qemu-test/src/tests/docker/install/libexec
include directory /tmp/qemu-test/src/tests/docker/install/include
config directory  /tmp/qemu-test/src/tests/docker/install/etc
local state directory   /tmp/qemu-test/src/tests/docker/install/var
Manual directory  /tmp/qemu-test/src/tests/docker/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
uuid support      no
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
vhdx              no
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
  GEN   x86_64-softmmu/config-devices.mak.tmp
  GEN   aarch64-softmmu/config-devices.mak.tmp
  GEN   config-host.h
  GEN   qemu-options.def
  GEN   qmp-commands.h
  GEN   qapi-types.h
  GEN   qapi-visit.h
  GEN   qapi-event.h
  GEN   x86_64-softmmu/config-devices.mak
  GEN   aarch64-softmmu/config-devices.mak
  GEN   qmp-introspect.h
  GEN   module_block.h
  GEN   tests/test-qapi-types.h
  GEN   tests/test-qapi-visit.h
  GEN   tests/test-qmp-commands.h
  GEN   tests/test-qapi-event.h
  GEN   tests/test-qmp-introspect.h
  GEN   config-all-devices.mak
  GEN   trace/generated-events.h
  GEN   trace/generated-tracers.h
  GEN   trace/generated-tcg-tracers.h
  GEN   trace/generated-helpers-wrappers.h
  GEN   trace/generated-helpers.h
  CC    tests/qemu-iotests/socket_scm_helper.o
  GEN   qga/qapi-generated/qga-qapi-types.h
  GEN   qga/qapi-generated/qga-qapi-visit.h
  GEN   qga/qapi-generated/qga-qmp-commands.h
  GEN   qga/qapi-generated/qga-qapi-types.c
  GEN   qga/qapi-generated/qga-qapi-visit.c
  GEN   qga/qapi-generated/qga-qmp-marshal.c
  GEN   qmp-introspect.c
  GEN   qapi-types.c
  GEN   qapi-visit.c
  GEN   qapi-event.c
  CC    qapi/qapi-visit-core.o
  CC    qapi/qapi-dealloc-visitor.o
  CC    qapi/qmp-input-visitor.o
  CC    qapi/qmp-output-visitor.o
  CC    qapi/qmp-registry.o
  CC    qapi/qmp-dispatch.o
  CC    qapi/string-input-visitor.o
  CC    qapi/string-output-visitor.o
  CC    qapi/opts-visitor.o
  CC    qapi/qapi-clone-visitor.o
  CC    qapi/qmp-event.o
  CC    qapi/qapi-util.o
  CC    qobject/qnull.o
  CC    qobject/qint.o
  CC    qobject/qstring.o
  CC    qobject/qdict.o
  CC    qobject/qlist.o
  CC    qobject/qfloat.o
  CC    qobject/qbool.o
  CC    qobject/qjson.o
  CC    qobject/qobject.o
  CC    qobject/json-lexer.o
  CC    qobject/json-streamer.o
  CC    qobject/json-parser.o
  GEN   trace/generated-events.c
  CC    trace/control.o
  CC    trace/qmp.o
  CC    util/osdep.o
  CC    util/cutils.o
  CC    util/unicode.o
  CC    util/qemu-timer-common.o
  CC    util/bufferiszero.o
  CC    util/compatfd.o
  CC    util/event_notifier-posix.o
  CC    util/mmap-alloc.o
  CC    util/oslib-posix.o
  CC    util/qemu-openpty.o
  CC    util/qemu-thread-posix.o
  CC    util/memfd.o
  CC    util/envlist.o
  CC    util/path.o
  CC    util/module.o
  CC    util/bitmap.o
  CC    util/bitops.o
  CC    util/hbitmap.o
  CC    util/fifo8.o
  CC    util/acl.o
  CC    util/error.o
  CC    util/qemu-error.o
  CC    util/id.o
  CC    util/iov.o
  CC    util/qemu-config.o
  CC    util/qemu-sockets.o
  CC    util/uri.o
  CC    util/notify.o
  CC    util/qemu-option.o
  CC    util/qemu-progress.o
  CC    util/hexdump.o
  CC    util/crc32c.o
  CC    util/throttle.o
  CC    util/getauxval.o
  CC    util/readline.o
  CC    util/rfifolock.o
  CC    util/rcu.o
  CC    util/qemu-coroutine.o
  CC    util/qemu-coroutine-lock.o
  CC    util/qemu-coroutine-io.o
  CC    util/qemu-coroutine-sleep.o
  CC    util/coroutine-ucontext.o
  CC    util/buffer.o
  CC    util/timed-average.o
  CC    util/base64.o
  CC    util/log.o
  CC    util/qdist.o
  CC    util/qht.o
  CC    util/range.o
  CC    crypto/pbkdf-stub.o
  CC    stubs/arch-query-cpu-def.o
  CC    stubs/arch-query-cpu-model-expansion.o
  CC    stubs/arch-query-cpu-model-comparison.o
  CC    stubs/arch-query-cpu-model-baseline.o
  CC    stubs/bdrv-next-monitor-owned.o
  CC    stubs/blk-commit-all.o
  CC    stubs/blockdev-close-all-bdrv-states.o
/tmp/qemu-test/src/util/qht.c: In function ‘qht_reset_size’:
/tmp/qemu-test/src/util/qht.c:413: warning: ‘new’ may be used uninitialized in this function
  CC    stubs/clock-warp.o
  CC    stubs/cpu-get-clock.o
  CC    stubs/cpu-get-icount.o
  CC    stubs/dump.o
  CC    stubs/fdset-add-fd.o
  CC    stubs/fdset-find-fd.o
  CC    stubs/fdset-get-fd.o
  CC    stubs/fdset-remove-fd.o
  CC    stubs/gdbstub.o
  CC    stubs/get-fd.o
  CC    stubs/get-next-serial.o
  CC    stubs/get-vm-name.o
  CC    stubs/iothread-lock.o
  CC    stubs/is-daemonized.o
  CC    stubs/machine-init-done.o
  CC    stubs/migr-blocker.o
  CC    stubs/mon-is-qmp.o
  CC    stubs/mon-printf.o
  CC    stubs/monitor-init.o
  CC    stubs/notify-event.o
  CC    stubs/qtest.o
  CC    stubs/replay.o
  CC    stubs/replay-user.o
  CC    stubs/reset.o
  CC    stubs/runstate-check.o
  CC    stubs/set-fd-handler.o
  CC    stubs/slirp.o
  CC    stubs/sysbus.o
  CC    stubs/trace-control.o
  CC    stubs/uuid.o
  CC    stubs/vm-stop.o
  CC    stubs/vmstate.o
  CC    stubs/cpus.o
  CC    stubs/kvm.o
  CC    stubs/qmp_pc_dimm_device_list.o
  CC    stubs/target-monitor-defs.o
  CC    stubs/target-get-monitor-def.o
  CC    stubs/vhost.o
  CC    stubs/iohandler.o
  CC    stubs/smbios_type_38.o
  CC    stubs/ipmi.o
  CC    stubs/pc_madt_cpu_entry.o
  CC    contrib/ivshmem-client/ivshmem-client.o
  CC    contrib/ivshmem-client/main.o
  CC    contrib/ivshmem-server/ivshmem-server.o
  CC    contrib/ivshmem-server/main.o
  CC    qemu-nbd.o
  CC    async.o
  CC    thread-pool.o
  CC    block.o
  CC    blockjob.o
  CC    main-loop.o
  CC    iohandler.o
  CC    qemu-timer.o
  CC    aio-posix.o
  CC    qemu-io-cmds.o
  CC    replication.o
  CC    block/raw_bsd.o
  CC    block/qcow.o
  CC    block/vdi.o
  CC    block/vmdk.o
  CC    block/cloop.o
  CC    block/bochs.o
  CC    block/vpc.o
  CC    block/vvfat.o
  CC    block/dmg.o
  CC    block/qcow2.o
  CC    block/qcow2-refcount.o
  CC    block/qcow2-cluster.o
  CC    block/qcow2-snapshot.o
  CC    block/qcow2-cache.o
  CC    block/qed.o
  CC    block/qed-gencb.o
  CC    block/qed-l2-cache.o
  CC    block/qed-table.o
  CC    block/qed-cluster.o
  CC    block/qed-check.o
  CC    block/quorum.o
  CC    block/parallels.o
  CC    block/blkdebug.o
  CC    block/blkverify.o
  CC    block/blkreplay.o
  CC    block/block-backend.o
  CC    block/snapshot.o
  CC    block/qapi.o
  CC    block/raw-posix.o
  CC    block/null.o
  CC    block/mirror.o
  CC    block/commit.o
  CC    block/io.o
  CC    block/throttle-groups.o
  CC    block/nbd.o
  CC    block/nbd-client.o
  CC    block/sheepdog.o
  CC    block/accounting.o
  CC    block/dirty-bitmap.o
  CC    block/write-threshold.o
  CC    block/backup.o
  CC    block/replication.o
  CC    block/crypto.o
  CC    nbd/server.o
  CC    nbd/client.o
  CC    nbd/common.o
  CC    crypto/init.o
  CC    crypto/hash.o
  CC    crypto/hash-glib.o
  CC    crypto/aes.o
  CC    crypto/desrfb.o
  CC    crypto/cipher.o
  CC    crypto/tlscreds.o
  CC    crypto/tlscredsanon.o
  CC    crypto/tlscredsx509.o
  CC    crypto/tlssession.o
  CC    crypto/secret.o
  CC    crypto/random-platform.o
  CC    crypto/pbkdf.o
  CC    crypto/ivgen.o
  CC    crypto/ivgen-essiv.o
  CC    crypto/ivgen-plain.o
  CC    crypto/ivgen-plain64.o
  CC    crypto/afsplit.o
  CC    crypto/xts.o
  CC    crypto/block.o
  CC    crypto/block-qcow.o
  CC    crypto/block-luks.o
  CC    io/channel.o
  CC    io/channel-buffer.o
  CC    io/channel-command.o
  CC    io/channel-file.o
  CC    io/channel-socket.o
  CC    io/channel-tls.o
  CC    io/channel-watch.o
  CC    io/channel-websock.o
  CC    io/channel-util.o
  CC    io/task.o
  CC    qom/object.o
  CC    qom/container.o
  CC    qom/qom-qobject.o
  CC    qom/object_interfaces.o
  GEN   qemu-img-cmds.h
  CC    qemu-io.o
  CC    qemu-bridge-helper.o
  CC    blockdev.o
  CC    blockdev-nbd.o
  CC    iothread.o
  CC    qdev-monitor.o
  CC    device-hotplug.o
  CC    os-posix.o
  CC    qemu-char.o
  CC    page_cache.o
  CC    accel.o
  CC    bt-host.o
  CC    bt-vhci.o
  CC    dma-helpers.o
  CC    vl.o
  CC    tpm.o
  CC    device_tree.o
  GEN   qmp-marshal.c
  CC    qmp.o
  CC    hmp.o
  CC    tcg-runtime.o
  CC    audio/audio.o
  CC    audio/noaudio.o
  CC    audio/wavaudio.o
  CC    audio/mixeng.o
  CC    audio/sdlaudio.o
  CC    audio/ossaudio.o
  CC    audio/wavcapture.o
  CC    backends/rng.o
  CC    backends/rng-egd.o
  CC    backends/rng-random.o
  CC    backends/msmouse.o
  CC    backends/testdev.o
  CC    backends/tpm.o
  CC    backends/hostmem.o
  CC    backends/hostmem-ram.o
  CC    backends/hostmem-file.o
  CC    block/stream.o
  CC    disas/arm.o
  CC    disas/i386.o
  CC    fsdev/qemu-fsdev-dummy.o
  CC    fsdev/qemu-fsdev-opts.o
  CC    hw/acpi/core.o
  CC    hw/acpi/piix4.o
  CC    hw/acpi/pcihp.o
  CC    hw/acpi/ich9.o
  CC    hw/acpi/tco.o
  CC    hw/acpi/cpu_hotplug.o
  CC    hw/acpi/memory_hotplug.o
  CC    hw/acpi/memory_hotplug_acpi_table.o
  CC    hw/acpi/cpu.o
  CC    hw/acpi/acpi_interface.o
  CC    hw/acpi/bios-linker-loader.o
  CC    hw/acpi/aml-build.o
  CC    hw/acpi/ipmi.o
  CC    hw/audio/sb16.o
  CC    hw/audio/es1370.o
  CC    hw/audio/ac97.o
  CC    hw/audio/fmopl.o
  CC    hw/audio/adlib.o
  CC    hw/audio/gus.o
  CC    hw/audio/gusemu_hal.o
  CC    hw/audio/gusemu_mixer.o
  CC    hw/audio/cs4231a.o
  CC    hw/audio/intel-hda.o
  CC    hw/audio/hda-codec.o
  CC    hw/audio/pcspk.o
  CC    hw/audio/wm8750.o
  CC    hw/audio/pl041.o
  CC    hw/audio/lm4549.o
  CC    hw/block/block.o
  CC    hw/audio/marvell_88w8618.o
  CC    hw/block/cdrom.o
  CC    hw/block/hd-geometry.o
  CC    hw/block/fdc.o
  CC    hw/block/m25p80.o
  CC    hw/block/nand.o
  CC    hw/block/pflash_cfi01.o
  CC    hw/block/pflash_cfi02.o
  CC    hw/block/ecc.o
  CC    hw/block/onenand.o
  CC    hw/block/nvme.o
  CC    hw/bt/core.o
  CC    hw/bt/l2cap.o
  CC    hw/bt/sdp.o
  CC    hw/bt/hci.o
  CC    hw/bt/hid.o
  CC    hw/bt/hci-csr.o
  CC    hw/char/ipoctal232.o
  CC    hw/char/parallel.o
  CC    hw/char/pl011.o
  CC    hw/char/serial.o
  CC    hw/char/serial-isa.o
  CC    hw/char/serial-pci.o
  CC    hw/char/virtio-console.o
  CC    hw/char/cadence_uart.o
  CC    hw/char/debugcon.o
  CC    hw/char/imx_serial.o
  CC    hw/core/qdev.o
  CC    hw/core/qdev-properties.o
  CC    hw/core/bus.o
  CC    hw/core/fw-path-provider.o
  CC    hw/core/irq.o
  CC    hw/core/hotplug.o
  CC    hw/core/ptimer.o
  CC    hw/core/sysbus.o
  CC    hw/core/machine.o
  CC    hw/core/null-machine.o
  CC    hw/core/loader.o
  CC    hw/core/qdev-properties-system.o
  CC    hw/core/register.o
  CC    hw/core/security-policy.o
  CC    hw/core/platform-bus.o
  CC    hw/display/ads7846.o
  CC    hw/display/cirrus_vga.o
  CC    hw/display/pl110.o
  CC    hw/display/ssd0303.o
  CC    hw/display/ssd0323.o
  CC    hw/display/vga-pci.o
  CC    hw/display/vga-isa.o
  CC    hw/display/vmware_vga.o
  CC    hw/display/blizzard.o
  CC    hw/display/exynos4210_fimd.o
  CC    hw/display/framebuffer.o
  CC    hw/display/tc6393xb.o
  CC    hw/dma/pl080.o
  CC    hw/dma/pl330.o
  CC    hw/dma/i8257.o
  CC    hw/dma/xlnx-zynq-devcfg.o
  CC    hw/gpio/max7310.o
  CC    hw/gpio/pl061.o
  CC    hw/gpio/zaurus.o
  CC    hw/gpio/gpio_key.o
  CC    hw/i2c/core.o
  CC    hw/i2c/smbus.o
  CC    hw/i2c/smbus_eeprom.o
  CC    hw/i2c/i2c-ddc.o
  CC    hw/i2c/versatile_i2c.o
  CC    hw/i2c/smbus_ich9.o
  CC    hw/i2c/pm_smbus.o
  CC    hw/i2c/bitbang_i2c.o
  CC    hw/i2c/exynos4210_i2c.o
  CC    hw/i2c/imx_i2c.o
  CC    hw/i2c/aspeed_i2c.o
  CC    hw/ide/core.o
  CC    hw/ide/atapi.o
  CC    hw/ide/qdev.o
  CC    hw/ide/pci.o
  CC    hw/ide/isa.o
  CC    hw/ide/piix.o
  CC    hw/ide/microdrive.o
  CC    hw/ide/ahci.o
  CC    hw/ide/ich.o
  CC    hw/input/hid.o
  CC    hw/input/lm832x.o
  CC    hw/input/pckbd.o
  CC    hw/input/pl050.o
  CC    hw/input/ps2.o
  CC    hw/input/stellaris_input.o
  CC    hw/input/tsc2005.o
  CC    hw/input/vmmouse.o
  CC    hw/input/virtio-input.o
  CC    hw/input/virtio-input-hid.o
  CC    hw/input/virtio-input-host.o
  CC    hw/intc/i8259_common.o
  CC    hw/intc/i8259.o
  CC    hw/intc/pl190.o
  CC    hw/intc/imx_avic.o
  CC    hw/intc/realview_gic.o
  CC    hw/intc/ioapic_common.o
  CC    hw/intc/arm_gic_common.o
  CC    hw/intc/arm_gic.o
  CC    hw/intc/arm_gicv2m.o
  CC    hw/intc/arm_gicv3_common.o
  CC    hw/intc/arm_gicv3.o
  CC    hw/intc/arm_gicv3_dist.o
  CC    hw/intc/arm_gicv3_redist.o
  CC    hw/ipack/ipack.o
  CC    hw/ipack/tpci200.o
  CC    hw/ipmi/ipmi.o
  CC    hw/ipmi/ipmi_bmc_sim.o
  CC    hw/ipmi/ipmi_bmc_extern.o
  CC    hw/ipmi/isa_ipmi_kcs.o
  CC    hw/ipmi/isa_ipmi_bt.o
  CC    hw/isa/isa-bus.o
  CC    hw/isa/apm.o
  CC    hw/mem/pc-dimm.o
  CC    hw/mem/nvdimm.o
  CC    hw/misc/applesmc.o
  CC    hw/misc/max111x.o
  CC    hw/misc/tmp105.o
  CC    hw/misc/debugexit.o
  CC    hw/misc/sga.o
  CC    hw/misc/pc-testdev.o
  CC    hw/misc/pci-testdev.o
  CC    hw/misc/arm_l2x0.o
  CC    hw/misc/arm_integrator_debug.o
  CC    hw/misc/a9scu.o
  CC    hw/misc/arm11scu.o
  CC    hw/net/ne2000.o
  CC    hw/net/eepro100.o
  CC    hw/net/pcnet-pci.o
  CC    hw/net/pcnet.o
  CC    hw/net/e1000.o
  CC    hw/net/e1000x_common.o
  CC    hw/net/net_tx_pkt.o
  CC    hw/net/net_rx_pkt.o
  CC    hw/net/e1000e.o
  CC    hw/net/e1000e_core.o
  CC    hw/net/rtl8139.o
  CC    hw/net/vmxnet3.o
  CC    hw/net/smc91c111.o
  CC    hw/net/lan9118.o
  CC    hw/net/ne2000-isa.o
  CC    hw/net/xgmac.o
  CC    hw/net/allwinner_emac.o
  CC    hw/net/imx_fec.o
  CC    hw/net/cadence_gem.o
  CC    hw/net/stellaris_enet.o
  CC    hw/net/rocker/rocker.o
  CC    hw/net/rocker/rocker_fp.o
  CC    hw/net/rocker/rocker_desc.o
  CC    hw/net/rocker/rocker_world.o
  CC    hw/net/rocker/rocker_of_dpa.o
  CC    hw/nvram/eeprom93xx.o
  CC    hw/nvram/fw_cfg.o
  CC    hw/pci-bridge/pci_bridge_dev.o
  CC    hw/pci-bridge/pci_expander_bridge.o
  CC    hw/pci-bridge/xio3130_upstream.o
  CC    hw/pci-bridge/xio3130_downstream.o
  CC    hw/pci-bridge/ioh3420.o
  CC    hw/pci-bridge/i82801b11.o
  CC    hw/pci-host/pam.o
  CC    hw/pci-host/versatile.o
  CC    hw/pci-host/piix.o
  CC    hw/pci-host/q35.o
  CC    hw/pci-host/gpex.o
  CC    hw/pci/pci.o
  CC    hw/pci/pci_bridge.o
  CC    hw/pci/msix.o
/tmp/qemu-test/src/hw/nvram/fw_cfg.c: In function ‘fw_cfg_dma_transfer’:
/tmp/qemu-test/src/hw/nvram/fw_cfg.c:330: warning: ‘read’ may be used uninitialized in this function
  CC    hw/pci/msi.o
  CC    hw/pci/shpc.o
  CC    hw/pci/slotid_cap.o
  CC    hw/pci/pci_host.o
  CC    hw/pci/pcie_host.o
  CC    hw/pci/pcie.o
  CC    hw/pci/pcie_aer.o
  CC    hw/pci/pcie_port.o
  CC    hw/pci/pci-stub.o
  CC    hw/pcmcia/pcmcia.o
  CC    hw/scsi/scsi-disk.o
  CC    hw/scsi/scsi-generic.o
  CC    hw/scsi/scsi-bus.o
  CC    hw/scsi/lsi53c895a.o
  CC    hw/scsi/mptsas.o
  CC    hw/scsi/mptconfig.o
  CC    hw/scsi/mptendian.o
  CC    hw/scsi/megasas.o
  CC    hw/scsi/vmw_pvscsi.o
  CC    hw/scsi/esp.o
  CC    hw/scsi/esp-pci.o
  CC    hw/sd/pl181.o
  CC    hw/sd/ssi-sd.o
  CC    hw/sd/sd.o
  CC    hw/sd/core.o
  CC    hw/sd/sdhci.o
  CC    hw/smbios/smbios.o
  CC    hw/smbios/smbios_type_38.o
  CC    hw/ssi/pl022.o
  CC    hw/ssi/ssi.o
  CC    hw/ssi/xilinx_spips.o
  CC    hw/ssi/aspeed_smc.o
  CC    hw/timer/arm_timer.o
  CC    hw/timer/arm_mptimer.o
  CC    hw/timer/a9gtimer.o
  CC    hw/timer/cadence_ttc.o
  CC    hw/timer/ds1338.o
  CC    hw/timer/hpet.o
  CC    hw/timer/i8254_common.o
  CC    hw/timer/i8254.o
  CC    hw/timer/pl031.o
  CC    hw/timer/twl92230.o
  CC    hw/timer/imx_epit.o
  CC    hw/timer/imx_gpt.o
  CC    hw/timer/stm32f2xx_timer.o
  CC    hw/timer/aspeed_timer.o
  CC    hw/tpm/tpm_tis.o
  CC    hw/tpm/tpm_passthrough.o
  CC    hw/tpm/tpm_util.o
  CC    hw/usb/core.o
  CC    hw/usb/combined-packet.o
  CC    hw/usb/bus.o
  CC    hw/usb/libhw.o
  CC    hw/usb/desc.o
  CC    hw/usb/desc-msos.o
  CC    hw/usb/hcd-uhci.o
  CC    hw/usb/hcd-ohci.o
  CC    hw/usb/hcd-ehci.o
  CC    hw/usb/hcd-ehci-pci.o
  CC    hw/usb/hcd-ehci-sysbus.o
  CC    hw/usb/hcd-xhci.o
  CC    hw/usb/hcd-musb.o
  CC    hw/usb/dev-hub.o
  CC    hw/usb/dev-hid.o
  CC    hw/usb/dev-wacom.o
  CC    hw/usb/dev-storage.o
  CC    hw/usb/dev-uas.o
  CC    hw/usb/dev-audio.o
  CC    hw/usb/dev-serial.o
  CC    hw/usb/dev-network.o
  CC    hw/usb/dev-bluetooth.o
  CC    hw/usb/dev-smartcard-reader.o
  CC    hw/usb/dev-mtp.o
  CC    hw/usb/host-stub.o
  CC    hw/virtio/virtio-rng.o
  CC    hw/virtio/virtio-pci.o
  CC    hw/virtio/virtio-bus.o
  CC    hw/virtio/virtio-mmio.o
  CC    hw/watchdog/watchdog.o
  CC    hw/watchdog/wdt_i6300esb.o
  CC    hw/watchdog/wdt_ib700.o
  CC    migration/migration.o
  CC    migration/socket.o
  CC    migration/fd.o
  CC    migration/exec.o
  CC    migration/tls.o
  CC    migration/vmstate.o
  CC    migration/qemu-file.o
  CC    migration/qemu-file-channel.o
  CC    migration/xbzrle.o
  CC    migration/postcopy-ram.o
  CC    migration/qjson.o
  CC    migration/block.o
  CC    net/net.o
  CC    net/queue.o
  CC    net/checksum.o
  CC    net/util.o
  CC    net/hub.o
  CC    net/socket.o
  CC    net/dump.o
  CC    net/eth.o
  CC    net/l2tpv3.o
  CC    net/tap.o
  CC    net/vhost-user.o
  CC    net/tap-linux.o
  CC    net/slirp.o
  CC    net/filter.o
  CC    net/filter-buffer.o
  CC    net/filter-mirror.o
  CC    qom/cpu.o
  CC    replay/replay.o
  CC    replay/replay-internal.o
  CC    replay/replay-events.o
  CC    replay/replay-time.o
  CC    replay/replay-input.o
  CC    replay/replay-char.o
  CC    slirp/cksum.o
  CC    slirp/if.o
  CC    slirp/ip_icmp.o
  CC    slirp/ip6_icmp.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:68: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  CC    slirp/ip6_input.o
  CC    slirp/ip6_output.o
  CC    slirp/ip_input.o
  CC    slirp/ip_output.o
  CC    slirp/dnssearch.o
  CC    slirp/dhcpv6.o
  CC    slirp/slirp.o
  CC    slirp/mbuf.o
  CC    slirp/misc.o
  CC    slirp/sbuf.o
  CC    slirp/socket.o
  CC    slirp/tcp_input.o
  CC    slirp/tcp_output.o
  CC    slirp/tcp_subr.o
  CC    slirp/tcp_timer.o
  CC    slirp/udp.o
  CC    slirp/udp6.o
  CC    slirp/bootp.o
  CC    slirp/tftp.o
  CC    slirp/arp_table.o
  CC    slirp/ndp_table.o
  CC    ui/keymaps.o
/tmp/qemu-test/src/slirp/tcp_input.c: In function ‘tcp_input’:
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_p’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_len’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_tos’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_id’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_off’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_ttl’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_sum’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_src.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_dst.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:220: warning: ‘save_ip6.ip_nh’ may be used uninitialized in this function
  CC    ui/console.o
  CC    ui/cursor.o
  CC    ui/qemu-pixman.o
  CC    ui/input.o
  CC    ui/input-keymap.o
  CC    ui/input-legacy.o
  CC    ui/input-linux.o
  CC    ui/sdl.o
  CC    ui/sdl_zoom.o
  CC    ui/x_keymap.o
  CC    ui/vnc.o
  CC    ui/vnc-enc-zlib.o
  CC    ui/vnc-enc-hextile.o
  CC    ui/vnc-enc-tight.o
  CC    ui/vnc-palette.o
  CC    ui/vnc-enc-zrle.o
  CC    ui/vnc-auth-vencrypt.o
  CC    ui/vnc-ws.o
  CC    ui/vnc-jobs.o
  AS    optionrom/multiboot.o
  AS    optionrom/linuxboot.o
  CC    optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
  AS    optionrom/kvmvapic.o
  LINK  tests/qemu-iotests/socket_scm_helper
  Building optionrom/multiboot.img
  Building optionrom/linuxboot.img
  Building optionrom/linuxboot_dma.img
  Building optionrom/kvmvapic.img
  CC    qga/commands.o
  Building optionrom/multiboot.raw
  Building optionrom/linuxboot.raw
  Building optionrom/linuxboot_dma.raw
  CC    qga/guest-agent-command-state.o
  Building optionrom/kvmvapic.raw
  Signing optionrom/multiboot.bin
  Signing optionrom/linuxboot.bin
  Signing optionrom/linuxboot_dma.bin
  Signing optionrom/kvmvapic.bin
  CC    qga/main.o
  CC    qga/commands-posix.o
  CC    qga/channel-posix.o
  CC    qga/qapi-generated/qga-qapi-types.o
  CC    qga/qapi-generated/qga-qapi-visit.o
  CC    qga/qapi-generated/qga-qmp-marshal.o
  CC    qmp-introspect.o
  CC    qapi-types.o
  CC    qapi-visit.o
  CC    qapi-event.o
  AR    libqemustub.a
  CC    qemu-img.o
  CC    qmp-marshal.o
  CC    trace/generated-events.o
  AR    libqemuutil.a
  LINK  qemu-ga
  LINK  ivshmem-client
  LINK  ivshmem-server
  LINK  qemu-nbd
  LINK  qemu-img
  LINK  qemu-io
  LINK  qemu-bridge-helper
  GEN   x86_64-softmmu/hmp-commands-info.h
  GEN   x86_64-softmmu/hmp-commands.h
  GEN   x86_64-softmmu/config-target.h
  CC    x86_64-softmmu/exec.o
  CC    x86_64-softmmu/translate-all.o
  CC    x86_64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/translate-common.o
  CC    x86_64-softmmu/tcg/tcg-op.o
  CC    x86_64-softmmu/cpu-exec-common.o
  CC    x86_64-softmmu/tcg/tcg.o
  GEN   aarch64-softmmu/hmp-commands.h
  GEN   aarch64-softmmu/hmp-commands-info.h
  GEN   aarch64-softmmu/config-target.h
  CC    aarch64-softmmu/exec.o
  CC    x86_64-softmmu/tcg/optimize.o
  CC    x86_64-softmmu/tcg/tcg-common.o
  CC    aarch64-softmmu/translate-all.o
  CC    aarch64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/disas.o
  CC    x86_64-softmmu/arch_init.o
  CC    x86_64-softmmu/cpus.o
  CC    aarch64-softmmu/translate-common.o
  CC    x86_64-softmmu/monitor.o
  CC    x86_64-softmmu/gdbstub.o
  CC    x86_64-softmmu/balloon.o
  CC    x86_64-softmmu/ioport.o
  CC    aarch64-softmmu/cpu-exec-common.o
  CC    aarch64-softmmu/tcg/tcg.o
  CC    aarch64-softmmu/tcg/tcg-op.o
  CC    aarch64-softmmu/tcg/optimize.o
  CC    x86_64-softmmu/numa.o
  CC    x86_64-softmmu/qtest.o
  CC    x86_64-softmmu/bootdevice.o
  CC    x86_64-softmmu/kvm-all.o
  CC    x86_64-softmmu/sev.o
  CC    aarch64-softmmu/tcg/tcg-common.o
  CC    aarch64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/memory.o
  CC    aarch64-softmmu/disas.o
  GEN   aarch64-softmmu/gdbstub-xml.c
/tmp/qemu-test/src/sev.c: In function ‘sev_launch_info_get_params’:
/tmp/qemu-test/src/sev.c:632: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:633: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:634: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:635: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:636: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:637: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:639: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:642: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:643: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:644: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:644: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:645: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:645: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:646: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:646: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:649: error: invalid application of ‘sizeof’ to incomplete type ‘struct kvm_sev_launch_update’ 
/tmp/qemu-test/src/sev.c: In function ‘sev_ioctl’:
/tmp/qemu-test/src/sev.c:916: error: storage size of ‘input’ isn’t known
/tmp/qemu-test/src/sev.c:920: error: ‘KVM_SEV_ISSUE_CMD’ undeclared (first use in this function)
/tmp/qemu-test/src/sev.c:920: error: (Each undeclared identifier is reported only once
/tmp/qemu-test/src/sev.c:920: error: for each function it appears in.)
/tmp/qemu-test/src/sev.c:916: warning: unused variable ‘input’
/tmp/qemu-test/src/sev.c: In function ‘sev_launch_start’:
/tmp/qemu-test/src/sev.c:945: error: ‘KVM_SEV_LAUNCH_START’ undeclared (first use in this function)
/tmp/qemu-test/src/sev.c: In function ‘sev_launch_finish’:
/tmp/qemu-test/src/sev.c:963: error: ‘KVM_SEV_LAUNCH_FINISH’ undeclared (first use in this function)
/tmp/qemu-test/src/sev.c:969: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:970: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c: In function ‘sev_launch_update’:
/tmp/qemu-test/src/sev.c:983: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:984: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:986: error: ‘KVM_SEV_LAUNCH_UPDATE’ undeclared (first use in this function)
/tmp/qemu-test/src/sev.c: In function ‘sev_debug_decrypt’:
/tmp/qemu-test/src/sev.c:1090: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1091: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1092: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1093: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1095: error: ‘KVM_SEV_DBG_DECRYPT’ undeclared (first use in this function)
/tmp/qemu-test/src/sev.c: In function ‘sev_debug_encrypt’:
/tmp/qemu-test/src/sev.c:1108: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1109: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1110: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1111: error: dereferencing pointer to incomplete type
/tmp/qemu-test/src/sev.c:1113: error: ‘KVM_SEV_DBG_ENCRYPT’ undeclared (first use in this function)
make[1]: *** [sev.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/kvm-stub.o
  CC    aarch64-softmmu/arch_init.o
  CC    aarch64-softmmu/cpus.o
  CC    aarch64-softmmu/monitor.o
  CC    aarch64-softmmu/gdbstub.o
  CC    aarch64-softmmu/balloon.o
  CC    aarch64-softmmu/ioport.o
  CC    aarch64-softmmu/numa.o
  CC    aarch64-softmmu/qtest.o
  CC    aarch64-softmmu/bootdevice.o
  CC    aarch64-softmmu/memory.o
  CC    aarch64-softmmu/cputlb.o
  CC    aarch64-softmmu/memory_mapping.o
make: *** [subdir-x86_64-softmmu] Error 2
make: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/dump.o
  CC    aarch64-softmmu/migration/ram.o
  CC    aarch64-softmmu/migration/savevm.o
  CC    aarch64-softmmu/xen-common-stub.o
  CC    aarch64-softmmu/xen-hvm-stub.o
  CC    aarch64-softmmu/hw/block/virtio-blk.o
  CC    aarch64-softmmu/hw/block/dataplane/virtio-blk.o
  CC    aarch64-softmmu/hw/char/exynos4210_uart.o
  CC    aarch64-softmmu/hw/char/omap_uart.o
  CC    aarch64-softmmu/hw/char/digic-uart.o
  CC    aarch64-softmmu/hw/char/stm32f2xx_usart.o
  CC    aarch64-softmmu/hw/char/bcm2835_aux.o
  CC    aarch64-softmmu/hw/char/virtio-serial-bus.o
  CC    aarch64-softmmu/hw/core/nmi.o
  CC    aarch64-softmmu/hw/cpu/arm11mpcore.o
  CC    aarch64-softmmu/hw/cpu/realview_mpcore.o
  CC    aarch64-softmmu/hw/cpu/a9mpcore.o
  CC    aarch64-softmmu/hw/cpu/a15mpcore.o
  CC    aarch64-softmmu/hw/cpu/core.o
  CC    aarch64-softmmu/hw/display/omap_dss.o
  CC    aarch64-softmmu/hw/display/omap_lcdc.o
  CC    aarch64-softmmu/hw/display/pxa2xx_lcd.o
  CC    aarch64-softmmu/hw/display/bcm2835_fb.o
  CC    aarch64-softmmu/hw/display/vga.o
  CC    aarch64-softmmu/hw/display/virtio-gpu.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-3d.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-pci.o
  CC    aarch64-softmmu/hw/display/dpcd.o
  CC    aarch64-softmmu/hw/display/xlnx_dp.o
  CC    aarch64-softmmu/hw/dma/xlnx_dpdma.o
  CC    aarch64-softmmu/hw/dma/omap_dma.o
  CC    aarch64-softmmu/hw/dma/soc_dma.o
  CC    aarch64-softmmu/hw/dma/pxa2xx_dma.o
  CC    aarch64-softmmu/hw/dma/bcm2835_dma.o
  CC    aarch64-softmmu/hw/gpio/omap_gpio.o
  CC    aarch64-softmmu/hw/gpio/imx_gpio.o
  CC    aarch64-softmmu/hw/i2c/omap_i2c.o
  CC    aarch64-softmmu/hw/input/pxa2xx_keypad.o
  CC    aarch64-softmmu/hw/input/tsc210x.o
  CC    aarch64-softmmu/hw/intc/armv7m_nvic.o
  CC    aarch64-softmmu/hw/intc/exynos4210_gic.o
  CC    aarch64-softmmu/hw/intc/exynos4210_combiner.o
  CC    aarch64-softmmu/hw/intc/omap_intc.o
  CC    aarch64-softmmu/hw/intc/bcm2835_ic.o
  CC    aarch64-softmmu/hw/intc/bcm2836_control.o
  CC    aarch64-softmmu/hw/intc/allwinner-a10-pic.o
  CC    aarch64-softmmu/hw/intc/aspeed_vic.o
  CC    aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
  CC    aarch64-softmmu/hw/misc/ivshmem.o
  CC    aarch64-softmmu/hw/misc/arm_sysctl.o
  CC    aarch64-softmmu/hw/misc/cbus.o
  CC    aarch64-softmmu/hw/misc/exynos4210_pmu.o
  CC    aarch64-softmmu/hw/misc/imx_ccm.o
  CC    aarch64-softmmu/hw/misc/imx31_ccm.o
  CC    aarch64-softmmu/hw/misc/imx25_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_src.o
  CC    aarch64-softmmu/hw/misc/mst_fpga.o
  CC    aarch64-softmmu/hw/misc/omap_clk.o
  CC    aarch64-softmmu/hw/misc/omap_gpmc.o
  CC    aarch64-softmmu/hw/misc/omap_l4.o
  CC    aarch64-softmmu/hw/misc/omap_sdrc.o
  CC    aarch64-softmmu/hw/misc/omap_tap.o
  CC    aarch64-softmmu/hw/misc/bcm2835_mbox.o
  CC    aarch64-softmmu/hw/misc/bcm2835_property.o
  CC    aarch64-softmmu/hw/misc/zynq_slcr.o
  CC    aarch64-softmmu/hw/misc/zynq-xadc.o
  CC    aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
  CC    aarch64-softmmu/hw/misc/edu.o
  CC    aarch64-softmmu/hw/misc/auxbus.o
  CC    aarch64-softmmu/hw/misc/aspeed_scu.o
  CC    aarch64-softmmu/hw/misc/aspeed_sdmc.o
  CC    aarch64-softmmu/hw/net/virtio-net.o
  CC    aarch64-softmmu/hw/net/vhost_net.o
  CC    aarch64-softmmu/hw/pcmcia/pxa2xx.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC    aarch64-softmmu/hw/scsi/vhost-scsi.o
  CC    aarch64-softmmu/hw/sd/omap_mmc.o
  CC    aarch64-softmmu/hw/sd/pxa2xx_mmci.o
  CC    aarch64-softmmu/hw/ssi/omap_spi.o
  CC    aarch64-softmmu/hw/ssi/imx_spi.o
  CC    aarch64-softmmu/hw/timer/exynos4210_mct.o
  CC    aarch64-softmmu/hw/timer/exynos4210_pwm.o
  CC    aarch64-softmmu/hw/timer/exynos4210_rtc.o
  CC    aarch64-softmmu/hw/timer/omap_gptimer.o
  CC    aarch64-softmmu/hw/timer/omap_synctimer.o
  CC    aarch64-softmmu/hw/timer/pxa2xx_timer.o
  CC    aarch64-softmmu/hw/timer/digic-timer.o
  CC    aarch64-softmmu/hw/timer/allwinner-a10-pit.o
  CC    aarch64-softmmu/hw/usb/tusb6010.o
  CC    aarch64-softmmu/hw/vfio/common.o
  CC    aarch64-softmmu/hw/vfio/pci.o
  CC    aarch64-softmmu/hw/vfio/pci-quirks.o
  CC    aarch64-softmmu/hw/vfio/platform.o
  CC    aarch64-softmmu/hw/vfio/calxeda-xgmac.o
  CC    aarch64-softmmu/hw/vfio/amd-xgbe.o
  CC    aarch64-softmmu/hw/vfio/spapr.o
  CC    aarch64-softmmu/hw/virtio/virtio.o
  CC    aarch64-softmmu/hw/virtio/virtio-balloon.o
  CC    aarch64-softmmu/hw/virtio/vhost.o
  CC    aarch64-softmmu/hw/virtio/vhost-backend.o
  CC    aarch64-softmmu/hw/virtio/vhost-user.o
  CC    aarch64-softmmu/hw/virtio/vhost-vsock.o
  CC    aarch64-softmmu/hw/arm/boot.o
  CC    aarch64-softmmu/hw/arm/collie.o
  CC    aarch64-softmmu/hw/arm/exynos4_boards.o
  CC    aarch64-softmmu/hw/arm/gumstix.o
  CC    aarch64-softmmu/hw/arm/highbank.o
  CC    aarch64-softmmu/hw/arm/digic_boards.o
  CC    aarch64-softmmu/hw/arm/integratorcp.o
  CC    aarch64-softmmu/hw/arm/mainstone.o
  CC    aarch64-softmmu/hw/arm/musicpal.o
  CC    aarch64-softmmu/hw/arm/nseries.o
  CC    aarch64-softmmu/hw/arm/omap_sx1.o
  CC    aarch64-softmmu/hw/arm/palm.o
  CC    aarch64-softmmu/hw/arm/realview.o
  CC    aarch64-softmmu/hw/arm/spitz.o
  CC    aarch64-softmmu/hw/arm/stellaris.o
  CC    aarch64-softmmu/hw/arm/tosa.o
  CC    aarch64-softmmu/hw/arm/versatilepb.o
  CC    aarch64-softmmu/hw/arm/vexpress.o
  CC    aarch64-softmmu/hw/arm/virt.o
  CC    aarch64-softmmu/hw/arm/xilinx_zynq.o
  CC    aarch64-softmmu/hw/arm/z2.o
  CC    aarch64-softmmu/hw/arm/virt-acpi-build.o
  CC    aarch64-softmmu/hw/arm/netduino2.o
  CC    aarch64-softmmu/hw/arm/sysbus-fdt.o
  CC    aarch64-softmmu/hw/arm/armv7m.o
  CC    aarch64-softmmu/hw/arm/exynos4210.o
  CC    aarch64-softmmu/hw/arm/pxa2xx.o
  CC    aarch64-softmmu/hw/arm/pxa2xx_gpio.o
  CC    aarch64-softmmu/hw/arm/pxa2xx_pic.o
  CC    aarch64-softmmu/hw/arm/digic.o
  CC    aarch64-softmmu/hw/arm/omap1.o
  CC    aarch64-softmmu/hw/arm/omap2.o
  CC    aarch64-softmmu/hw/arm/strongarm.o
  CC    aarch64-softmmu/hw/arm/allwinner-a10.o
  CC    aarch64-softmmu/hw/arm/cubieboard.o
  CC    aarch64-softmmu/hw/arm/bcm2835_peripherals.o
  CC    aarch64-softmmu/hw/arm/bcm2836.o
  CC    aarch64-softmmu/hw/arm/raspi.o
  CC    aarch64-softmmu/hw/arm/stm32f205_soc.o
  CC    aarch64-softmmu/hw/arm/xlnx-zynqmp.o
  CC    aarch64-softmmu/hw/arm/xlnx-ep108.o
  CC    aarch64-softmmu/hw/arm/fsl-imx25.o
  CC    aarch64-softmmu/hw/arm/imx25_pdk.o
  CC    aarch64-softmmu/hw/arm/fsl-imx31.o
  CC    aarch64-softmmu/hw/arm/kzm.o
  CC    aarch64-softmmu/hw/arm/fsl-imx6.o
  CC    aarch64-softmmu/hw/arm/sabrelite.o
  CC    aarch64-softmmu/hw/arm/ast2400.o
  CC    aarch64-softmmu/hw/arm/palmetto-bmc.o
  CC    aarch64-softmmu/target-arm/arm-semi.o
  CC    aarch64-softmmu/target-arm/machine.o
  CC    aarch64-softmmu/target-arm/psci.o
  CC    aarch64-softmmu/target-arm/arch_dump.o
  CC    aarch64-softmmu/target-arm/monitor.o
  CC    aarch64-softmmu/target-arm/kvm-stub.o
  CC    aarch64-softmmu/target-arm/translate.o
  CC    aarch64-softmmu/target-arm/op_helper.o
  CC    aarch64-softmmu/target-arm/helper.o
  CC    aarch64-softmmu/target-arm/cpu.o
  CC    aarch64-softmmu/target-arm/neon_helper.o
  CC    aarch64-softmmu/target-arm/iwmmxt_helper.o
  CC    aarch64-softmmu/target-arm/gdbstub.o
  CC    aarch64-softmmu/target-arm/cpu64.o
  CC    aarch64-softmmu/target-arm/translate-a64.o
  CC    aarch64-softmmu/target-arm/helper-a64.o
  CC    aarch64-softmmu/target-arm/gdbstub64.o
  CC    aarch64-softmmu/target-arm/crypto_helper.o
  CC    aarch64-softmmu/target-arm/arm-powerctl.o
  GEN   trace/generated-helpers.c
  CC    aarch64-softmmu/trace/control-target.o
  CC    aarch64-softmmu/gdbstub-xml.o
  CC    aarch64-softmmu/trace/generated-helpers.o
/tmp/qemu-test/src/target-arm/translate-a64.c: In function ‘handle_shri_with_rndacc’:
/tmp/qemu-test/src/target-arm/translate-a64.c:6333: warning: ‘tcg_src_hi’ may be used uninitialized in this function
/tmp/qemu-test/src/target-arm/translate-a64.c: In function ‘disas_simd_scalar_two_reg_misc’:
/tmp/qemu-test/src/target-arm/translate-a64.c:8060: warning: ‘rmode’ may be used uninitialized in this function
  LINK  aarch64-softmmu/qemu-system-aarch64
../qmp.o: In function `qmp_query_kvm':
/tmp/qemu-test/src/qmp.c:70: undefined reference to `kvm_memory_encryption_enabled'
../hw/core/loader.o: In function `rom_reset':
/tmp/qemu-test/src/hw/core/loader.c:1004: undefined reference to `kvm_memory_encryption_enabled'
/tmp/qemu-test/src/hw/core/loader.c:1037: undefined reference to `kvm_memory_encryption_enabled'
/tmp/qemu-test/src/hw/core/loader.c:1005: undefined reference to `kvm_memory_encryption_start'
/tmp/qemu-test/src/hw/core/loader.c:1038: undefined reference to `kvm_memory_encryption_finish'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-aarch64] Error 1
make: *** [subdir-aarch64-softmmu] Error 2
tests/docker/Makefile.include:107: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 1
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD)
  2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (16 preceding siblings ...)
  2016-09-22 15:53 ` [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) no-reply
@ 2016-09-22 15:54 ` no-reply
  17 siblings, 0 replies; 29+ messages in thread
From: no-reply @ 2016-09-22 15:54 UTC (permalink / raw)
  To: brijesh.singh
  Cc: famz, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 147455590865.8519.11191009507297313736.stgit@brijesh-build-machine
Subject: [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD)

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1474556029-24992-1-git-send-email-ehabkost@redhat.com -> patchew/1474556029-24992-1-git-send-email-ehabkost@redhat.com
Switched to a new branch 'test'
850cc25 i386: clear C-bit in SEV guest page table walk
118801a target-i386: add cpuid Fn8000_001f
0a1150c i386: set memory encryption ops for PC.BIOS and PC.RAM regions
cc8e566 sev: add DEBUG_ENCRYPT command
7a078d0 sev: add DEBUG_DECRYPT command
86d0fa9 sev: add LAUNCH_FINISH command
2fab8c2 sev: add LAUNCH_UPDATE command
1786fb6 sev: add LAUNCH_START command
0b20533 core: loader: create memory encryption context before copying data
9d4475b hmp: display memory encryption support in 'info kvm'
a3a62fd sev: add Secure Encrypted Virtulization (SEV) support
405efda core: add new security-policy object
3d2db73 monitor: use debug version of memory access apis
bcb1584 exec: add debug version of physical memory read and write apis
ef720ae exec: add guest RAM read and write ops
bcdc107 memattrs: add debug attrs

=== OUTPUT BEGIN ===
Checking PATCH 1/16: memattrs: add debug attrs...
Checking PATCH 2/16: exec: add guest RAM read and write ops...
Checking PATCH 3/16: exec: add debug version of physical memory read and write apis...
Checking PATCH 4/16: monitor: use debug version of memory access apis...
Checking PATCH 5/16: core: add new security-policy object...
Checking PATCH 6/16: sev: add Secure Encrypted Virtulization (SEV) support...
ERROR: trailing whitespace
#705: FILE: qemu-options.hx:4000:
+SEV-enabled guest. $

ERROR: do not use C99 // comments
#1736: FILE: sev.c:923:
+    // add the command to launch guest in next patches

ERROR: do not use C99 // comments
#1743: FILE: sev.c:930:
+    // add the command to finalize the launch in next patches

ERROR: do not use C99 // comments
#1810: FILE: sev.c:997:
+        // use receive_info commands

ERROR: do not use C99 // comments
#1827: FILE: sev.c:1014:
+        // use launch_finish commands

ERROR: do not use C99 // comments
#1829: FILE: sev.c:1016:
+        // use receive_finish commands

ERROR: do not use C99 // comments
#1844: FILE: sev.c:1031:
+    // fill in the code in next patches

ERROR: do not use C99 // comments
#1855: FILE: sev.c:1042:
+    // fill in the code in next patches

total: 8 errors, 0 warnings, 1775 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 7/16: hmp: display memory encryption support in 'info kvm'...
Checking PATCH 8/16: core: loader: create memory encryption context before copying data...
Checking PATCH 9/16: sev: add LAUNCH_START command...
Checking PATCH 10/16: sev: add LAUNCH_UPDATE command...
Checking PATCH 11/16: sev: add LAUNCH_FINISH command...
Checking PATCH 12/16: sev: add DEBUG_DECRYPT command...
Checking PATCH 13/16: sev: add DEBUG_ENCRYPT command...
Checking PATCH 14/16: i386: set memory encryption ops for PC.BIOS and PC.RAM regions...
Checking PATCH 15/16: target-i386: add cpuid Fn8000_001f...
Checking PATCH 16/16: i386: clear C-bit in SEV guest page table walk...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis Brijesh Singh
  2016-09-22 15:18   ` Paolo Bonzini
@ 2016-09-22 19:24   ` Michael S. Tsirkin
  2016-09-22 20:55     ` Brijesh Singh
  1 sibling, 1 reply; 29+ messages in thread
From: Michael S. Tsirkin @ 2016-09-22 19:24 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

On Thu, Sep 22, 2016 at 10:52:28AM -0400, Brijesh Singh wrote:
> updates hmp monitor to use debug version of memory access apis when
> accessing the guest memory.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>

Does this cover the gdb stub as well?

> ---
>  cpus.c                |    2 +-
>  disas.c               |    2 +-
>  monitor.c             |    2 +-
>  target-i386/helper.c  |   14 +++++++-------
>  target-i386/monitor.c |   18 ++++++++++--------
>  5 files changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 84c3520..48dc4d1 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -1725,7 +1725,7 @@ void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
>          l = sizeof(buf);
>          if (l > size)
>              l = size;
> -        cpu_physical_memory_read(addr, buf, l);
> +        cpu_physical_memory_read_debug(addr, buf, l);
>          if (fwrite(buf, 1, l, f) != l) {
>              error_setg(errp, QERR_IO_ERROR);
>              goto exit;
> diff --git a/disas.c b/disas.c
> index 05a7a12..382cc2c 100644
> --- a/disas.c
> +++ b/disas.c
> @@ -356,7 +356,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
>      CPUDebug *s = container_of(info, CPUDebug, info);
>  
>      if (monitor_disas_is_physical) {
> -        cpu_physical_memory_read(memaddr, myaddr, length);
> +        cpu_physical_memory_read_debug(memaddr, myaddr, length);
>      } else {
>          cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
>      }
> diff --git a/monitor.c b/monitor.c
> index 5c00373..4773ee1 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1299,7 +1299,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
>          if (l > line_size)
>              l = line_size;
>          if (is_physical) {
> -            cpu_physical_memory_read(addr, buf, l);
> +            cpu_physical_memory_read_debug(addr, buf, l);
>          } else {
>              if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) {
>                  monitor_printf(mon, " Cannot access memory\n");
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 1c250b8..88fa4fa 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -1034,13 +1034,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>              }
>              pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
>                  env->a20_mask;
> -            pml4e = x86_ldq_phys(cs, pml4e_addr);
> +            pml4e = ldq_phys_debug(cs, pml4e_addr);
>              if (!(pml4e & PG_PRESENT_MASK)) {
>                  return -1;
>              }
>              pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
>                           (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
> -            pdpe = x86_ldq_phys(cs, pdpe_addr);
> +            pdpe = ldq_phys_debug(cs, pdpe_addr);
>              if (!(pdpe & PG_PRESENT_MASK)) {
>                  return -1;
>              }
> @@ -1055,14 +1055,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>          {
>              pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
>                  env->a20_mask;
> -            pdpe = x86_ldq_phys(cs, pdpe_addr);
> +            pdpe = ldq_phys_debug(cs, pdpe_addr);
>              if (!(pdpe & PG_PRESENT_MASK))
>                  return -1;
>          }
>  
>          pde_addr = ((pdpe & PG_ADDRESS_MASK) +
>                      (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
> -        pde = x86_ldq_phys(cs, pde_addr);
> +        pde = ldq_phys_debug(cs, pde_addr);
>          if (!(pde & PG_PRESENT_MASK)) {
>              return -1;
>          }
> @@ -1075,7 +1075,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>              pte_addr = ((pde & PG_ADDRESS_MASK) +
>                          (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
>              page_size = 4096;
> -            pte = x86_ldq_phys(cs, pte_addr);
> +            pte = ldq_phys_debug(cs, pte_addr);
>          }
>          if (!(pte & PG_PRESENT_MASK)) {
>              return -1;
> @@ -1085,7 +1085,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>  
>          /* page directory entry */
>          pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
> -        pde = x86_ldl_phys(cs, pde_addr);
> +        pde = ldl_phys_debug(cs, pde_addr);
>          if (!(pde & PG_PRESENT_MASK))
>              return -1;
>          if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
> @@ -1094,7 +1094,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>          } else {
>              /* page directory entry */
>              pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
> -            pte = x86_ldl_phys(cs, pte_addr);
> +            pte = ldl_phys_debug(cs, pte_addr);
>              if (!(pte & PG_PRESENT_MASK)) {
>                  return -1;
>              }
> diff --git a/target-i386/monitor.c b/target-i386/monitor.c
> index fccfe40..47d3c2d 100644
> --- a/target-i386/monitor.c
> +++ b/target-i386/monitor.c
> @@ -130,12 +130,12 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
>  
>      pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
>      for (l1 = 0; l1 < 512; l1++) {
> -        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
> +        cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
>          pml4e = le64_to_cpu(pml4e);
>          if (pml4e & PG_PRESENT_MASK) {
>              pdp_addr = pml4e & 0x3fffffffff000ULL;
>              for (l2 = 0; l2 < 512; l2++) {
> -                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
> +                cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
>                  pdpe = le64_to_cpu(pdpe);
>                  if (pdpe & PG_PRESENT_MASK) {
>                      if (pdpe & PG_PSE_MASK) {
> @@ -145,7 +145,8 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
>                      } else {
>                          pd_addr = pdpe & 0x3fffffffff000ULL;
>                          for (l3 = 0; l3 < 512; l3++) {
> -                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
> +                            cpu_physical_memory_read_debug(pd_addr + l3 * 8,
> +                                    &pde, 8);
>                              pde = le64_to_cpu(pde);
>                              if (pde & PG_PRESENT_MASK) {
>                                  if (pde & PG_PSE_MASK) {
> @@ -156,7 +157,7 @@ static void tlb_info_64(Monitor *mon, CPUArchState *env)
>                                  } else {
>                                      pt_addr = pde & 0x3fffffffff000ULL;
>                                      for (l4 = 0; l4 < 512; l4++) {
> -                                        cpu_physical_memory_read(pt_addr
> +                                        cpu_physical_memory_read_debug(pt_addr
>                                                                   + l4 * 8,
>                                                                   &pte, 8);
>                                          pte = le64_to_cpu(pte);
> @@ -335,13 +336,13 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
>      last_prot = 0;
>      start = -1;
>      for (l1 = 0; l1 < 512; l1++) {
> -        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
> +        cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
>          pml4e = le64_to_cpu(pml4e);
>          end = l1 << 39;
>          if (pml4e & PG_PRESENT_MASK) {
>              pdp_addr = pml4e & 0x3fffffffff000ULL;
>              for (l2 = 0; l2 < 512; l2++) {
> -                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
> +                cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
>                  pdpe = le64_to_cpu(pdpe);
>                  end = (l1 << 39) + (l2 << 30);
>                  if (pdpe & PG_PRESENT_MASK) {
> @@ -353,7 +354,8 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
>                      } else {
>                          pd_addr = pdpe & 0x3fffffffff000ULL;
>                          for (l3 = 0; l3 < 512; l3++) {
> -                            cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
> +                            cpu_physical_memory_read_debug(pd_addr + l3 * 8,
> +                                    &pde, 8);
>                              pde = le64_to_cpu(pde);
>                              end = (l1 << 39) + (l2 << 30) + (l3 << 21);
>                              if (pde & PG_PRESENT_MASK) {
> @@ -365,7 +367,7 @@ static void mem_info_64(Monitor *mon, CPUArchState *env)
>                                  } else {
>                                      pt_addr = pde & 0x3fffffffff000ULL;
>                                      for (l4 = 0; l4 < 512; l4++) {
> -                                        cpu_physical_memory_read(pt_addr
> +                                        cpu_physical_memory_read_debug(pt_addr
>                                                                   + l4 * 8,
>                                                                   &pte, 8);
>                                          pte = le64_to_cpu(pte);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support
  2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
  2016-09-22 15:12   ` Paolo Bonzini
@ 2016-09-22 19:51   ` Michael S. Tsirkin
  1 sibling, 0 replies; 29+ messages in thread
From: Michael S. Tsirkin @ 2016-09-22 19:51 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth

On Thu, Sep 22, 2016 at 10:52:49AM -0400, Brijesh Singh wrote:
>  # $QEMU \
>     -object sev-receive-info,id=launch0,flags.ks=off \
>     -object sev-guest-info,id=sev0,launch=launch0 \
>     -object security-policy,id=secure0,memory-encryption=sev0 \
>     -machine ....,security-policy=secure0

Looks like most of info in a sev object is actually quite generic.
Let's give it readable generic names please, it will be easier to
review then. For example sev-guest-info -> memory-encryption-guest-info,
etc.

+Bit 0 (debug) - Debugging of the guest is disallowed when set
+Bit 1 (ks) - Sharing keys with other guests is disallowed when set
+Bit 2 (reserved) - must be set to 1
+Bit 3 (nosend) - Sending the guest to another platform is disallowed when set
+Bit 4 (domain) - The guest must not be transmitted to another platform that is not in the domain when set
+Bit 5 (sev) - The guest must not be transmitted to another platform that is not SEV capable when set.
+Bit 15:6 (reserved)
+Bit 16:24 (fw_major) - The guest must not be transmitted to another platform that is not SEV capable when set.
+Bit 25:31 (fw_minor) - The guest must not be transmitted to another platform that is not SEV capable when set.

So e.g. ks -> key-sharing=off. Etc.

And please include documentation about what does each of these things
actually do, so we can discuss whether we even need all of these knobs.

For example: key-sharing=off - will this mean that starting two VMs with
same key on same host fails?
But is it ever useful to do allow key sharing?
Etc.

-- 
MST

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis
  2016-09-22 19:24   ` Michael S. Tsirkin
@ 2016-09-22 20:55     ` Brijesh Singh
  0 siblings, 0 replies; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 20:55 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth

Hi,

On 09/22/2016 02:24 PM, Michael S. Tsirkin wrote:
> On Thu, Sep 22, 2016 at 10:52:28AM -0400, Brijesh Singh wrote:
>> updates hmp monitor to use debug version of memory access apis when
>> accessing the guest memory.
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>
> Does this cover the gdb stub as well?

Yes, gdb stub works. gdb was already wired to use debug version of api

target_memory_rw_debug
   cpu_memory_rw_debug

Only part which i needed to take care was to ensure that page table walk 
to find a physical address for a given virtual address goes through the 
debug version of apis. changes in target-i386/helper.c takes care of this.

-Brijesh

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support
  2016-09-22 15:12   ` Paolo Bonzini
@ 2016-09-22 21:12     ` Brijesh Singh
  2016-09-22 21:57       ` Michael S. Tsirkin
  0 siblings, 1 reply; 29+ messages in thread
From: Brijesh Singh @ 2016-09-22 21:12 UTC (permalink / raw)
  To: Paolo Bonzini, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, rth
  Cc: brijesh.singh

Hi,

On 09/22/2016 10:12 AM, Paolo Bonzini wrote:
>
>
>>
>>   to use encrypted guest launch
>>   # $QEMU \
>>      -object sev-receive-info,id=launch0 \
>>      -object sev-send-info,id=send0 \
>>      -object sev-guest-info,id=sev0,launch=launch0,send=send0 \
>>      .....
>>
>
> References to other objects should be implemented as link properties
> (e.g. with type 'link<sev-guest-info>').  Then QOM takes care of filling
> in a QSEVGuestInfo* with the pointer to an object with the right id.
>
> There is some redundancy (e.g. "flags.ks" in launch/receive vs. "ks" in
> policy).  Can you document the full model in
> docs/amd-memory-encryption.txt?  It's not necessary to include the
> kernel API documentation.
>

The flags.ks means that hypervisor requested the key-sharing. The 
policy.ks means that key-sharing is allowed by guest owner. The values 
in sev-policy should be provided by the guest owner. The content of 
policy field is used during the measurement calculation. If hypervisor 
changes anything into policy field without guest owners permission then 
measurement value will not match.

I can think of one case where flag.ks may be used.

e.g lets say guest policy allows key sharing and this is first SEV guest 
in the system then hypervisor will set flags.ks=0. In next guest launch 
it can set flags.ks=1 and use the SEV handle from previous guest.

I will add some more text to clarify it in doc and property description.

> Paolo
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support
  2016-09-22 21:12     ` Brijesh Singh
@ 2016-09-22 21:57       ` Michael S. Tsirkin
  0 siblings, 0 replies; 29+ messages in thread
From: Michael S. Tsirkin @ 2016-09-22 21:57 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: Paolo Bonzini, ehabkost, crosthwaite.peter, armbru, p.fedin,
	qemu-devel, lcapitulino, rth

On Thu, Sep 22, 2016 at 04:12:04PM -0500, Brijesh Singh wrote:
> Hi,
> 
> On 09/22/2016 10:12 AM, Paolo Bonzini wrote:
> > 
> > 
> > > 
> > >   to use encrypted guest launch
> > >   # $QEMU \
> > >      -object sev-receive-info,id=launch0 \
> > >      -object sev-send-info,id=send0 \
> > >      -object sev-guest-info,id=sev0,launch=launch0,send=send0 \
> > >      .....
> > > 
> > 
> > References to other objects should be implemented as link properties
> > (e.g. with type 'link<sev-guest-info>').  Then QOM takes care of filling
> > in a QSEVGuestInfo* with the pointer to an object with the right id.
> > 
> > There is some redundancy (e.g. "flags.ks" in launch/receive vs. "ks" in
> > policy).  Can you document the full model in
> > docs/amd-memory-encryption.txt?  It's not necessary to include the
> > kernel API documentation.
> > 
> 
> The flags.ks means that hypervisor requested the key-sharing. The policy.ks
> means that key-sharing is allowed by guest owner. The values in sev-policy
> should be provided by the guest owner. The content of policy field is used
> during the measurement calculation.

We excluded the measurement part for now, so I think this can
go as well.

> If hypervisor changes anything into
> policy field without guest owners permission then measurement value will not
> match.

IMHO measurement is mostly useless with current hardware.

I suggest that for now we just assume that hypervisor is not
attacking the guest while it's booting.
Extend this later once first part is merged.

> I can think of one case where flag.ks may be used.
> 
> e.g lets say guest policy allows key sharing and this is first SEV guest in
> the system then hypervisor will set flags.ks=0. In next guest launch it can
> set flags.ks=1 and use the SEV handle from previous guest.
>
> I will add some more text to clarify it in doc and property description.
> 
> > Paolo
> > 

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-09-22 21:57 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-22 14:51 [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs Brijesh Singh
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops Brijesh Singh
2016-09-22 15:22   ` Paolo Bonzini
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis Brijesh Singh
2016-09-22 15:21   ` Paolo Bonzini
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis Brijesh Singh
2016-09-22 15:18   ` Paolo Bonzini
2016-09-22 19:24   ` Michael S. Tsirkin
2016-09-22 20:55     ` Brijesh Singh
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 05/16] core: add new security-policy object Brijesh Singh
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
2016-09-22 15:12   ` Paolo Bonzini
2016-09-22 21:12     ` Brijesh Singh
2016-09-22 21:57       ` Michael S. Tsirkin
2016-09-22 19:51   ` Michael S. Tsirkin
2016-09-22 14:52 ` [Qemu-devel] [RFC PATCH v2 07/16] hmp: display memory encryption support in 'info kvm' Brijesh Singh
2016-09-22 15:32   ` Eric Blake
2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 08/16] core: loader: create memory encryption context before copying data Brijesh Singh
2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 09/16] sev: add LAUNCH_START command Brijesh Singh
2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 10/16] sev: add LAUNCH_UPDATE command Brijesh Singh
2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 11/16] sev: add LAUNCH_FINISH command Brijesh Singh
2016-09-22 14:53 ` [Qemu-devel] [RFC PATCH v2 12/16] sev: add DEBUG_DECRYPT command Brijesh Singh
2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 13/16] sev: add DEBUG_ENCRYPT command Brijesh Singh
2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 14/16] i386: set memory encryption ops for PC.BIOS and PC.RAM regions Brijesh Singh
2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 15/16] target-i386: add cpuid Fn8000_001f Brijesh Singh
2016-09-22 14:54 ` [Qemu-devel] [RFC PATCH v2 16/16] i386: clear C-bit in SEV guest page table walk Brijesh Singh
2016-09-22 15:53 ` [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD) no-reply
2016-09-22 15:54 ` no-reply

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.