All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD)
@ 2017-03-08 20:51 Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file Brijesh Singh
                   ` (21 more replies)
  0 siblings, 22 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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.

The KVM RFC introduced a new ioctl (KVM_MEMORY_ENCRYPTION_OP) which can be
used by qemu to issue the SEV commands to assist performing common hypervisor
activities such as a launching, running, snapshooting, migration and debugging
guests.

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_Specification.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=linux-mm&m=148846752931115&w=2

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

---

The patch series implements booting SEV guest from unencrypted boot images.
In this series we do not expose object properties to use guest owners specific
PDH certificates or session data. We let the firmware auto generate the VM
encryption keys and ignore the measurements. Passing guest specific certificate
blobs will be added after the first part is reviewed and merged.

The series is tested using OVMF BIOS. I have been working to integerate SEV
support into OVMF tree [2]

[2] https://lists.01.org/pipermail/edk2-devel/2017-March/008213.html

The patches are based on commit 43c227f (disas/arm: Avoid unintended sign
extension)

Changes since v3:
 - update to newer SEV spec (0.12 -> 0.14)
 - update to newer KVM RFC and use KVM_MEMORY_ENCRYPTION_OP ioctl instead
   of KVM_ISSUE_SEV.
 - add support to encrypt plfash

Changes since v2:
- rename ram_ops to ram_debug_ops
- use '-' rather than '_' when adding new member in KvmInfo struct
- update sev object to use link properties when referencing other objects
- use ldq_phys_debug in tlb_info_64 and mem_info_64.
- remove sev-guest-policy object, we will revisit it after basic SEV
  guest support is merged.
- remove kernel API from doc and add SEV guest LAUNCH model. The doc will
  be updated as we integerate the remaining SEV APIs.

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:
- 'info mem' runs very slow in SEV enable guest. 
  
  info mem command does a guest pagetable walk, which reads 8 bytes of data
  at a time. When SEV is enabled then we need to call into kernel (which will
  invoke SEV DEBUG DECRYPT command) to read the guest memory for debug purposes.
  I am thinking that inside the SEV debug callback handler we can cache a full
  page to reduce number of kernel calls to improve the performance.

- integrate SEV SEND_* command in vmsave code path.
- integerate SEV RECEIVE_* command in vm restore code path.
- virtio support in SEV guest.
- Integrate SEV SEND and RECEIVE command in live migration.

Brijesh Singh (20):
      kvm: update kvm.h header file
      memattrs: add debug attribute
      exec: add guest RAM read and write ops
      exec: add debug version of physical memory read and write api
      monitor/i386: use debug apis when accessing guest memory
      core: add new security-policy object
      kvm: add memory encryption api support
      sev: add Secure Encrypted Virtulization (SEV) support
      hmp: display memory encryption support in 'info kvm'
      vl: add memory encryption support
      sev: add LAUNCH_START command
      SEV: add GUEST_STATUS command
      sev: add LAUNCH_UPDATE_DATA command
      sev: add LAUNCH_FINISH command
      sev: add DEBUG_DECRYPT command
      sev: add DEBUG_ENCRYPT command
      target/i386: encrypt bios rom when memory encryption is enabled
      target/i386: add cpuid Fn8000_001f
      target/i386: clear memory encryption bit when walking SEV guest page table
      migration: disable save/restore and migration when SEV is active


 Makefile.target                  |    2 
 cpus.c                           |    2 
 disas.c                          |    2 
 docs/amd-memory-encryption.txt   |  121 +++++++++
 exec.c                           |   94 ++++++-
 hmp.c                            |    2 
 hw/core/Makefile.objs            |    1 
 hw/core/machine.c                |   22 ++
 hw/core/security-policy.c        |  165 +++++++++++++
 hw/i386/pc.c                     |    7 +
 hw/i386/pc_sysfw.c               |   30 ++
 include/exec/cpu-common.h        |   15 +
 include/exec/memattrs.h          |    4 
 include/exec/memory.h            |   25 ++
 include/hw/boards.h              |    1 
 include/sysemu/kvm.h             |    7 +
 include/sysemu/security-policy.h |   75 ++++++
 include/sysemu/sev.h             |  102 ++++++++
 kvm-all.c                        |   77 ++++++
 kvm-stub.c                       |   36 +++
 linux-headers/linux/kvm.h        |  100 ++++++++
 migration/migration.c            |    7 +
 migration/savevm.c               |   11 +
 monitor.c                        |    2 
 qapi-schema.json                 |    5 
 qemu-options.hx                  |   48 ++++
 qmp.c                            |    1 
 sev.c                            |  489 ++++++++++++++++++++++++++++++++++++++
 target/i386/cpu.c                |    6 
 target/i386/helper.c             |   39 ++-
 target/i386/monitor.c            |  159 +++++++++---
 vl.c                             |   15 +
 32 files changed, 1596 insertions(+), 76 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] 41+ messages in thread

* [Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
@ 2017-03-08 20:51 ` Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute Brijesh Singh
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Updates kmv.h to include memory encryption ioctls and SEV command structure
introduced in KVM RFC [1]

[1] http://marc.info/?l=linux-mm&m=148846752931115&w=2

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 linux-headers/linux/kvm.h |  100 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 4e082a8..1050f53 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1300,6 +1300,106 @@ struct kvm_s390_ucas_mapping {
 #define KVM_S390_GET_IRQ_STATE	  _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
 /* Available with KVM_CAP_X86_SMM */
 #define KVM_SMI                   _IO(KVMIO,   0xb7)
+/* Memory Encryption Commands */
+#define KVM_MEMORY_ENCRYPT_OP	  _IOWR(KVMIO, 0xb8, unsigned long)
+
+/* Secure Encrypted Virtualization mode */
+enum sev_cmd_id {
+	/* Guest launch commands */
+	KVM_SEV_LAUNCH_START = 0,
+	KVM_SEV_LAUNCH_UPDATE_DATA,
+	KVM_SEV_LAUNCH_MEASURE,
+	KVM_SEV_LAUNCH_FINISH,
+	/* Guest migration commands (outgoing) */
+	KVM_SEV_SEND_START,
+	KVM_SEV_SEND_UPDATE_DATA,
+	KVM_SEV_SEND_FINISH,
+	/* Guest migration commands (incoming) */
+	KVM_SEV_RECEIVE_START,
+	KVM_SEV_RECEIVE_UPDATE_DATA,
+	KVM_SEV_RECEIVE_FINISH,
+	/* Guest status and debug commands */
+	KVM_SEV_GUEST_STATUS,
+	KVM_SEV_DBG_DECRYPT,
+	KVM_SEV_DBG_ENCRYPT,
+
+	KVM_SEV_NR_MAX,
+};
+
+struct kvm_sev_cmd {
+	__u32 id;
+	__u64 data;
+	__u32 error;
+	__u32 sev_fd;
+};
+
+struct kvm_sev_launch_start {
+	__u32 handle;
+	__u32 policy;
+	__u64 dh_cert_data;
+	__u32 dh_cert_length;
+	__u64 session_data;
+	__u32 session_length;
+};
+
+struct kvm_sev_launch_update_data {
+	__u64 address;
+	__u32 length;
+};
+
+struct kvm_sev_launch_measure {
+	__u64 address;
+	__u32 length;
+};
+
+struct kvm_sev_send_start {
+	__u64 pdh_cert_data;
+	__u32 pdh_cert_length;
+	__u64 plat_cert_data;
+	__u32 plat_cert_length;
+	__u64 amd_cert_data;
+	__u32 amd_cert_length;
+	__u64 session_data;
+	__u32 session_length;
+};
+
+struct kvm_sev_send_update_data {
+	__u64 hdr_data;
+	__u32 hdr_length;
+	__u64 guest_address;
+	__u32 guest_length;
+	__u64 host_address;
+	__u32 host_length;
+};
+
+struct kvm_sev_receive_start {
+	__u32 handle;
+	__u64 pdh_cert_data;
+	__u32 pdh_cert_length;
+	__u64 session_data;
+	__u32 session_length;
+};
+
+struct kvm_sev_receive_update_data {
+	__u64 hdr_data;
+	__u32 hdr_length;
+	__u64 guest_address;
+	__u32 guest_length;
+	__u64 host_address;
+	__u32 host_length;
+};
+
+struct kvm_sev_guest_status {
+	__u32 handle;
+	__u32 policy;
+	__u32 state;
+};
+
+struct kvm_sev_dbg {
+	__u64 src_addr;
+	__u64 dst_addr;
+	__u32 length;
+};
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)

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

* [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file Brijesh Singh
@ 2017-03-08 20:51 ` Brijesh Singh
  2017-03-23 11:29   ` Stefan Hajnoczi
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 03/20] exec: add guest RAM read and write ops Brijesh Singh
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Add a new debug attribute, the attribute should be set when guest memory
accesses are performed for debug purposes.

The attribute will be used in SEV guest, where we need to distinguish normal
vs debug access to guest memory. In debug mode, we need to use SEV commands
to access the guest memory.

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] 41+ messages in thread

* [Qemu-devel] [RFC PATCH v4 03/20] exec: add guest RAM read and write ops
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute Brijesh Singh
@ 2017-03-08 20:51 ` Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 04/20] exec: add debug version of physical memory read and write api Brijesh Singh
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

In current implementation, read and write of the guest RAM is
performed using using memcpy(). The 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_debug_ops(mem, ops);

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 exec.c                |   55 ++++++++++++++++++++++++++++++++++++-------------
 include/exec/memory.h |   25 ++++++++++++++++++++++
 2 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/exec.c b/exec.c
index aabb035..48ae29c 100644
--- a/exec.c
+++ b/exec.c
@@ -2913,11 +2913,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;
@@ -2931,13 +2933,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_debug_ops) {
+                    mr->ram_debug_ops->read(buf, ptr, l, attrs);
+                } else {
+                    memcpy(buf, ptr, l);
+                }
+                break;
             case WRITE_DATA:
-                memcpy(ptr, buf, l);
+                if (mr->ram_debug_ops) {
+                    mr->ram_debug_ops->write(ptr, buf, l, attrs);
+                } else {
+                    memcpy(ptr, buf, l);
+                }
                 invalidate_and_set_dirty(mr, addr1, l);
                 break;
             case FLUSH_CACHE:
@@ -2956,7 +2978,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
 void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
                                    const 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, (uint8_t *)buf, len,
+            MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
 }
 
 void cpu_flush_icache_range(hwaddr start, int len)
@@ -2971,8 +2994,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 {
@@ -3308,6 +3333,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;
@@ -3316,6 +3342,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;
@@ -3323,14 +3353,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/memory.h b/include/exec/memory.h
index 6911023..e1d21cc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -163,6 +163,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 {
@@ -220,6 +232,7 @@ struct MemoryRegion {
     MemoryRegionIoeventfd *ioeventfds;
     QLIST_HEAD(, IOMMUNotifier) iommu_notify;
     IOMMUNotifierFlag iommu_notify_flags;
+    const MemoryRegionRAMReadWriteOps *ram_debug_ops;
 };
 
 /**
@@ -526,6 +539,18 @@ void memory_region_init_rom_device(MemoryRegion *mr,
                                    Error **errp);
 
 /**
+ * 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_debug_ops(MemoryRegion *mr,
+                               const MemoryRegionRAMReadWriteOps *ops)
+{
+    mr->ram_debug_ops = ops;
+}
+
+/**
  * memory_region_init_reservation: Initialize a memory region that reserves
  *                                 I/O space.
  *

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

* [Qemu-devel] [RFC PATCH v4 04/20] exec: add debug version of physical memory read and write api
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (2 preceding siblings ...)
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 03/20] exec: add guest RAM read and write ops Brijesh Singh
@ 2017-03-08 20:51 ` Brijesh Singh
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 05/20] monitor/i386: use debug apis when accessing guest memory Brijesh Singh
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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 48ae29c..772a959 100644
--- a/exec.c
+++ b/exec.c
@@ -3326,6 +3326,38 @@ static inline MemoryRegion *address_space_translate_cached(
 #define RCU_READ_UNLOCK()        ((void)0)
 #include "memory_ldst.inc.c"
 
+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;
+}
+
+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 b62f0d8..4a9c842 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -74,11 +74,26 @@ size_t qemu_ram_pagesize_largest(void);
 
 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)
 {
     cpu_physical_memory_rw(addr, buf, len, 0);
 }
+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);
+
 static inline void cpu_physical_memory_write(hwaddr addr,
                                              const void *buf, int len)
 {

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

* [Qemu-devel] [RFC PATCH v4 05/20] monitor/i386: use debug apis when accessing guest memory
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (3 preceding siblings ...)
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 04/20] exec: add debug version of physical memory read and write api Brijesh Singh
@ 2017-03-08 20:51 ` Brijesh Singh
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object Brijesh Singh
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:51 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

updates hmp monitor to use debug version of memory access apis when
reading 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  |   16 +++----
 target/i386/monitor.c |  114 +++++++++++++++++++++++++++++--------------------
 5 files changed, 79 insertions(+), 57 deletions(-)

diff --git a/cpus.c b/cpus.c
index c857ad2..5c3b596 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1906,7 +1906,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 d335c55..6d67de5 100644
--- a/disas.c
+++ b/disas.c
@@ -357,7 +357,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 ec7623e..4a1c772 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1350,7 +1350,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(cs, 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 e2af340..05395d7 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -1061,7 +1061,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             if (la57) {
                 pml5e_addr = ((env->cr[3] & ~0xfff) +
                         (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask;
-                pml5e = x86_ldq_phys(cs, pml5e_addr);
+                pml5e = ldq_phys_debug(cs, pml5e_addr);
                 if (!(pml5e & PG_PRESENT_MASK)) {
                     return -1;
                 }
@@ -1071,13 +1071,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
                     (((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;
             }
@@ -1092,14 +1092,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;
         }
@@ -1112,7 +1112,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;
@@ -1122,7 +1122,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)) {
@@ -1131,7 +1131,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 77ead60..7c39e05 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -59,14 +59,16 @@ static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
                    pte & PG_RW_MASK ? 'W' : '-');
 }
 
-static void tlb_info_32(Monitor *mon, CPUArchState *env)
+static void tlb_info_32(Monitor *mon, CPUState *cs)
 {
     unsigned int l1, l2;
     uint32_t pgd, pde, pte;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
 
     pgd = env->cr[3] & ~0xfff;
     for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
+        pde = ldl_phys_debug(cs, pgd + l1 * 4);
         pde = le32_to_cpu(pde);
         if (pde & PG_PRESENT_MASK) {
             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
@@ -74,7 +76,7 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env)
                 print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1));
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
+                    pte = ldl_phys_debug(cs, (pde & ~0xfff) + l2 * 4);
                     pte = le32_to_cpu(pte);
                     if (pte & PG_PRESENT_MASK) {
                         print_pte(mon, env, (l1 << 22) + (l2 << 12),
@@ -87,20 +89,22 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env)
     }
 }
 
-static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
+static void tlb_info_pae32(Monitor *mon, CPUState *cs)
 {
     unsigned int l1, l2, l3;
     uint64_t pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
 
     pdp_addr = env->cr[3] & ~0x1f;
     for (l1 = 0; l1 < 4; l1++) {
-        cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
+        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8);
         pdpe = le64_to_cpu(pdpe);
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
+                pde = ldq_phys_debug(cs, pd_addr + l2 * 8);
                 pde = le64_to_cpu(pde);
                 if (pde & PG_PRESENT_MASK) {
                     if (pde & PG_PSE_MASK) {
@@ -110,7 +114,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
+                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8);
                             pte = le64_to_cpu(pte);
                             if (pte & PG_PRESENT_MASK) {
                                 print_pte(mon, env, (l1 << 30) + (l2 << 21)
@@ -127,15 +131,17 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
 }
 
 #ifdef TARGET_X86_64
-static void tlb_info_la48(Monitor *mon, CPUArchState *env,
+static void tlb_info_la48(Monitor *mon, CPUState *cs,
         uint64_t l0, uint64_t pml4_addr)
 {
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
     uint64_t l1, l2, l3, l4;
     uint64_t pml4e, pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
 
     for (l1 = 0; l1 < 512; l1++) {
-        cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
+        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8);
         pml4e = le64_to_cpu(pml4e);
         if (!(pml4e & PG_PRESENT_MASK)) {
             continue;
@@ -143,7 +149,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
 
         pdp_addr = pml4e & 0x3fffffffff000ULL;
         for (l2 = 0; l2 < 512; l2++) {
-            cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
+            pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
             pdpe = le64_to_cpu(pdpe);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 continue;
@@ -158,7 +164,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
 
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l3 = 0; l3 < 512; l3++) {
-                cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
+                pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
                 pde = le64_to_cpu(pde);
                 if (!(pde & PG_PRESENT_MASK)) {
                     continue;
@@ -173,9 +179,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
 
                 pt_addr = pde & 0x3fffffffff000ULL;
                 for (l4 = 0; l4 < 512; l4++) {
-                    cpu_physical_memory_read(pt_addr
-                            + l4 * 8,
-                            &pte, 8);
+                    pte = ldq_phys_debug(cs, pt_addr + l4 * 8);
                     pte = le64_to_cpu(pte);
                     if (pte & PG_PRESENT_MASK) {
                         print_pte(mon, env, (l0 << 48) + (l1 << 39) +
@@ -188,18 +192,20 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
     }
 }
 
-static void tlb_info_la57(Monitor *mon, CPUArchState *env)
+static void tlb_info_la57(Monitor *mon, CPUState *cs)
 {
     uint64_t l0;
     uint64_t pml5e;
     uint64_t pml5_addr;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
 
     pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
     for (l0 = 0; l0 < 512; l0++) {
-        cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
+        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8);
         pml5e = le64_to_cpu(pml5e);
         if (pml5e & PG_PRESENT_MASK) {
-            tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL);
+            tlb_info_la48(mon, cs, l0, pml5e & 0x3fffffffff000ULL);
         }
     }
 }
@@ -207,9 +213,13 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env)
 
 void hmp_info_tlb(Monitor *mon, const QDict *qdict)
 {
+    X86CPU *cpu;
+    CPUState *cs;
     CPUArchState *env;
 
-    env = mon_get_cpu_env();
+    cs = mon_get_cpu();
+    cpu = X86_CPU(cs);
+    env = &cpu->env;
     if (!env) {
         monitor_printf(mon, "No CPU available\n");
         return;
@@ -223,17 +233,17 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
             if (env->cr[4] & CR4_LA57_MASK) {
-                tlb_info_la57(mon, env);
+                tlb_info_la57(mon, cs);
             } else {
-                tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL);
+                tlb_info_la48(mon, cs, 0, env->cr[3] & 0x3fffffffff000ULL);
             }
         } else
 #endif
         {
-            tlb_info_pae32(mon, env);
+            tlb_info_pae32(mon, cs);
         }
     } else {
-        tlb_info_32(mon, env);
+        tlb_info_32(mon, cs);
     }
 }
 
@@ -260,18 +270,20 @@ static void mem_print(Monitor *mon, hwaddr *pstart,
     }
 }
 
-static void mem_info_32(Monitor *mon, CPUArchState *env)
+static void mem_info_32(Monitor *mon, CPUState *cs)
 {
     unsigned int l1, l2;
     int prot, last_prot;
     uint32_t pgd, pde, pte;
     hwaddr start, end;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
 
     pgd = env->cr[3] & ~0xfff;
     last_prot = 0;
     start = -1;
     for(l1 = 0; l1 < 1024; l1++) {
-        cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
+        pde = ldl_phys_debug(cs, pgd + l1 * 4);
         pde = le32_to_cpu(pde);
         end = l1 << 22;
         if (pde & PG_PRESENT_MASK) {
@@ -280,7 +292,7 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
                 mem_print(mon, &start, &last_prot, end, prot);
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
-                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
+                    pte = ldl_phys_debug(cs, (pde & ~0xfff) + l2 * 4);
                     pte = le32_to_cpu(pte);
                     end = (l1 << 22) + (l2 << 12);
                     if (pte & PG_PRESENT_MASK) {
@@ -301,25 +313,27 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
     mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0);
 }
 
-static void mem_info_pae32(Monitor *mon, CPUArchState *env)
+static void mem_info_pae32(Monitor *mon, CPUState *cs)
 {
     unsigned int l1, l2, l3;
     int prot, last_prot;
     uint64_t pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
     hwaddr start, end;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
 
     pdp_addr = env->cr[3] & ~0x1f;
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 4; l1++) {
-        cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
+        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8);
         pdpe = le64_to_cpu(pdpe);
         end = l1 << 30;
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
+                pde = ldq_phys_debug(cs, pd_addr + l2 * 8);
                 pde = le64_to_cpu(pde);
                 end = (l1 << 30) + (l2 << 21);
                 if (pde & PG_PRESENT_MASK) {
@@ -330,7 +344,7 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
+                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8);
                             pte = le64_to_cpu(pte);
                             end = (l1 << 30) + (l2 << 21) + (l3 << 12);
                             if (pte & PG_PRESENT_MASK) {
@@ -358,10 +372,12 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
 
 
 #ifdef TARGET_X86_64
-static void mem_info_la48(Monitor *mon, CPUArchState *env)
+static void mem_info_la48(Monitor *mon, CPUState *cs)
 {
     int prot, last_prot;
     uint64_t l1, l2, l3, l4;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
     uint64_t pml4e, pdpe, pde, pte;
     uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
 
@@ -369,13 +385,13 @@ static void mem_info_la48(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);
+        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 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);
+                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
                 pdpe = le64_to_cpu(pdpe);
                 end = (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -387,7 +403,7 @@ static void mem_info_la48(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);
+                            pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
                             pde = le64_to_cpu(pde);
                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
                             if (pde & PG_PRESENT_MASK) {
@@ -399,9 +415,8 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
                                 } else {
                                     pt_addr = pde & 0x3fffffffff000ULL;
                                     for (l4 = 0; l4 < 512; l4++) {
-                                        cpu_physical_memory_read(pt_addr
-                                                                 + l4 * 8,
-                                                                 &pte, 8);
+                                        pte = ldq_phys_debug(cs,
+                                                             pt_addr + l4 * 8);
                                         pte = le64_to_cpu(pte);
                                         end = (l1 << 39) + (l2 << 30) +
                                             (l3 << 21) + (l4 << 12);
@@ -435,10 +450,12 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
     mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0);
 }
 
-static void mem_info_la57(Monitor *mon, CPUArchState *env)
+static void mem_info_la57(Monitor *mon, CPUState *cs)
 {
     int prot, last_prot;
     uint64_t l0, l1, l2, l3, l4;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUArchState *env = &cpu->env;
     uint64_t pml5e, pml4e, pdpe, pde, pte;
     uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
 
@@ -446,7 +463,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
     last_prot = 0;
     start = -1;
     for (l0 = 0; l0 < 512; l0++) {
-        cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
+        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8);
         pml4e = le64_to_cpu(pml5e);
         end = l0 << 48;
         if (!(pml5e & PG_PRESENT_MASK)) {
@@ -457,7 +474,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
 
         pml4_addr = pml5e & 0x3fffffffff000ULL;
         for (l1 = 0; l1 < 512; l1++) {
-            cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
+            pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8);
             pml4e = le64_to_cpu(pml4e);
             end = (l0 << 48) + (l1 << 39);
             if (!(pml4e & PG_PRESENT_MASK)) {
@@ -468,7 +485,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
 
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
+                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
                 pdpe = le64_to_cpu(pdpe);
                 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -487,7 +504,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
 
                 pd_addr = pdpe & 0x3fffffffff000ULL;
                 for (l3 = 0; l3 < 512; l3++) {
-                    cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
+                    pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
                     pde = le64_to_cpu(pde);
                     end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
                     if (pde & PG_PRESENT_MASK) {
@@ -506,7 +523,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
 
                     pt_addr = pde & 0x3fffffffff000ULL;
                     for (l4 = 0; l4 < 512; l4++) {
-                        cpu_physical_memory_read(pt_addr + l4 * 8, &pte, 8);
+                        pte = ldq_phys_debug(cs, pt_addr + l4 * 8);
                         pte = le64_to_cpu(pte);
                         end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
                             (l3 << 21) + (l4 << 12);
@@ -530,8 +547,13 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
 
 void hmp_info_mem(Monitor *mon, const QDict *qdict)
 {
+    X86CPU *cpu;
+    CPUState *cs;
     CPUArchState *env;
 
+    cs = mon_get_cpu();
+    cpu = X86_CPU(cs);
+    env = &cpu->env;
     env = mon_get_cpu_env();
     if (!env) {
         monitor_printf(mon, "No CPU available\n");
@@ -546,17 +568,17 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
             if (env->cr[4] & CR4_LA57_MASK) {
-                mem_info_la57(mon, env);
+                mem_info_la57(mon, cs);
             } else {
-                mem_info_la48(mon, env);
+                mem_info_la48(mon, cs);
             }
         } else
 #endif
         {
-            mem_info_pae32(mon, env);
+            mem_info_pae32(mon, cs);
         }
     } else {
-        mem_info_32(mon, env);
+        mem_info_32(mon, cs);
     }
 }
 

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

* [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (4 preceding siblings ...)
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 05/20] monitor/i386: use debug apis when accessing guest memory Brijesh Singh
@ 2017-03-08 20:52 ` Brijesh Singh
  2017-03-23 11:35   ` Stefan Hajnoczi
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support Brijesh Singh
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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

object provides two properties:

 1) debug: can be used to disable guest memory access from hypervisor.

   e.g to disable guest memory debug accesses

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

 2) memory-encryption: if hypervisor supports memory encryption then this
    property can be used to define object for encryption.

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

The memory-encryption property will be used for enabling AMD's SEV feature.

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        |  165 ++++++++++++++++++++++++++++++++++++++
 include/hw/boards.h              |    1 
 include/sysemu/security-policy.h |   75 +++++++++++++++++
 qemu-options.hx                  |   21 +++++
 7 files changed, 292 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 772a959..2c7c891 100644
--- a/exec.c
+++ b/exec.c
@@ -40,6 +40,7 @@
 #else /* !CONFIG_USER_ONLY */
 #include "hw/hw.h"
 #include "exec/memory.h"
+#include "sysemu/security-policy.h"
 #include "exec/ioport.h"
 #include "sysemu/dma.h"
 #include "sysemu/numa.h"
@@ -2926,6 +2927,12 @@ static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
     hwaddr addr1;
     MemoryRegion *mr;
 
+    /* Check if debug accesses is allowed */
+    if (attrs.debug &&
+        !security_policy_debug_allowed(current_machine->security_policy)) {
+        return;
+    }
+
     rcu_read_lock();
     while (len > 0) {
         l = len;
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 91450b2..3c413b1 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
 common-obj-$(CONFIG_SOFTMMU) += or-irq.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
+common-obj-$(CONFIG_SOFTMMU) += security-policy.o
 
 obj-$(CONFIG_SOFTMMU) += generic-loader.o
 obj-$(CONFIG_SOFTMMU) += null-machine.o
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 0699750..c14f59c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -332,6 +332,23 @@ 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 void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
     error_report("Option '-device %s' cannot be handled by this machine",
@@ -493,6 +510,11 @@ static void machine_class_init(ObjectClass *oc, void *data)
         &error_abort);
     object_class_property_set_description(oc, "enforce-config-section",
         "Set on to enforce configuration section migration", &error_abort);
+
+    object_class_property_add_str(oc, "security-policy",
+            machine_get_security_policy, machine_set_security_policy, NULL);
+    object_class_property_set_description(oc, "security-policy",
+            "Set the security policy for the machine", NULL);
 }
 
 static void machine_class_base_init(ObjectClass *oc, void *data)
diff --git a/hw/core/security-policy.c b/hw/core/security-policy.c
new file mode 100644
index 0000000..4d4658e
--- /dev/null
+++ b/hw/core/security-policy.c
@@ -0,0 +1,165 @@
+/*
+ * 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 "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 269d0ba..a1c99a0 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -153,6 +153,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 2292438..536db1b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4140,6 +4140,27 @@ contents of @code{iv.b64} to the second secret
 
 @end table
 
+@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' object.
+
 ETEXI
 
 

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

* [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (5 preceding siblings ...)
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object Brijesh Singh
@ 2017-03-08 20:52 ` Brijesh Singh
  2017-03-08 21:06   ` Eduardo Habkost
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 08/20] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Add high level API's to provide guest memory encryption support.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/kvm.h |    7 +++++++
 kvm-all.c            |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 kvm-stub.c           |   31 ++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 24281fc..6f88a06 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -227,6 +227,13 @@ int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
 int kvm_destroy_vcpu(CPUState *cpu);
 
+bool kvm_memcrypt_enabled(void);
+void *kvm_memcrypt_get_handle(void);
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr);
+int kvm_memcrypt_create_launch_context(void);
+int kvm_memcrypt_release_launch_context(void);
+int kvm_memcrypt_encrypt_launch_data(uint8_t *ptr, uint64_t len);
+
 #ifdef NEED_CPU_H
 #include "cpu.h"
 
diff --git a/kvm-all.c b/kvm-all.c
index 9040bd5..bba0f39 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -36,6 +36,7 @@
 #include "qemu/event_notifier.h"
 #include "trace-root.h"
 #include "hw/irq.h"
+#include "sysemu/security-policy.h"
 
 #include "hw/boards.h"
 
@@ -101,6 +102,13 @@ struct KVMState
 #endif
     KVMMemoryListener memory_listener;
     QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
+
+    /* memory encryption support */
+    void *ehandle;
+    int (*create_launch_context)(void *ehandle);
+    int (*release_launch_context)(void *ehandle);
+    int (*encrypt_launch_data)(void *ehandle, uint8_t *dst, uint64_t len);
+    void (*memcrypt_debug_ops)(void *ehandle, MemoryRegion *mr);
 };
 
 KVMState *kvm_state;
@@ -128,6 +136,50 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = {
     KVM_CAP_LAST_INFO
 };
 
+bool kvm_memcrypt_enabled(void)
+{
+    return kvm_state->ehandle ? true : false;
+}
+
+int kvm_memcrypt_create_launch_context(void)
+{
+    if (kvm_state->create_launch_context) {
+        return kvm_state->create_launch_context(kvm_state->ehandle);
+    }
+
+    return 1;
+}
+
+int kvm_memcrypt_release_launch_context(void)
+{
+    if (kvm_state->release_launch_context) {
+        return kvm_state->release_launch_context(kvm_state->ehandle);
+    }
+
+    return 1;
+}
+
+int kvm_memcrypt_encrypt_launch_data(uint8_t *dst, uint64_t len)
+{
+    if (kvm_state->encrypt_launch_data) {
+        return kvm_state->encrypt_launch_data(kvm_state->ehandle, dst, len);
+    }
+
+    return 1;
+}
+
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
+{
+    if (kvm_state->memcrypt_debug_ops) {
+        return kvm_state->memcrypt_debug_ops(kvm_state->ehandle, mr);
+    }
+}
+
+void *kvm_memcrypt_get_handle(void)
+{
+    return kvm_state->ehandle;
+}
+
 int kvm_get_max_memslots(void)
 {
     KVMState *s = KVM_STATE(current_machine->accelerator);
diff --git a/kvm-stub.c b/kvm-stub.c
index ef0c734..20920aa 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -105,6 +105,37 @@ int kvm_on_sigbus(int code, void *addr)
     return 1;
 }
 
+bool kvm_memcrypt_enabled(void)
+{
+    return false;
+}
+
+void *kvm_memcrypt_get_handle(void)
+{
+    return NULL;
+}
+
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
+{
+    return;
+}
+
+int kvm_memcrypt_create_launch_context(void)
+{
+    return 1;
+}
+
+int kvm_memcrypt_release_launch_context(void)
+{
+    return 1;
+}
+
+int kvm_memcrypt_encrypt_launch_data(uint8_t *ptr, uint64_t len)
+{
+    return 1;
+}
+
+
 #ifndef CONFIG_USER_ONLY
 int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
 {

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

* [Qemu-devel] [RFC PATCH v4 08/20] sev: add Secure Encrypted Virtulization (SEV) support
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (6 preceding siblings ...)
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support Brijesh Singh
@ 2017-03-08 20:52 ` Brijesh Singh
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm' Brijesh Singh
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Adds 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.

Patch adds the following new objects:

- sev-launch-info: provides the properties to get and set various parameters
  used to boot SEV guest from unencrypted boot images.

  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 owners PDH key provided through this object.

- sev-guest: a top level object to transition a guest into SEV-enabled

e.g to launch SEV guest from unencrypted boot images
 # $QEMU \
    -object sev-launch-info,id=launch0 \
    -object sev-guest,id=sev0 \
    -object security-policy,id=secure0,memory-encryption=sev0 \
    -machine ....,security-policy=secure0

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 Makefile.target                |    2 
 docs/amd-memory-encryption.txt |  121 ++++++++++++++++++++++
 include/sysemu/sev.h           |   91 ++++++++++++++++
 kvm-all.c                      |   22 ++++
 kvm-stub.c                     |    5 +
 qemu-options.hx                |   27 +++++
 sev.c                          |  225 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 492 insertions(+), 1 deletion(-)
 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 924304c..5150c12 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -142,7 +142,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..03e31c0
--- /dev/null
+++ b/docs/amd-memory-encryption.txt
@@ -0,0 +1,121 @@
+Secure Encrypted Virtualization (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  Secure
+Processor firmware which exposes commands for these tasks.
+
+At highest level the SEV key management APIs are divided into two sections:
+
+* Platform management commands
+* Guest management commands
+
+In this doc we will focus on Guest management commands. 
+
+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 deployment of SEV guest: the guest owner and
+the platform owner. For example, in a cloud environment, the platform owner
+would be cloud vendor and the guest owner would be the user that wishes to run
+their workload in the cloud.
+
+1. Guest Management Commands
+-----------------------------
+
+The guest management commands provide the support for common guest lifecycle
+events. These events include launching, running, snapshotting, migrating and
+decommission guest. The guest management commands are issued through
+KVM_MEMORY_ENCRYPTION_OPS ioctl.
+
+1.1 Launch
+
+When a guest is launched, its memory must first be encrypted using guest owners
+key before SEV can be enabled in hardware. There are two types of launches:
+
+1.1.1 unencrypted
+
+Boot images (such as bios, kernel, initrd) provided by the guest owner to
+bootstrap the guest is unencrypted. The firmware provides interfaces to
+bootstrap the memory encryption for this purpose: LAUNCH_START, LAUNCH_UPDATE,
+, LAUNCH_MEASURE and LAUNCH_FINISH. These four commands together generate a fresh
+memory encryption key for the guest, encrypt guest memory and provide an
+attestation of the successful launch.
+
+LAUNCH_START is called first to create a cryptographic launch context within the
+firmware. To create this context, guest owner must provide security policy,
+public Diffie-Hellman key (PDH defined in section 12 of SEV key API management)
+and session data. If PDH certificate blob is not provided by guest owner then
+firmware will auto generate a key and use that key for memory encryption. Guest
+owners PDH key is used to establish a cryptographic session with the guest owner
+to negotiate keys used for attestation. The guest security policy is a 4-byte
+data structure containing several flags that restrict what the hypervisor can do
+on the running SEV guest.  If the hypervisor requests this guest to share key
+with another SEV guest then hypervisor must set 'key-sharing' field in guest
+security policy and a shared SEV handle must be provided in LAUNCH_START command.
+
+LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
+created via LAUNCH_START command. If required this command can be called multiple
+times to encrypt different memory regions. The command also calculates the
+measurement of the memory contents as it encrypts.
+
+LAUNCH_MEASURE command can be used to retrieve the measurement of encrypted memory.
+This measurement is a signature of the memory contents that can be sent to the
+guest owner as an attestation that the memory was encrypted correctly by the
+firmware. The guest owner may wait to provide the guest confidential information
+until it can verify the attestation measurement. Since the guest owner knows the
+initial contents of the guest at boot, the attestation measurement can be
+verified by comparing it to what the guest owner expects.
+
+LAUNCH_FINISH command finalizes the guest launch and destory's the cryptographic
+context.
+
+See SEV API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
+complete flow chart.
+
+SEV support can be enabled via 'memory-encryption' parameters defined in
+security-policy object.
+
+Input to LAUNCH_START command can be provided through the properties defined in
+'sev-launch-info' object.
+
+e.g to launch SEV guest from unencrypted boot images
+
+# ${QEMU} \
+      -object sev-launch-info,id=launch0\
+      -object sev-guest,id=sev0\
+      -object security-policy,id=mypolicy,memory-encryption=sev0\
+      -machine ...,security-policy=mypolicy
+
+1.1.2 pre-encrypted
+
+1.2 Snapshot
+
+1.3 Restore
+
+1.4 Live Migration
+
+1.5 Debugging
+
+Since memory contents of SEV guest is encrypted hence hypervisor access to the
+guest memory will get a cipher text. If guest policy allows debugging, then
+hypervisor can use SEV debug command to decrypt guest memory region for debug
+purposes.
+
+2. References
+-----------------
+
+AMD Memory Encryption whitepaper:
+http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
+
+Secure Encrypted Virutualization Key Management:
+[1] http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
+
+KVM Forum slides:
+http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
+
+AMD64 Architecture Programmer's Manual:
+   http://support.amd.com/TechDocs/24593.pdf
+   SME is section 7.10
+   SEV is section 15.34
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
new file mode 100644
index 0000000..dbc3c6c
--- /dev/null
+++ b/include/sysemu/sev.h
@@ -0,0 +1,91 @@
+/*
+ * QEMU Secure Encrypted Virutualization (SEV) support
+ *
+ * Copyright: Advanced Micro Devices, 2016-2017
+ *
+ * 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_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 a SEV
+ * guest from unnencrypted boot images. SEV will encrypt the boot images using
+ * guest owner's key before launching the guest.
+ *
+ * # $QEMU -object sev-launch-info,id=launch0,dh-cert=0000,session=abcd \
+ *         ....
+ */
+struct QSevLaunchInfo {
+    Object parent_obj;
+};
+
+struct QSevLaunchInfoClass {
+    ObjectClass parent_class;
+};
+
+#define TYPE_QSEV_GUEST_INFO "sev-guest"
+#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 is used for creating a SEV guest.
+ *
+ * e.g to launch a SEV guest from unencrypted boot images
+ *
+ * # $QEMU -object sev-launch-info,id=launch0 \
+ *         -object sev-guest,id=sev0,sev-device=/dev/sev \
+ *         -object security-policy,id=secure0,memory-encryption=sev0 \
+ *         -machine ...security-policy=secure0
+ */
+struct QSevGuestInfo {
+    Object parent_obj;
+
+    char *sev_device;
+
+    QSevLaunchInfo *launch_info;
+};
+
+struct QSevGuestInfoClass {
+    ObjectClass parent_class;
+};
+
+struct SEVState {
+    QSevGuestInfo *sev_info;
+};
+
+typedef struct SEVState SEVState;
+
+
+bool sev_enabled(void);
+void *sev_guest_init(const char *keyid);
+void sev_set_debug_ops(void *handle, MemoryRegion *mr);
+
+#endif
+
diff --git a/kvm-all.c b/kvm-all.c
index bba0f39..1fa6413 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -37,6 +37,7 @@
 #include "trace-root.h"
 #include "hw/irq.h"
 #include "sysemu/security-policy.h"
+#include "sysemu/sev.h"
 
 #include "hw/boards.h"
 
@@ -1808,6 +1809,27 @@ 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 */
+            kvm_state->ehandle = sev_guest_init(id);
+            if (!kvm_state->ehandle) {
+                fprintf(stderr,
+                        "failed to initialize SEV guest\n");
+                goto err;
+            }
+            kvm_state->memcrypt_debug_ops = sev_set_debug_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/kvm-stub.c b/kvm-stub.c
index 20920aa..1a9838d 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -14,6 +14,7 @@
 #include "qemu-common.h"
 #include "cpu.h"
 #include "sysemu/kvm.h"
+#include "sysemu/sev.h"
 
 #ifndef CONFIG_USER_ONLY
 #include "hw/pci/msi.h"
@@ -135,6 +136,10 @@ int kvm_memcrypt_encrypt_launch_data(uint8_t *ptr, uint64_t len)
     return 1;
 }
 
+bool sev_enabled(void)
+{
+    return false;
+}
 
 #ifndef CONFIG_USER_ONLY
 int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
diff --git a/qemu-options.hx b/qemu-options.hx
index 536db1b..2b2d8c3 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4161,6 +4161,33 @@ can be set to the unquie ID of memory encryption object.
 
 On AMD processor, memory encryption is supported via 'sev-guest' object.
 
+@item -object sev-guest,id=@var{id},sev-device=@var{string}
+
+Create a Secure Encrypted Virtualization (SEV) guest object, which be used to
+provide the memory encryption support on AMD processors.
+
+e.g to launch a SEV guest
+@example
+ # $QEMU \
+     -object sev-launch-info,id=launch0,sev-device=/dev/sev0 \
+     -object sev-guest-info,id=sev0 \
+     -object security-policy,id=secure0-guest,memory-encryption=sev0 \
+     -machine ...,security-policy=secure0
+@end example
+
+@item -object sev-launch-info,id=@var{id}
+
+Create a SEV launch info object, which can be used to pass various parameters
+required to boot SEV guest from  unencrypted boot images.
+The id parameter is a unique ID that should be used in sev-guest-info object
+when creating a unencrypted SEV guest.
+
+e.g to launch SEV guest from unencrypted boot images
+@example
+ # $QEMU \
+     -object sev-launch-info,id=launch0\
+     -object sev-guest,id=sev0 \
+@end example
 ETEXI
 
 
diff --git a/sev.c b/sev.c
new file mode 100644
index 0000000..3e02453
--- /dev/null
+++ b/sev.c
@@ -0,0 +1,225 @@
+/*
+ * QEMU SEV support
+ *
+ * Copyright Advanced Micro Devices 2016-2017
+ *
+ * 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 "sysemu/sysemu.h"
+#include "trace.h"
+
+#define DEBUG_SEV
+#ifdef DEBUG_SEV
+#define DPRINTF(fmt, ...) \
+    do { fprintf(stdout, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+    do { } while (0)
+#endif
+
+#define DEFAULT_SEV_DEVICE      "/dev/sev1"
+
+static MemoryRegionRAMReadWriteOps sev_ops;
+static bool sev_allowed;
+static int sev_fd;
+
+static void
+qsev_guest_finalize(Object *obj)
+{
+}
+
+static char *
+qsev_guest_get_sev_device(Object *obj, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    return g_strdup(sev->sev_device);
+}
+
+static void
+qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    sev->sev_device = g_strdup(value);
+}
+
+static void
+qsev_guest_class_init(ObjectClass *oc, void *data)
+{
+    object_class_property_add_str(oc, "sev-device",
+                                  qsev_guest_get_sev_device,
+                                  qsev_guest_set_sev_device,
+                                  NULL);
+    object_class_property_set_description(oc, "sev-device",
+            "device to use for SEV command", 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 void
+qsev_guest_init(Object *obj)
+{
+    QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
+
+    object_property_add_link(obj, "launch", TYPE_QSEV_LAUNCH_INFO,
+                             (Object **)&sev->launch_info,
+                             object_property_allow_set_link,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
+
+    sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
+}
+
+/* sev guest info */
+static const TypeInfo qsev_guest_info = {
+    .parent = TYPE_OBJECT,
+    .name = TYPE_QSEV_GUEST_INFO,
+    .instance_size = sizeof(QSevGuestInfo),
+    .instance_finalize = qsev_guest_finalize,
+    .class_size = sizeof(QSevGuestInfoClass),
+    .class_init = qsev_guest_class_init,
+    .instance_init = qsev_guest_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+qsev_launch_finalize(Object *obj)
+{
+}
+
+static void
+qsev_launch_class_init(ObjectClass *oc, void *data)
+{
+    /* add launch properties */
+}
+
+static void
+qsev_launch_init(Object *obj)
+{
+}
+
+/* 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,
+    .instance_init = qsev_launch_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static int
+sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
+{
+    return 0;
+}
+
+static int
+sev_mem_read(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
+{
+    return 0;
+}
+
+void *
+sev_guest_init(const char *id)
+{
+    Object *obj;
+    SEVState *s;
+    char *sev_device_name;
+
+    s = g_malloc0(sizeof(SEVState));
+    if (!s) {
+        return NULL;
+    }
+
+    s->sev_info = lookup_sev_guest_info(id);
+    if (!s->sev_info) {
+        fprintf(stderr, "'%s' not a valid '%s' object\n",
+                id, TYPE_QSEV_GUEST_INFO);
+        goto err;
+    }
+
+    sev_device_name = object_property_get_str(OBJECT(s->sev_info),
+                                              "sev-device", NULL);
+    sev_fd = open(sev_device_name, O_RDWR);
+    if (sev_fd < 0) {
+        fprintf(stderr, "%s:%s\n", sev_device_name, strerror(errno));
+        goto err;
+    }
+    g_free(sev_device_name);
+
+    obj = object_resolve_path_type("", TYPE_QSEV_LAUNCH_INFO, NULL);
+    if (obj) {
+        object_property_set_link(OBJECT(s->sev_info), obj, "launch",
+                &error_abort);
+    }
+
+    sev_allowed = true;
+    return s;
+err:
+    g_free(s);
+    return NULL;
+}
+
+void
+sev_set_debug_ops(void *handle, MemoryRegion *mr)
+{
+    sev_ops.read = sev_mem_read;
+    sev_ops.write = sev_mem_write;
+
+    memory_region_set_ram_debug_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_launch_info);
+}
+
+type_init(sev_policy_register_types);

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

* [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm'
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (7 preceding siblings ...)
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 08/20] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
@ 2017-03-08 20:52 ` Brijesh Singh
  2017-03-08 21:43   ` Eric Blake
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 10/20] vl: add memory encryption support Brijesh Singh
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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 |    5 ++++-
 qmp.c            |    1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/hmp.c b/hmp.c
index 261843f..0b8b315 100644
--- a/hmp.c
+++ b/hmp.c
@@ -83,6 +83,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 6febfa7..e1dc847 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -185,9 +185,12 @@
 #
 # @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'} }
 
 ##
 # @query-kvm:
diff --git a/qmp.c b/qmp.c
index fa82b59..7b61c43 100644
--- a/qmp.c
+++ b/qmp.c
@@ -69,6 +69,7 @@ KvmInfo *qmp_query_kvm(Error **errp)
 
     info->enabled = kvm_enabled();
     info->present = kvm_available();
+    info->mem_encryption = kvm_memcrypt_enabled();
 
     return info;
 }

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

* [Qemu-devel] [RFC PATCH v4 10/20] vl: add memory encryption support
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (8 preceding siblings ...)
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm' Brijesh Singh
@ 2017-03-08 20:52 ` Brijesh Singh
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command Brijesh Singh
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:52 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

If memory encryption is enabled then create memory encryption launch
context to ensure that bootstrap data (bios images) get encrypted. Also
release the encryption context after machine is succesfully created.

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

diff --git a/vl.c b/vl.c
index 71b75ef..c6e7846 100644
--- a/vl.c
+++ b/vl.c
@@ -4521,6 +4521,14 @@ int main(int argc, char **argv, char **envp)
     current_machine->boot_order = boot_order;
     current_machine->cpu_model = cpu_model;
 
+    /* If memory encryption is enabled then create encryption context. */
+    if (kvm_memcrypt_enabled()) {
+        if (kvm_memcrypt_create_launch_context()) {
+            error_report("failed to create memory encryption context");
+            exit(1);
+        }
+    }
+
     machine_class->init(current_machine);
 
     realtime_init();
@@ -4671,6 +4679,13 @@ int main(int argc, char **argv, char **envp)
         vm_start();
     }
 
+    if (kvm_memcrypt_enabled()) {
+        if (kvm_memcrypt_release_launch_context()) {
+            error_report("failed to stop encryption context");
+            exit(1);
+        }
+    }
+
     os_setup_post();
 
     main_loop();

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

* [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (9 preceding siblings ...)
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 10/20] vl: add memory encryption support Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 21:13   ` Eduardo Habkost
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 12/20] SEV: add GUEST_STATUS command Brijesh Singh
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

The command is used to bootstrap SEV guest from unencrypted boot images.
The command creates a new VM encryption key (VEK) using guest owner's public
DH certificate, and security policy and session parameters. The encryption
key created during launch start process will be used for encryption the boot
images (such as BIOS).

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |    1 +
 kvm-all.c            |    1 +
 sev.c                |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index dbc3c6c..747fe87 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -86,6 +86,7 @@ typedef struct SEVState SEVState;
 bool sev_enabled(void);
 void *sev_guest_init(const char *keyid);
 void sev_set_debug_ops(void *handle, MemoryRegion *mr);
+int sev_create_launch_context(void *handle);
 
 #endif
 
diff --git a/kvm-all.c b/kvm-all.c
index 1fa6413..a13d62f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1826,6 +1826,7 @@ static int kvm_init(MachineState *ms)
                 goto err;
             }
             kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
+            kvm_state->create_launch_context = sev_create_launch_context;
             g_free(id);
         }
     }
diff --git a/sev.c b/sev.c
index 3e02453..4b3f39a 100644
--- a/sev.c
+++ b/sev.c
@@ -148,6 +148,55 @@ static const TypeInfo qsev_launch_info = {
 };
 
 static int
+sev_ioctl(int cmd, void *data, int *error)
+{
+    int r;
+    struct kvm_sev_cmd input;
+
+    input.id = cmd;
+    input.sev_fd = sev_fd;
+    input.data = (__u64)data;
+
+    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
+    *error = input.error;
+    return r;
+}
+
+static int
+sev_launch_start(SEVState *s)
+{
+    int ret = 1;
+    Object *obj;
+    int fw_error;
+    struct kvm_sev_launch_start *start;
+
+    if (!s) {
+        return 1;
+    }
+
+    start = g_malloc0(sizeof(*start));
+    if (!start) {
+        return 1;
+    }
+
+    obj = object_property_get_link(OBJECT(s->sev_info), "launch", &error_abort);
+    if (!obj) {
+        goto err;
+    }
+
+    ret = sev_ioctl(KVM_SEV_LAUNCH_START, start, &fw_error);
+    if (ret < 0) {
+        fprintf(stderr, "failed LAUNCH_START %d (%#x)\n", ret, fw_error);
+        goto err;
+    }
+
+    DPRINTF("SEV: LAUNCH_START\n");
+err:
+    g_free(start);
+    return ret;
+}
+
+static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
     return 0;
@@ -200,6 +249,12 @@ err:
     return NULL;
 }
 
+int
+sev_create_launch_context(void *handle)
+{
+    return sev_launch_start((SEVState *)handle);
+}
+
 void
 sev_set_debug_ops(void *handle, MemoryRegion *mr)
 {

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

* [Qemu-devel] [RFC PATCH v4 12/20] SEV: add GUEST_STATUS command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (10 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 13/20] sev: add LAUNCH_UPDATE_DATA command Brijesh Singh
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

The command is used to retrieve status information about an SEV-enabled guest.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |    9 +++++++++
 sev.c                |   28 ++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index 747fe87..88cbea5 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -82,6 +82,15 @@ struct SEVState {
 
 typedef struct SEVState SEVState;
 
+enum {
+    SEV_STATE_INVALID = 0,
+    SEV_STATE_LAUNCHING,
+    SEV_STATE_SECRET,
+    SEV_STATE_RUNNING,
+    SEV_STATE_RECEIVING,
+    SEV_STATE_SENDING,
+    SEV_STATE_MAX
+};
 
 bool sev_enabled(void);
 void *sev_guest_init(const char *keyid);
diff --git a/sev.c b/sev.c
index 4b3f39a..c13bbfd 100644
--- a/sev.c
+++ b/sev.c
@@ -197,6 +197,34 @@ err:
 }
 
 static int
+sev_get_current_state(SEVState *s)
+{
+    int error;
+    int ret = SEV_STATE_INVALID;
+    struct kvm_sev_guest_status *status;
+
+    if (!s) {
+        return ret;
+    }
+
+    status = g_malloc(sizeof(*status));
+    if (!status) {
+        return ret;
+    }
+
+    ret = sev_ioctl(KVM_SEV_GUEST_STATUS, status, &error);
+    if (ret) {
+        fprintf(stderr, "failed GUEST_STATUS %d (%#x)\n", ret, error);
+        goto err;
+    }
+
+    ret = status->state;
+err:
+    g_free(status);
+    return ret;
+}
+
+static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
     return 0;

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

* [Qemu-devel] [RFC PATCH v4 13/20] sev: add LAUNCH_UPDATE_DATA command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (11 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 12/20] SEV: add GUEST_STATUS command Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 14/20] sev: add LAUNCH_FINISH command Brijesh Singh
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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 for attestation.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |    2 +-
 kvm-all.c            |    1 +
 sev.c                |   44 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index 88cbea5..c614cc0 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -96,6 +96,6 @@ bool sev_enabled(void);
 void *sev_guest_init(const char *keyid);
 void sev_set_debug_ops(void *handle, MemoryRegion *mr);
 int sev_create_launch_context(void *handle);
-
+int sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len);
 #endif
 
diff --git a/kvm-all.c b/kvm-all.c
index a13d62f..5e98534 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1827,6 +1827,7 @@ static int kvm_init(MachineState *ms)
             }
             kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
             kvm_state->create_launch_context = sev_create_launch_context;
+            kvm_state->encrypt_launch_data = sev_encrypt_launch_buffer;
             g_free(id);
         }
     }
diff --git a/sev.c b/sev.c
index c13bbfd..b391012 100644
--- a/sev.c
+++ b/sev.c
@@ -225,9 +225,45 @@ err:
 }
 
 static int
+sev_launch_update_data(SEVState *s, uint8_t *addr, uint64_t len)
+{
+    int ret, error;
+    struct kvm_sev_launch_update_data *update;
+
+    if (!s) {
+        return 1;
+    }
+
+    update = g_malloc0(sizeof(*update));
+    if (!update) {
+        return 1;
+    }
+
+    update->address = (__u64)addr;
+    update->length = len;
+    ret = sev_ioctl(KVM_SEV_LAUNCH_UPDATE_DATA, update, &error);
+    if (ret) {
+        fprintf(stderr, "failed LAUNCH_UPDATE_DATA %d (%#x)\n", ret, error);
+        goto err;
+    }
+
+    DPRINTF("SEV: LAUNCH_UPDATE_DATA %#lx+%#lx\n", (unsigned long)addr, len);
+err:
+    g_free(update);
+    return ret;
+}
+
+static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
-    return 0;
+    SEVState *s = kvm_memcrypt_get_handle();
+
+    if (sev_get_current_state(s) == SEV_STATE_LAUNCHING) {
+        memcpy(dst, src, len);
+        return sev_launch_update_data(s, dst, len);
+    }
+
+    return 1;
 }
 
 static int
@@ -292,6 +328,12 @@ sev_set_debug_ops(void *handle, MemoryRegion *mr)
     memory_region_set_ram_debug_ops(mr, &sev_ops);
 }
 
+int
+sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len)
+{
+    return sev_launch_update_data((SEVState *)handle, ptr, len);
+}
+
 bool
 sev_enabled(void)
 {

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

* [Qemu-devel] [RFC PATCH v4 14/20] sev: add LAUNCH_FINISH command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (12 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 13/20] sev: add LAUNCH_UPDATE_DATA command Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 15/20] sev: add DEBUG_DECRYPT command Brijesh Singh
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |    1 +
 kvm-all.c            |    1 +
 sev.c                |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+)

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index c614cc0..7632202 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -97,5 +97,6 @@ void *sev_guest_init(const char *keyid);
 void sev_set_debug_ops(void *handle, MemoryRegion *mr);
 int sev_create_launch_context(void *handle);
 int sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len);
+int sev_release_launch_context(void *handle);
 #endif
 
diff --git a/kvm-all.c b/kvm-all.c
index 5e98534..92b4fbf 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1828,6 +1828,7 @@ static int kvm_init(MachineState *ms)
             kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
             kvm_state->create_launch_context = sev_create_launch_context;
             kvm_state->encrypt_launch_data = sev_encrypt_launch_buffer;
+            kvm_state->release_launch_context = sev_release_launch_context;
             g_free(id);
         }
     }
diff --git a/sev.c b/sev.c
index b391012..d32391e 100644
--- a/sev.c
+++ b/sev.c
@@ -253,6 +253,72 @@ err:
     return ret;
 }
 
+static void
+print_hex_dump(const char *prefix_str, uint8_t *data, int len)
+{
+    int i;
+
+    DPRINTF("%s: ", prefix_str);
+    for (i = 0; i < len; i++) {
+        DPRINTF("%02hhx", *data++);
+    }
+    DPRINTF("\n");
+}
+
+static int
+sev_launch_finish(SEVState *s)
+{
+    uint8_t *data;
+    int error, ret;
+    struct kvm_sev_launch_measure *measure;
+
+    if (!s) {
+        return 1;
+    }
+
+    measure = g_malloc0(sizeof(*measure));
+    if (!measure) {
+        return 1;
+    }
+
+    /* query measurement blob length */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measure, &error);
+    if (!measure->length) {
+        fprintf(stderr, "Error: failed to get launch measurement length\n");
+        ret = 1;
+        goto err_1;
+    }
+
+    data = g_malloc0(measure->length);
+    if (!data) {
+        goto err_1;
+    }
+    measure->address = (unsigned long)data;
+    /* get measurement */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measure, &error);
+    if (ret) {
+        fprintf(stderr, "failed LAUNCH_MEASURE %d (%#x)\n", ret, error);
+        goto err_2;
+    }
+
+    print_hex_dump("SEV: MEASUREMENT", data, measure->length);
+
+    /* finalize the launch */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_FINISH, 0, &error);
+    if (ret) {
+        fprintf(stderr, "failed LAUNCH_FINISH %d (%#x)\n", ret, error);
+        goto err_2;
+    }
+
+    DPRINTF("SEV: LAUNCH_FINISH\n");
+err_2:
+    g_free(data);
+err_1:
+    g_free(measure);
+
+    return ret;
+}
+
 static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
@@ -334,6 +400,12 @@ sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len)
     return sev_launch_update_data((SEVState *)handle, ptr, len);
 }
 
+int
+sev_release_launch_context(void *handle)
+{
+    return sev_launch_finish((SEVState *)handle);
+}
+
 bool
 sev_enabled(void)
 {

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

* [Qemu-devel] [RFC PATCH v4 15/20] sev: add DEBUG_DECRYPT command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (13 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 14/20] sev: add LAUNCH_FINISH command Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 16/20] sev: add DEBUG_ENCRYPT command Brijesh Singh
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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

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 |   36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/sev.c b/sev.c
index d32391e..f8d822d 100644
--- a/sev.c
+++ b/sev.c
@@ -320,6 +320,36 @@ err_1:
 }
 
 static int
+sev_debug_decrypt(SEVState *s, uint8_t *dst, const uint8_t *src, uint32_t len)
+{
+    int ret, error;
+    struct kvm_sev_dbg *dbg;
+
+    if (!s) {
+        return 1;
+    }
+
+    dbg = g_malloc0(sizeof(*dbg));
+    if (!dbg) {
+        return 1;
+    }
+
+    dbg->src_addr = (unsigned long)src;
+    dbg->dst_addr = (unsigned long)dst;
+    dbg->length = len;
+
+    ret = sev_ioctl(KVM_SEV_DBG_DECRYPT, dbg, &error);
+    if (ret) {
+        fprintf(stderr, "failed DBG_DECRYPT %d (%#x)\n", ret, error);
+        goto err;
+    }
+
+err:
+    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_memcrypt_get_handle();
@@ -335,7 +365,11 @@ sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 static int
 sev_mem_read(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
-    return 0;
+    SEVState *s = kvm_memcrypt_get_handle();
+
+    assert(attrs.debug);
+
+    return sev_debug_decrypt(s, dst, src, len);
 }
 
 void *

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

* [Qemu-devel] [RFC PATCH v4 16/20] sev: add DEBUG_ENCRYPT command
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (14 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 15/20] sev: add DEBUG_DECRYPT command Brijesh Singh
@ 2017-03-08 20:53 ` Brijesh Singh
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 17/20] target/i386: encrypt bios rom when memory encryption is enabled Brijesh Singh
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:53 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

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

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 |   39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/sev.c b/sev.c
index f8d822d..52b75e3 100644
--- a/sev.c
+++ b/sev.c
@@ -350,16 +350,49 @@ err:
 }
 
 static int
+sev_debug_encrypt(SEVState *s, uint8_t *dst, const uint8_t *src, uint32_t len)
+{
+    int ret, error;
+    struct kvm_sev_dbg *dbg;
+
+    if (!s) {
+        return 1;
+    }
+
+    dbg = g_malloc0(sizeof(*dbg));
+    if (!dbg) {
+        return 1;
+    }
+
+    dbg->src_addr = (unsigned long)src;
+    dbg->dst_addr = (unsigned long)dst;
+    dbg->length = len;
+
+    ret = sev_ioctl(KVM_SEV_DBG_ENCRYPT, dbg, &error);
+    if (ret) {
+        fprintf(stderr, "failed DBG_ENCRYPT %d (%#x)\n", ret, error);
+        goto err;
+    }
+
+err:
+    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_memcrypt_get_handle();
 
-    if (sev_get_current_state(s) == SEV_STATE_LAUNCHING) {
+    if (attrs.debug) {
+        return sev_debug_encrypt(s, dst, src, len);
+    } else if (sev_get_current_state(s) == SEV_STATE_LAUNCHING) {
         memcpy(dst, src, len);
         return sev_launch_update_data(s, dst, len);
+    } else {
+        return 1;
     }
-
-    return 1;
 }
 
 static int

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

* [Qemu-devel] [RFC PATCH v4 17/20] target/i386: encrypt bios rom when memory encryption is enabled
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (15 preceding siblings ...)
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 16/20] sev: add DEBUG_ENCRYPT command Brijesh Singh
@ 2017-03-08 20:54 ` Brijesh Singh
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f Brijesh Singh
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

If guest is launched with memory encryption enabled then we encrypt the
data copied into pflash device also set the debug ops for PC.BIOS, PC.RAM
and PLFASH memory regions. This will ensure that any debug access to these
memory region will go through the memory encryption APIs. It cover both plfash
type of device as well as passing the bios image via -bios option in qemu
command line.

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

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d24388e..a0c0816 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1392,6 +1392,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 debug read and write to guest memory from hypervisor will
+     * go through encryption routines. */
+    if (kvm_memcrypt_enabled()) {
+        kvm_memcrypt_set_debug_ops(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..518a341 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -47,7 +47,7 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
                              MemoryRegion *flash_mem,
                              int ram_size)
 {
-    int isa_bios_size;
+    int ret, isa_bios_size;
     MemoryRegion *isa_bios;
     uint64_t flash_size;
     void *flash_ptr, *isa_bios_ptr;
@@ -72,6 +72,15 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
            ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
            isa_bios_size);
 
+    /* If memory encryption is enabled then encrypt the ISA rom */
+    if (kvm_memcrypt_enabled()) {
+        ret = kvm_memcrypt_encrypt_launch_data(isa_bios_ptr, isa_bios_size);
+        if (ret) {
+            fprintf(stderr, "Error: failed to encrypt isa_bios image\n");
+        }
+        kvm_memcrypt_set_debug_ops(isa_bios);
+    }
+
     memory_region_set_readonly(isa_bios, true);
 }
 
@@ -103,6 +112,7 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
  */
 static void pc_system_flash_init(MemoryRegion *rom_memory)
 {
+    int ret;
     int unit;
     DriveInfo *pflash_drv;
     BlockBackend *blk;
@@ -113,6 +123,8 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
     pflash_t *system_flash;
     MemoryRegion *flash_mem;
     char name[64];
+    void *flash_ptr;
+    int flash_size;
 
     sector_bits = 12;
     sector_size = 1 << sector_bits;
@@ -168,7 +180,20 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
                                              0      /* be */);
         if (unit == 0) {
             flash_mem = pflash_cfi01_get_memory(system_flash);
+
             pc_isa_bios_init(rom_memory, flash_mem, size);
+
+            /* Encrypt the pflash boot ROM */
+            if (kvm_memcrypt_enabled()) {
+                flash_ptr = memory_region_get_ram_ptr(flash_mem);
+                flash_size = memory_region_size(flash_mem);
+                ret = kvm_memcrypt_encrypt_launch_data(flash_ptr, flash_size);
+                if (ret) {
+                    fprintf(stderr, "Error: failed to encrypt %s\n", name);
+                    exit(1);
+                }
+                kvm_memcrypt_set_debug_ops(flash_mem);
+            }
         }
     }
 }
@@ -208,6 +233,9 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
     }
     g_free(filename);
 
+    if (kvm_memcrypt_enabled()) {
+        kvm_memcrypt_set_debug_ops(bios);
+    }
     /* map the last 128KB of the BIOS in ISA space */
     isa_bios_size = bios_size;
     if (isa_bios_size > (128 * 1024)) {

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

* [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (16 preceding siblings ...)
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 17/20] target/i386: encrypt bios rom when memory encryption is enabled Brijesh Singh
@ 2017-03-08 20:54 ` Brijesh Singh
  2017-03-08 21:29   ` Eduardo Habkost
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 19/20] target/i386: clear memory encryption bit when walking SEV guest page table Brijesh Singh
                   ` (3 subsequent siblings)
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Fn8000_001f cpuid provides the memory encryption (aka C-bit) location
in a page table for the SEV-enabled guest.

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

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fba9212..44662eb 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -40,6 +40,7 @@
 #include "qapi/visitor.h"
 #include "qom/qom-qobject.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/sev.h"
 
 #if defined(CONFIG_KVM)
 #include <linux/kvm_para.h>
@@ -2966,6 +2967,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] 41+ messages in thread

* [Qemu-devel] [RFC PATCH v4 19/20] target/i386: clear memory encryption bit when walking SEV guest page table
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (17 preceding siblings ...)
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f Brijesh Singh
@ 2017-03-08 20:54 ` Brijesh Singh
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active Brijesh Singh
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

In SEV-enabled guest the pte entry 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  |   39 ++++++++++++++++++-----
 target/i386/monitor.c |   83 +++++++++++++++++++++++++++++++++++++------------
 2 files changed, 94 insertions(+), 28 deletions(-)

diff --git a/target/i386/helper.c b/target/i386/helper.c
index 05395d7..bbdef4d 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -22,6 +22,7 @@
 #include "exec/exec-all.h"
 #include "sysemu/kvm.h"
 #include "kvm_i386.h"
+#include "sysemu/sev.h"
 #ifndef CONFIG_USER_ONLY
 #include "sysemu/sysemu.h"
 #include "sysemu/hw_accel.h"
@@ -1029,6 +1030,22 @@ do_check_protect_pse36:
     return 1;
 }
 
+static uint64_t get_me_mask(void)
+{
+    uint64_t me_mask = 0;
+
+    /*
+     * When SEV is active, Fn8000_001F[EBX] Bit 0:5 contains the C-bit position
+     */
+    if (sev_enabled()) {
+        uint32_t pos;
+        pos = kvm_arch_get_supported_cpuid(kvm_state, 0x8000001f, 0, R_EBX);
+        me_mask = (1UL << (pos & 0x3f));
+    }
+
+    return ~me_mask;
+}
+
 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     X86CPU *cpu = X86_CPU(cs);
@@ -1037,6 +1054,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;
@@ -1061,7 +1084,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
             if (la57) {
                 pml5e_addr = ((env->cr[3] & ~0xfff) +
                         (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask;
-                pml5e = ldq_phys_debug(cs, pml5e_addr);
+                pml5e = ldq_phys_debug(cs, pml5e_addr) & me_mask;
                 if (!(pml5e & PG_PRESENT_MASK)) {
                     return -1;
                 }
@@ -1071,13 +1094,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 
             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
                     (((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;
             }
@@ -1092,14 +1115,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;
         }
@@ -1112,7 +1135,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;
@@ -1122,7 +1145,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 = ldl_phys_debug(cs, pde_addr);
+        pde = ldl_phys_debug(cs, pde_addr) & me_mask;
         if (!(pde & PG_PRESENT_MASK))
             return -1;
         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
@@ -1131,7 +1154,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 7c39e05..04982fa 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"
 
 
@@ -59,6 +60,22 @@ static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
                    pte & PG_RW_MASK ? 'W' : '-');
 }
 
+static uint64_t get_me_mask(void)
+{
+    uint64_t me_mask = 0;
+
+    /*
+     * When SEV is active, Fn8000_001F[EBX] Bit 0:5 contains the C-bit position
+     */
+    if (sev_enabled()) {
+        uint32_t pos;
+        pos = kvm_arch_get_supported_cpuid(kvm_state, 0x8000001f, 0, R_EBX);
+        me_mask = (1UL << (pos & 0x3f));
+    }
+
+    return ~me_mask;
+}
+
 static void tlb_info_32(Monitor *mon, CPUState *cs)
 {
     unsigned int l1, l2;
@@ -96,15 +113,19 @@ static void tlb_info_pae32(Monitor *mon, CPUState *cs)
     uint64_t pdp_addr, pd_addr, pt_addr;
     X86CPU *cpu = X86_CPU(cs);
     CPUArchState *env = &cpu->env;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     pdp_addr = env->cr[3] & ~0x1f;
+    pdp_addr &= me_mask;
     for (l1 = 0; l1 < 4; l1++) {
-        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8);
+        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8) & me_mask;
         pdpe = le64_to_cpu(pdpe);
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                pde = ldq_phys_debug(cs, pd_addr + l2 * 8);
+                pde = ldq_phys_debug(cs, pd_addr + l2 * 8) & me_mask;
                 pde = le64_to_cpu(pde);
                 if (pde & PG_PRESENT_MASK) {
                     if (pde & PG_PSE_MASK) {
@@ -114,7 +135,8 @@ static void tlb_info_pae32(Monitor *mon, CPUState *cs)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8);
+                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8)
+                                        & me_mask;
                             pte = le64_to_cpu(pte);
                             if (pte & PG_PRESENT_MASK) {
                                 print_pte(mon, env, (l1 << 30) + (l2 << 21)
@@ -131,6 +153,7 @@ static void tlb_info_pae32(Monitor *mon, CPUState *cs)
 }
 
 #ifdef TARGET_X86_64
+
 static void tlb_info_la48(Monitor *mon, CPUState *cs,
         uint64_t l0, uint64_t pml4_addr)
 {
@@ -139,9 +162,12 @@ static void tlb_info_la48(Monitor *mon, CPUState *cs,
     uint64_t l1, l2, l3, l4;
     uint64_t pml4e, pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     for (l1 = 0; l1 < 512; l1++) {
-        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8);
+        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8) & me_mask;
         pml4e = le64_to_cpu(pml4e);
         if (!(pml4e & PG_PRESENT_MASK)) {
             continue;
@@ -149,7 +175,7 @@ static void tlb_info_la48(Monitor *mon, CPUState *cs,
 
         pdp_addr = pml4e & 0x3fffffffff000ULL;
         for (l2 = 0; l2 < 512; l2++) {
-            pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
+            pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8) & me_mask;
             pdpe = le64_to_cpu(pdpe);
             if (!(pdpe & PG_PRESENT_MASK)) {
                 continue;
@@ -164,7 +190,7 @@ static void tlb_info_la48(Monitor *mon, CPUState *cs,
 
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l3 = 0; l3 < 512; l3++) {
-                pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
+                pde = ldq_phys_debug(cs, pd_addr + l3 * 8) & me_mask;
                 pde = le64_to_cpu(pde);
                 if (!(pde & PG_PRESENT_MASK)) {
                     continue;
@@ -179,7 +205,7 @@ static void tlb_info_la48(Monitor *mon, CPUState *cs,
 
                 pt_addr = pde & 0x3fffffffff000ULL;
                 for (l4 = 0; l4 < 512; l4++) {
-                    pte = ldq_phys_debug(cs, pt_addr + l4 * 8);
+                    pte = ldq_phys_debug(cs, pt_addr + l4 * 8) & me_mask;
                     pte = le64_to_cpu(pte);
                     if (pte & PG_PRESENT_MASK) {
                         print_pte(mon, env, (l0 << 48) + (l1 << 39) +
@@ -199,10 +225,14 @@ static void tlb_info_la57(Monitor *mon, CPUState *cs)
     uint64_t pml5_addr;
     X86CPU *cpu = X86_CPU(cs);
     CPUArchState *env = &cpu->env;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
+    pml5_addr &= me_mask;
     for (l0 = 0; l0 < 512; l0++) {
-        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8);
+        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8) & me_mask;
         pml5e = le64_to_cpu(pml5e);
         if (pml5e & PG_PRESENT_MASK) {
             tlb_info_la48(mon, cs, l0, pml5e & 0x3fffffffff000ULL);
@@ -322,18 +352,22 @@ static void mem_info_pae32(Monitor *mon, CPUState *cs)
     hwaddr start, end;
     X86CPU *cpu = X86_CPU(cs);
     CPUArchState *env = &cpu->env;
+    uint64_t me_mask;
+
+    me_mask = get_me_mask();
 
     pdp_addr = env->cr[3] & ~0x1f;
+    pdp_addr &= me_mask;
     last_prot = 0;
     start = -1;
     for (l1 = 0; l1 < 4; l1++) {
-        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8);
+        pdpe = ldq_phys_debug(cs, pdp_addr + l1 * 8) & me_mask;
         pdpe = le64_to_cpu(pdpe);
         end = l1 << 30;
         if (pdpe & PG_PRESENT_MASK) {
             pd_addr = pdpe & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                pde = ldq_phys_debug(cs, pd_addr + l2 * 8);
+                pde = ldq_phys_debug(cs, pd_addr + l2 * 8) & me_mask;
                 pde = le64_to_cpu(pde);
                 end = (l1 << 30) + (l2 << 21);
                 if (pde & PG_PRESENT_MASK) {
@@ -344,7 +378,8 @@ static void mem_info_pae32(Monitor *mon, CPUState *cs)
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8);
+                            pte = ldq_phys_debug(cs, pt_addr + l3 * 8)
+                                        & me_mask;
                             pte = le64_to_cpu(pte);
                             end = (l1 << 30) + (l2 << 21) + (l3 << 12);
                             if (pte & PG_PRESENT_MASK) {
@@ -380,18 +415,22 @@ static void mem_info_la48(Monitor *mon, CPUState *cs)
     CPUArchState *env = &cpu->env;
     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++) {
-        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8);
+        pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8) & 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++) {
-                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
+                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8) & me_mask;
                 pdpe = le64_to_cpu(pdpe);
                 end = (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -403,7 +442,8 @@ static void mem_info_la48(Monitor *mon, CPUState *cs)
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
-                            pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
+                            pde = ldq_phys_debug(cs, pd_addr + l3 * 8)
+                                        & me_mask;
                             pde = le64_to_cpu(pde);
                             end = (l1 << 39) + (l2 << 30) + (l3 << 21);
                             if (pde & PG_PRESENT_MASK) {
@@ -458,12 +498,15 @@ static void mem_info_la57(Monitor *mon, CPUState *cs)
     CPUArchState *env = &cpu->env;
     uint64_t pml5e, pml4e, pdpe, pde, pte;
     uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
+    uint64_t me_mask;
 
-    pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
+    me_mask = get_me_mask();
+
+    pml5_addr = env->cr[3] & 0x3fffffffff000ULL & me_mask;
     last_prot = 0;
     start = -1;
     for (l0 = 0; l0 < 512; l0++) {
-        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8);
+        pml5e = ldq_phys_debug(cs, pml5_addr + l0 * 8) & me_mask;
         pml4e = le64_to_cpu(pml5e);
         end = l0 << 48;
         if (!(pml5e & PG_PRESENT_MASK)) {
@@ -474,7 +517,7 @@ static void mem_info_la57(Monitor *mon, CPUState *cs)
 
         pml4_addr = pml5e & 0x3fffffffff000ULL;
         for (l1 = 0; l1 < 512; l1++) {
-            pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8);
+            pml4e = ldq_phys_debug(cs, pml4_addr + l1 * 8) & me_mask;
             pml4e = le64_to_cpu(pml4e);
             end = (l0 << 48) + (l1 << 39);
             if (!(pml4e & PG_PRESENT_MASK)) {
@@ -485,7 +528,7 @@ static void mem_info_la57(Monitor *mon, CPUState *cs)
 
             pdp_addr = pml4e & 0x3fffffffff000ULL;
             for (l2 = 0; l2 < 512; l2++) {
-                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8);
+                pdpe = ldq_phys_debug(cs, pdp_addr + l2 * 8) & me_mask;
                 pdpe = le64_to_cpu(pdpe);
                 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
@@ -504,7 +547,7 @@ static void mem_info_la57(Monitor *mon, CPUState *cs)
 
                 pd_addr = pdpe & 0x3fffffffff000ULL;
                 for (l3 = 0; l3 < 512; l3++) {
-                    pde = ldq_phys_debug(cs, pd_addr + l3 * 8);
+                    pde = ldq_phys_debug(cs, pd_addr + l3 * 8) & me_mask;
                     pde = le64_to_cpu(pde);
                     end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
                     if (pde & PG_PRESENT_MASK) {
@@ -523,7 +566,7 @@ static void mem_info_la57(Monitor *mon, CPUState *cs)
 
                     pt_addr = pde & 0x3fffffffff000ULL;
                     for (l4 = 0; l4 < 512; l4++) {
-                        pte = ldq_phys_debug(cs, pt_addr + l4 * 8);
+                        pte = ldq_phys_debug(cs, pt_addr + l4 * 8) & me_mask;
                         pte = le64_to_cpu(pte);
                         end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
                             (l3 << 21) + (l4 << 12);

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

* [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (18 preceding siblings ...)
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 19/20] target/i386: clear memory encryption bit when walking SEV guest page table Brijesh Singh
@ 2017-03-08 20:54 ` Brijesh Singh
  2017-03-08 21:32   ` Eduardo Habkost
  2017-03-08 21:27 ` [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Eduardo Habkost
  2017-03-08 22:29 ` no-reply
  21 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 20:54 UTC (permalink / raw)
  To: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky, brijesh.singh

Snapshot, Restore and Migration is not implemented yet. Return error when
user tries to perform any of these operations.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 migration/migration.c |    7 +++++++
 migration/savevm.c    |   11 +++++++++++
 2 files changed, 18 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index 3dab684..287c72b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -37,6 +37,7 @@
 #include "io/channel-buffer.h"
 #include "io/channel-tls.h"
 #include "migration/colo.h"
+#include "sysemu/sev.h"
 
 #define MAX_THROTTLE  (32 << 20)      /* Migration transfer speed throttling */
 
@@ -1221,6 +1222,12 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
         error_setg(errp, QERR_MIGRATION_ACTIVE);
         return;
     }
+
+    if (sev_enabled()) {
+        error_setg(errp, "Migration is not implemented");
+        return;
+    }
+
     if (runstate_check(RUN_STATE_INMIGRATE)) {
         error_setg(errp, "Guest is waiting for an incoming migration");
         return;
diff --git a/migration/savevm.c b/migration/savevm.c
index 3b19a4a..bf6e9b0 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -54,6 +54,7 @@
 #include "qemu/cutils.h"
 #include "io/channel-buffer.h"
 #include "io/channel-file.h"
+#include "sysemu/sev.h"
 
 #ifndef ETH_P_RARP
 #define ETH_P_RARP 0x8035
@@ -2084,6 +2085,11 @@ int save_vmstate(Monitor *mon, const char *name)
     Error *local_err = NULL;
     AioContext *aio_context;
 
+    if (sev_enabled()) {
+        monitor_printf(mon, "savevm is not implemented\n");
+        return -1;
+    }
+
     if (!bdrv_all_can_snapshot(&bs)) {
         monitor_printf(mon, "Device '%s' is writable but does not "
                        "support snapshots.\n", bdrv_get_device_name(bs));
@@ -2245,6 +2251,11 @@ int load_vmstate(const char *name)
     AioContext *aio_context;
     MigrationIncomingState *mis = migration_incoming_get_current();
 
+    if (sev_enabled()) {
+        error_report("loadvm is not implemented");
+        return -ENOTSUP;
+    }
+
     if (!bdrv_all_can_snapshot(&bs)) {
         error_report("Device '%s' is writable but does not support snapshots.",
                      bdrv_get_device_name(bs));

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

* Re: [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support Brijesh Singh
@ 2017-03-08 21:06   ` Eduardo Habkost
  0 siblings, 0 replies; 41+ messages in thread
From: Eduardo Habkost @ 2017-03-08 21:06 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: crosthwaite.peter, armbru, mst, p.fedin, qemu-devel, lcapitulino,
	pbonzini, rth, Thomas.Lendacky

On Wed, Mar 08, 2017 at 03:52:26PM -0500, Brijesh Singh wrote:
> Add high level API's to provide guest memory encryption support.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  include/sysemu/kvm.h |    7 +++++++
>  kvm-all.c            |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  kvm-stub.c           |   31 ++++++++++++++++++++++++++++++
>  3 files changed, 90 insertions(+)
> 
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 24281fc..6f88a06 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -227,6 +227,13 @@ int kvm_init_vcpu(CPUState *cpu);
>  int kvm_cpu_exec(CPUState *cpu);
>  int kvm_destroy_vcpu(CPUState *cpu);
>  
> +bool kvm_memcrypt_enabled(void);
> +void *kvm_memcrypt_get_handle(void);
> +void kvm_memcrypt_set_debug_ops(MemoryRegion *mr);
> +int kvm_memcrypt_create_launch_context(void);
> +int kvm_memcrypt_release_launch_context(void);
> +int kvm_memcrypt_encrypt_launch_data(uint8_t *ptr, uint64_t len);

Please document what the return value of those functions mean.

[...]
> +int kvm_memcrypt_create_launch_context(void)
> +{
> +    if (kvm_state->create_launch_context) {
> +        return kvm_state->create_launch_context(kvm_state->ehandle);
> +    }
> +
> +    return 1;

I suggest returning -ENOTSUP if not implemented.

> +}
> +
> +int kvm_memcrypt_release_launch_context(void)
> +{
> +    if (kvm_state->release_launch_context) {
> +        return kvm_state->release_launch_context(kvm_state->ehandle);
> +    }
> +
> +    return 1;
> +}
> +
> +int kvm_memcrypt_encrypt_launch_data(uint8_t *dst, uint64_t len)
> +{
> +    if (kvm_state->encrypt_launch_data) {
> +        return kvm_state->encrypt_launch_data(kvm_state->ehandle, dst, len);
> +    }
> +
> +    return 1;
> +}
> +
> +void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
> +{
> +    if (kvm_state->memcrypt_debug_ops) {
> +        return kvm_state->memcrypt_debug_ops(kvm_state->ehandle, mr);
> +    }
> +}
> +
> +void *kvm_memcrypt_get_handle(void)
> +{
> +    return kvm_state->ehandle;
> +}
> +
>  int kvm_get_max_memslots(void)
>  {
>      KVMState *s = KVM_STATE(current_machine->accelerator);
> diff --git a/kvm-stub.c b/kvm-stub.c
> index ef0c734..20920aa 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -105,6 +105,37 @@ int kvm_on_sigbus(int code, void *addr)
>      return 1;
>  }
>  
> +bool kvm_memcrypt_enabled(void)
> +{
> +    return false;
> +}
> +
> +void *kvm_memcrypt_get_handle(void)
> +{
> +    return NULL;
> +}
> +
> +void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
> +{
> +    return;
> +}
> +
> +int kvm_memcrypt_create_launch_context(void)
> +{
> +    return 1;
> +}
> +
> +int kvm_memcrypt_release_launch_context(void)
> +{
> +    return 1;
> +}
> +
> +int kvm_memcrypt_encrypt_launch_data(uint8_t *ptr, uint64_t len)
> +{
> +    return 1;
> +}
> +
> +
>  #ifndef CONFIG_USER_ONLY
>  int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
>  {
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command
  2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command Brijesh Singh
@ 2017-03-08 21:13   ` Eduardo Habkost
  2017-03-08 21:39     ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Eduardo Habkost @ 2017-03-08 21:13 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: crosthwaite.peter, armbru, mst, p.fedin, qemu-devel, lcapitulino,
	pbonzini, rth, Thomas.Lendacky

On Wed, Mar 08, 2017 at 03:53:03PM -0500, Brijesh Singh wrote:
> The command is used to bootstrap SEV guest from unencrypted boot images.
> The command creates a new VM encryption key (VEK) using guest owner's public
> DH certificate, and security policy and session parameters. The encryption
> key created during launch start process will be used for encryption the boot
> images (such as BIOS).
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>

These descriptions of what the commands do are very useful. I
suggest including something similar (but more generic and not
SEV-specific?) as the documentation of the kvm_memcrypt_*() API
functions, as it is not clear what each kvm_memcrypt_*() function
is supposed to do.


> ---
>  include/sysemu/sev.h |    1 +
>  kvm-all.c            |    1 +
>  sev.c                |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 57 insertions(+)
> 
> diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
> index dbc3c6c..747fe87 100644
> --- a/include/sysemu/sev.h
> +++ b/include/sysemu/sev.h
> @@ -86,6 +86,7 @@ typedef struct SEVState SEVState;
>  bool sev_enabled(void);
>  void *sev_guest_init(const char *keyid);
>  void sev_set_debug_ops(void *handle, MemoryRegion *mr);
> +int sev_create_launch_context(void *handle);
>  
>  #endif
>  
> diff --git a/kvm-all.c b/kvm-all.c
> index 1fa6413..a13d62f 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1826,6 +1826,7 @@ static int kvm_init(MachineState *ms)
>                  goto err;
>              }
>              kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
> +            kvm_state->create_launch_context = sev_create_launch_context;
>              g_free(id);
>          }
>      }
> diff --git a/sev.c b/sev.c
> index 3e02453..4b3f39a 100644
> --- a/sev.c
> +++ b/sev.c
> @@ -148,6 +148,55 @@ static const TypeInfo qsev_launch_info = {
>  };
>  
>  static int
> +sev_ioctl(int cmd, void *data, int *error)
> +{
> +    int r;
> +    struct kvm_sev_cmd input;
> +
> +    input.id = cmd;
> +    input.sev_fd = sev_fd;
> +    input.data = (__u64)data;
> +
> +    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
> +    *error = input.error;
> +    return r;
> +}
> +
> +static int
> +sev_launch_start(SEVState *s)
> +{
> +    int ret = 1;
> +    Object *obj;
> +    int fw_error;
> +    struct kvm_sev_launch_start *start;
> +
> +    if (!s) {
> +        return 1;
> +    }
> +
> +    start = g_malloc0(sizeof(*start));
> +    if (!start) {
> +        return 1;
> +    }
> +
> +    obj = object_property_get_link(OBJECT(s->sev_info), "launch", &error_abort);
> +    if (!obj) {
> +        goto err;
> +    }
> +
> +    ret = sev_ioctl(KVM_SEV_LAUNCH_START, start, &fw_error);
> +    if (ret < 0) {
> +        fprintf(stderr, "failed LAUNCH_START %d (%#x)\n", ret, fw_error);
> +        goto err;
> +    }
> +
> +    DPRINTF("SEV: LAUNCH_START\n");
> +err:
> +    g_free(start);
> +    return ret;
> +}
> +
> +static int
>  sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
>  {
>      return 0;
> @@ -200,6 +249,12 @@ err:
>      return NULL;
>  }
>  
> +int
> +sev_create_launch_context(void *handle)
> +{
> +    return sev_launch_start((SEVState *)handle);
> +}
> +
>  void
>  sev_set_debug_ops(void *handle, MemoryRegion *mr)
>  {
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD)
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (19 preceding siblings ...)
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active Brijesh Singh
@ 2017-03-08 21:27 ` Eduardo Habkost
  2017-03-08 21:37   ` Brijesh Singh
  2017-03-08 22:29 ` no-reply
  21 siblings, 1 reply; 41+ messages in thread
From: Eduardo Habkost @ 2017-03-08 21:27 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: crosthwaite.peter, armbru, mst, p.fedin, qemu-devel, lcapitulino,
	pbonzini, rth, Thomas.Lendacky

On Wed, Mar 08, 2017 at 03:51:07PM -0500, Brijesh Singh wrote:
> 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.
> 
> The KVM RFC introduced a new ioctl (KVM_MEMORY_ENCRYPTION_OP) which can be
> used by qemu to issue the SEV commands to assist performing common hypervisor
> activities such as a launching, running, snapshooting, migration and debugging
> guests.
> 
> 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

I am looking for detailed CPUID documentation, and latest version
of Volume 3 I can find
(http://support.amd.com/TechDocs/24594.pdf) is from June 2015 and
doesn't include CPUID Fn8000_001F.

Is there a public updated version of AMD64 Architecture
Programmer's Manual Volume 3 including SEV CPUID info?

> 
> Secure Encrypted Virutualization Key Management:
> http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
> 
> KVM Forum slides:
> http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
> 
> KVM RFC link:
> 
> [1] http://marc.info/?l=linux-mm&m=148846752931115&w=2
> 
> Video of the KVM Forum Talk:
> https://www.youtube.com/watch?v=RcvQ1xN55Ew
> 
[...]

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f Brijesh Singh
@ 2017-03-08 21:29   ` Eduardo Habkost
  0 siblings, 0 replies; 41+ messages in thread
From: Eduardo Habkost @ 2017-03-08 21:29 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: crosthwaite.peter, armbru, mst, p.fedin, qemu-devel, lcapitulino,
	pbonzini, rth, Thomas.Lendacky

On Wed, Mar 08, 2017 at 03:54:20PM -0500, Brijesh Singh wrote:
> Fn8000_001f cpuid provides the memory encryption (aka C-bit) location
> in a page table for the SEV-enabled guest.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  target/i386/cpu.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index fba9212..44662eb 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -40,6 +40,7 @@
>  #include "qapi/visitor.h"
>  #include "qom/qom-qobject.h"
>  #include "sysemu/arch_init.h"
> +#include "sysemu/sev.h"
>  
>  #if defined(CONFIG_KVM)
>  #include <linux/kvm_para.h>
> @@ -2966,6 +2967,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);

This doesn't look future-proof. The architecture may be extended
to include CPUID bits that we can't expose to the guest unless we
implement host-side support for it.

I suggest including only the specific bits we know we can really
expose to the guest, instead of exposing raw host CPUID directly.

Also, exposing only explicitly configured CPUID bits will make it
easier to implement migration support in the future.

> +        }
> +        break;
>      case 0xC0000000:
>          *eax = env->cpuid_xlevel2;
>          *ebx = 0;
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active
  2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active Brijesh Singh
@ 2017-03-08 21:32   ` Eduardo Habkost
  2017-03-08 21:40     ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Eduardo Habkost @ 2017-03-08 21:32 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: crosthwaite.peter, armbru, mst, p.fedin, qemu-devel, lcapitulino,
	pbonzini, rth, Thomas.Lendacky

On Wed, Mar 08, 2017 at 03:54:43PM -0500, Brijesh Singh wrote:
> Snapshot, Restore and Migration is not implemented yet. Return error when
> user tries to perform any of these operations.
> 
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
> ---
>  migration/migration.c |    7 +++++++
>  migration/savevm.c    |   11 +++++++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index 3dab684..287c72b 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -37,6 +37,7 @@
>  #include "io/channel-buffer.h"
>  #include "io/channel-tls.h"
>  #include "migration/colo.h"
> +#include "sysemu/sev.h"
>  
>  #define MAX_THROTTLE  (32 << 20)      /* Migration transfer speed throttling */
>  
> @@ -1221,6 +1222,12 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
>          error_setg(errp, QERR_MIGRATION_ACTIVE);
>          return;
>      }
> +
> +    if (sev_enabled()) {
> +        error_setg(errp, "Migration is not implemented");
> +        return;
> +    }
> +

You can do this more easily by registering a migration blocker
using migrate_add_blocker() when initializing SEV.

-- 
Eduardo

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

* Re: [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD)
  2017-03-08 21:27 ` [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Eduardo Habkost
@ 2017-03-08 21:37   ` Brijesh Singh
  0 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 21:37 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: brijesh.singh, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky



On 03/08/2017 03:27 PM, Eduardo Habkost wrote:
> On Wed, Mar 08, 2017 at 03:51:07PM -0500, Brijesh Singh wrote:
>> 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.
>>
>> The KVM RFC introduced a new ioctl (KVM_MEMORY_ENCRYPTION_OP) which can be
>> used by qemu to issue the SEV commands to assist performing common hypervisor
>> activities such as a launching, running, snapshooting, migration and debugging
>> guests.
>>
>> 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
>
> I am looking for detailed CPUID documentation, and latest version
> of Volume 3 I can find
> (http://support.amd.com/TechDocs/24594.pdf) is from June 2015 and
> doesn't include CPUID Fn8000_001F.
>
> Is there a public updated version of AMD64 Architecture
> Programmer's Manual Volume 3 including SEV CPUID info?
>

Right now the SEV specific CPUID is in AMD64 APM volume 2 [1].

[1] http://support.amd.com/TechDocs/24593.pdf

I will ask around to check when documentation team will update volume 3 to include this CPUID.

~ Brijesh

>>
>> Secure Encrypted Virutualization Key Management:
>> http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
>>
>> KVM Forum slides:
>> http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
>>
>> KVM RFC link:
>>
>> [1] http://marc.info/?l=linux-mm&m=148846752931115&w=2
>>
>> Video of the KVM Forum Talk:
>> https://www.youtube.com/watch?v=RcvQ1xN55Ew
>>
> [...]
>

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

* Re: [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command
  2017-03-08 21:13   ` Eduardo Habkost
@ 2017-03-08 21:39     ` Brijesh Singh
  0 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 21:39 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: brijesh.singh, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky



On 03/08/2017 03:13 PM, Eduardo Habkost wrote:
> On Wed, Mar 08, 2017 at 03:53:03PM -0500, Brijesh Singh wrote:
>> The command is used to bootstrap SEV guest from unencrypted boot images.
>> The command creates a new VM encryption key (VEK) using guest owner's public
>> DH certificate, and security policy and session parameters. The encryption
>> key created during launch start process will be used for encryption the boot
>> images (such as BIOS).
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>
> These descriptions of what the commands do are very useful. I
> suggest including something similar (but more generic and not
> SEV-specific?) as the documentation of the kvm_memcrypt_*() API
> functions, as it is not clear what each kvm_memcrypt_*() function
> is supposed to do.
>

Thanks for quick feedback. I will include some generic documentation of the kvm_memcrypt_*() APIs.

-Brijesh

>
>> ---
>>  include/sysemu/sev.h |    1 +
>>  kvm-all.c            |    1 +
>>  sev.c                |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 57 insertions(+)
>>
>> diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
>> index dbc3c6c..747fe87 100644
>> --- a/include/sysemu/sev.h
>> +++ b/include/sysemu/sev.h
>> @@ -86,6 +86,7 @@ typedef struct SEVState SEVState;
>>  bool sev_enabled(void);
>>  void *sev_guest_init(const char *keyid);
>>  void sev_set_debug_ops(void *handle, MemoryRegion *mr);
>> +int sev_create_launch_context(void *handle);
>>
>>  #endif
>>
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 1fa6413..a13d62f 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -1826,6 +1826,7 @@ static int kvm_init(MachineState *ms)
>>                  goto err;
>>              }
>>              kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
>> +            kvm_state->create_launch_context = sev_create_launch_context;
>>              g_free(id);
>>          }
>>      }
>> diff --git a/sev.c b/sev.c
>> index 3e02453..4b3f39a 100644
>> --- a/sev.c
>> +++ b/sev.c
>> @@ -148,6 +148,55 @@ static const TypeInfo qsev_launch_info = {
>>  };
>>
>>  static int
>> +sev_ioctl(int cmd, void *data, int *error)
>> +{
>> +    int r;
>> +    struct kvm_sev_cmd input;
>> +
>> +    input.id = cmd;
>> +    input.sev_fd = sev_fd;
>> +    input.data = (__u64)data;
>> +
>> +    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
>> +    *error = input.error;
>> +    return r;
>> +}
>> +
>> +static int
>> +sev_launch_start(SEVState *s)
>> +{
>> +    int ret = 1;
>> +    Object *obj;
>> +    int fw_error;
>> +    struct kvm_sev_launch_start *start;
>> +
>> +    if (!s) {
>> +        return 1;
>> +    }
>> +
>> +    start = g_malloc0(sizeof(*start));
>> +    if (!start) {
>> +        return 1;
>> +    }
>> +
>> +    obj = object_property_get_link(OBJECT(s->sev_info), "launch", &error_abort);
>> +    if (!obj) {
>> +        goto err;
>> +    }
>> +
>> +    ret = sev_ioctl(KVM_SEV_LAUNCH_START, start, &fw_error);
>> +    if (ret < 0) {
>> +        fprintf(stderr, "failed LAUNCH_START %d (%#x)\n", ret, fw_error);
>> +        goto err;
>> +    }
>> +
>> +    DPRINTF("SEV: LAUNCH_START\n");
>> +err:
>> +    g_free(start);
>> +    return ret;
>> +}
>> +
>> +static int
>>  sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
>>  {
>>      return 0;
>> @@ -200,6 +249,12 @@ err:
>>      return NULL;
>>  }
>>
>> +int
>> +sev_create_launch_context(void *handle)
>> +{
>> +    return sev_launch_start((SEVState *)handle);
>> +}
>> +
>>  void
>>  sev_set_debug_ops(void *handle, MemoryRegion *mr)
>>  {
>>
>

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

* Re: [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active
  2017-03-08 21:32   ` Eduardo Habkost
@ 2017-03-08 21:40     ` Brijesh Singh
  0 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-08 21:40 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: brijesh.singh, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky



On 03/08/2017 03:32 PM, Eduardo Habkost wrote:
> On Wed, Mar 08, 2017 at 03:54:43PM -0500, Brijesh Singh wrote:
>> Snapshot, Restore and Migration is not implemented yet. Return error when
>> user tries to perform any of these operations.
>>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  migration/migration.c |    7 +++++++
>>  migration/savevm.c    |   11 +++++++++++
>>  2 files changed, 18 insertions(+)
>>
>> diff --git a/migration/migration.c b/migration/migration.c
>> index 3dab684..287c72b 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -37,6 +37,7 @@
>>  #include "io/channel-buffer.h"
>>  #include "io/channel-tls.h"
>>  #include "migration/colo.h"
>> +#include "sysemu/sev.h"
>>
>>  #define MAX_THROTTLE  (32 << 20)      /* Migration transfer speed throttling */
>>
>> @@ -1221,6 +1222,12 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
>>          error_setg(errp, QERR_MIGRATION_ACTIVE);
>>          return;
>>      }
>> +
>> +    if (sev_enabled()) {
>> +        error_setg(errp, "Migration is not implemented");
>> +        return;
>> +    }
>> +
>
> You can do this more easily by registering a migration blocker
> using migrate_add_blocker() when initializing SEV.
>

Thanks for tip, I was not aware of migrate_add_blocker(), I will look at using in next rev.

-Brijesh

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

* Re: [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm'
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm' Brijesh Singh
@ 2017-03-08 21:43   ` Eric Blake
  0 siblings, 0 replies; 41+ messages in thread
From: Eric Blake @ 2017-03-08 21:43 UTC (permalink / raw)
  To: Brijesh Singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth
  Cc: Thomas.Lendacky

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

On 03/08/2017 02:52 PM, 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
> @@ -185,9 +185,12 @@
>  #
>  # @present: true if KVM acceleration is built into this executable
>  #
> +# @mem-encryption: true if Memory Encryption is active (since 2.8)

You've missed 2.8, and probably even 2.9, unless you can argue that this
is a bug-fix appropriate during soft freeze.  So this should be since 2.10.

> +#
>  # Since: 0.14.0
>  ##
> -{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
> +{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool',
> +            'mem-encryption' : 'bool'} }
>  


-- 
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] 41+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD)
  2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
                   ` (20 preceding siblings ...)
  2017-03-08 21:27 ` [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Eduardo Habkost
@ 2017-03-08 22:29 ` no-reply
  21 siblings, 0 replies; 41+ messages in thread
From: no-reply @ 2017-03-08 22:29 UTC (permalink / raw)
  To: brijesh.singh
  Cc: famz, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky

Hi,

This 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.

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

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=16
make docker-test-quick@centos6
make docker-test-mingw@fedora
make docker-test-build@min-glib
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
0e6d2f1 migration: disable save/restore and migration when SEV is active
5b188e9 target/i386: clear memory encryption bit when walking SEV guest page table
07894ea target/i386: add cpuid Fn8000_001f
27b9e53 target/i386: encrypt bios rom when memory encryption is enabled
8b63a82 sev: add DEBUG_ENCRYPT command
189b255 sev: add DEBUG_DECRYPT command
b0fff7a sev: add LAUNCH_FINISH command
e3caf4f sev: add LAUNCH_UPDATE_DATA command
39d860d SEV: add GUEST_STATUS command
50aa58c sev: add LAUNCH_START command
73fabb6 vl: add memory encryption support
db32057 hmp: display memory encryption support in 'info kvm'
b40c656 sev: add Secure Encrypted Virtulization (SEV) support
f988aa7 kvm: add memory encryption api support
2b8cba1 core: add new security-policy object
7a3a11c monitor/i386: use debug apis when accessing guest memory
8e6cd32 exec: add debug version of physical memory read and write api
767da59 exec: add guest RAM read and write ops
b01a313 memattrs: add debug attribute
52f6b0e kvm: update kvm.h header file

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'fa8bc7f928ac25f23532afc8beb2073efc8fb063'
  BUILD   centos6
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-0dx45yo9/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY    RUNNER
    RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache     tar git make gcc g++     zlib-devel glib2-devel SDL-devel pixman-devel     epel-release
HOSTNAME=d4bca5d1e110
TERM=xterm
MAKEFLAGS= -j16
HISTSIZE=1000
J=16
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix    /var/tmp/qemu-build/install
BIOS directory    /var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/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 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -mcx16 -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 -Wno-missing-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
HAX support       no
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
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
debug stack usage no
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
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
mkdir -p dtc/libfdt
mkdir -p dtc/tests
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     config-host.h
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     qemu-options.def
  GEN     qapi-types.h
  GEN     qmp-commands.h
  GEN     qapi-visit.h
  GEN     qapi-event.h
  GEN     qmp-introspect.h
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.h
  GEN     module_block.h
  GEN     tests/test-qapi-types.h
  GEN     tests/test-qapi-visit.h
  GEN     tests/test-qmp-commands.h
  GEN     x86_64-softmmu/config-devices.mak
  GEN     aarch64-softmmu/config-devices.mak
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace-root.h
  GEN     util/trace.h
  GEN     crypto/trace.h
  GEN     io/trace.h
  GEN     migration/trace.h
  GEN     block/trace.h
  GEN     backends/trace.h
  GEN     hw/block/trace.h
  GEN     hw/block/dataplane/trace.h
  GEN     hw/char/trace.h
  GEN     hw/intc/trace.h
  GEN     hw/net/trace.h
  GEN     hw/virtio/trace.h
  GEN     hw/audio/trace.h
  GEN     hw/misc/trace.h
  GEN     hw/usb/trace.h
  GEN     hw/scsi/trace.h
  GEN     hw/nvram/trace.h
  GEN     hw/display/trace.h
  GEN     hw/input/trace.h
  GEN     hw/timer/trace.h
  GEN     hw/dma/trace.h
  GEN     hw/sparc/trace.h
  GEN     hw/sd/trace.h
  GEN     hw/isa/trace.h
  GEN     hw/mem/trace.h
  GEN     hw/i386/trace.h
  GEN     hw/i386/xen/trace.h
  GEN     hw/9pfs/trace.h
  GEN     hw/ppc/trace.h
  GEN     hw/pci/trace.h
  GEN     hw/s390x/trace.h
  GEN     hw/vfio/trace.h
  GEN     hw/acpi/trace.h
  GEN     hw/arm/trace.h
  GEN     hw/alpha/trace.h
  GEN     hw/xen/trace.h
  GEN     ui/trace.h
  GEN     audio/trace.h
  GEN     net/trace.h
  GEN     target/arm/trace.h
  GEN     target/i386/trace.h
  GEN     target/sparc/trace.h
  GEN     target/s390x/trace.h
  GEN     target/ppc/trace.h
  GEN     qom/trace.h
  GEN     linux-user/trace.h
  GEN     qapi/trace.h
  GEN     config-all-devices.mak
	 DEP /tmp/qemu-test/src/dtc/tests/dumptrees.c
	 DEP /tmp/qemu-test/src/dtc/tests/trees.S
	 DEP /tmp/qemu-test/src/dtc/tests/testutils.c
	 DEP /tmp/qemu-test/src/dtc/tests/value-labels.c
	 DEP /tmp/qemu-test/src/dtc/tests/asm_tree_dump.c
	 DEP /tmp/qemu-test/src/dtc/tests/truncated_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/check_path.c
	 DEP /tmp/qemu-test/src/dtc/tests/overlay_bad_fixup.c
	 DEP /tmp/qemu-test/src/dtc/tests/overlay.c
	 DEP /tmp/qemu-test/src/dtc/tests/subnode_iterate.c
	 DEP /tmp/qemu-test/src/dtc/tests/property_iterate.c
	 DEP /tmp/qemu-test/src/dtc/tests/integer-expressions.c
	 DEP /tmp/qemu-test/src/dtc/tests/add_subnode_with_nops.c
	 DEP /tmp/qemu-test/src/dtc/tests/path_offset_aliases.c
	 DEP /tmp/qemu-test/src/dtc/tests/utilfdt_test.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_unordered.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtb_reverse.c
	 DEP /tmp/qemu-test/src/dtc/tests/dtbs_equal_ordered.c
	 DEP /tmp/qemu-test/src/dtc/tests/extra-terminating-null.c
	 DEP /tmp/qemu-test/src/dtc/tests/incbin.c
	 DEP /tmp/qemu-test/src/dtc/tests/boot-cpuid.c
	 DEP /tmp/qemu-test/src/dtc/tests/phandle_format.c
	 DEP /tmp/qemu-test/src/dtc/tests/path-references.c
	 DEP /tmp/qemu-test/src/dtc/tests/references.c
	 DEP /tmp/qemu-test/src/dtc/tests/string_escapes.c
	 DEP /tmp/qemu-test/src/dtc/tests/propname_escapes.c
	 DEP /tmp/qemu-test/src/dtc/tests/appendprop2.c
	 DEP /tmp/qemu-test/src/dtc/tests/appendprop1.c
	 DEP /tmp/qemu-test/src/dtc/tests/del_node.c
	 DEP /tmp/qemu-test/src/dtc/tests/del_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/setprop.c
	 DEP /tmp/qemu-test/src/dtc/tests/set_name.c
	 DEP /tmp/qemu-test/src/dtc/tests/rw_tree1.c
	 DEP /tmp/qemu-test/src/dtc/tests/open_pack.c
	 DEP /tmp/qemu-test/src/dtc/tests/nopulate.c
	 DEP /tmp/qemu-test/src/dtc/tests/mangle-layout.c
	 DEP /tmp/qemu-test/src/dtc/tests/move_and_save.c
	 DEP /tmp/qemu-test/src/dtc/tests/sw_tree1.c
	 DEP /tmp/qemu-test/src/dtc/tests/nop_node.c
	 DEP /tmp/qemu-test/src/dtc/tests/nop_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/setprop_inplace.c
	 DEP /tmp/qemu-test/src/dtc/tests/addr_size_cells.c
	 DEP /tmp/qemu-test/src/dtc/tests/stringlist.c
	 DEP /tmp/qemu-test/src/dtc/tests/notfound.c
	 DEP /tmp/qemu-test/src/dtc/tests/sized_cells.c
	 DEP /tmp/qemu-test/src/dtc/tests/char_literal.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_alias.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_compatible.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_check_compatible.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_phandle.c
	 DEP /tmp/qemu-test/src/dtc/tests/node_offset_by_prop_value.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_path.c
	 DEP /tmp/qemu-test/src/dtc/tests/parent_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/supernode_atdepth_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_phandle.c
	 DEP /tmp/qemu-test/src/dtc/tests/getprop.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_name.c
	 DEP /tmp/qemu-test/src/dtc/tests/path_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/subnode_offset.c
	 DEP /tmp/qemu-test/src/dtc/tests/find_property.c
	 DEP /tmp/qemu-test/src/dtc/tests/get_mem_rsv.c
	 DEP /tmp/qemu-test/src/dtc/tests/root_node.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_overlay.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_addresses.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_strerror.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_empty_tree.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_rw.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_sw.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_wip.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt_ro.c
	 DEP /tmp/qemu-test/src/dtc/libfdt/fdt.c
	 DEP /tmp/qemu-test/src/dtc/util.c
	 DEP /tmp/qemu-test/src/dtc/fdtput.c
	 DEP /tmp/qemu-test/src/dtc/fdtdump.c
	 DEP /tmp/qemu-test/src/dtc/fdtget.c
	 LEX convert-dtsv0-lexer.lex.c
	 DEP /tmp/qemu-test/src/dtc/srcpos.c
make[1]: flex: Command not found
	 BISON dtc-parser.tab.c
make[1]: bison: Command not found
	 LEX dtc-lexer.lex.c
make[1]: flex: Command not found
	 DEP /tmp/qemu-test/src/dtc/treesource.c
	 DEP /tmp/qemu-test/src/dtc/livetree.c
	 DEP /tmp/qemu-test/src/dtc/fstree.c
	 DEP /tmp/qemu-test/src/dtc/flattree.c
	 DEP /tmp/qemu-test/src/dtc/data.c
	 DEP /tmp/qemu-test/src/dtc/dtc.c
	 DEP /tmp/qemu-test/src/dtc/checks.c
	CHK version_gen.h
	 LEX convert-dtsv0-lexer.lex.c
make[1]: flex: Command not found
	UPD version_gen.h
	 BISON dtc-parser.tab.c
	 LEX dtc-lexer.lex.c
make[1]: bison: Command not found
make[1]: flex: Command not found
	 DEP /tmp/qemu-test/src/dtc/util.c
	 LEX convert-dtsv0-lexer.lex.c
make[1]: flex: Command not found
	 BISON dtc-parser.tab.c
	 LEX dtc-lexer.lex.c
make[1]: bison: Command not found
make[1]: flex: Command not found
	 CC libfdt/fdt.o
	 CC libfdt/fdt_ro.o
	 CC libfdt/fdt_rw.o
	 CC libfdt/fdt_wip.o
	 CC libfdt/fdt_overlay.o
	 CC libfdt/fdt_sw.o
	 CC libfdt/fdt_strerror.o
	 CC libfdt/fdt_empty_tree.o
	 CC libfdt/fdt_addresses.o
	 AR libfdt/libfdt.a
ar: creating libfdt/libfdt.a
a - libfdt/fdt.o
a - libfdt/fdt_ro.o
a - libfdt/fdt_wip.o
a - libfdt/fdt_sw.o
a - libfdt/fdt_rw.o
a - libfdt/fdt_strerror.o
a - libfdt/fdt_empty_tree.o
a - libfdt/fdt_addresses.o
a - libfdt/fdt_overlay.o
	 LEX convert-dtsv0-lexer.lex.c
	 BISON dtc-parser.tab.c
make[1]: flex: Command not found
make[1]: 	 LEX dtc-lexer.lex.c
bison: Command not found
make[1]: flex: Command not found
  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     trace-root.c
  GEN     util/trace.c
  GEN     crypto/trace.c
  GEN     io/trace.c
  GEN     migration/trace.c
  GEN     block/trace.c
  GEN     backends/trace.c
  GEN     hw/block/trace.c
  GEN     hw/block/dataplane/trace.c
  GEN     hw/char/trace.c
  GEN     hw/intc/trace.c
  GEN     hw/net/trace.c
  GEN     hw/virtio/trace.c
  GEN     hw/audio/trace.c
  GEN     hw/misc/trace.c
  GEN     hw/usb/trace.c
  GEN     hw/scsi/trace.c
  GEN     hw/nvram/trace.c
  GEN     hw/display/trace.c
  GEN     hw/input/trace.c
  GEN     hw/timer/trace.c
  GEN     hw/dma/trace.c
  GEN     hw/sparc/trace.c
  GEN     hw/sd/trace.c
  GEN     hw/isa/trace.c
  GEN     hw/mem/trace.c
  GEN     hw/i386/trace.c
  GEN     hw/i386/xen/trace.c
  GEN     hw/9pfs/trace.c
  GEN     hw/ppc/trace.c
  GEN     hw/pci/trace.c
  GEN     hw/s390x/trace.c
  GEN     hw/vfio/trace.c
  GEN     hw/acpi/trace.c
  GEN     hw/arm/trace.c
  GEN     hw/alpha/trace.c
  GEN     hw/xen/trace.c
  GEN     ui/trace.c
  GEN     audio/trace.c
  GEN     net/trace.c
  GEN     target/arm/trace.c
  GEN     target/i386/trace.c
  GEN     target/sparc/trace.c
  GEN     target/s390x/trace.c
  GEN     target/ppc/trace.c
  GEN     qom/trace.c
  GEN     linux-user/trace.c
  GEN     qmp-introspect.c
  GEN     qapi/trace.c
  GEN     qapi-types.c
  GEN     qapi-visit.c
  GEN     qapi-event.c
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qobject-input-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      trace/control.o
  CC      qobject/json-parser.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/lockcnt.o
  CC      util/aiocb.o
  CC      util/async.o
  CC      util/thread-pool.o
  CC      util/qemu-timer.o
  CC      util/main-loop.o
  CC      util/iohandler.o
  CC      util/aio-posix.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/host-utils.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/keyval.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/uuid.o
  CC      util/throttle.o
  CC      util/getauxval.o
  CC      util/readline.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/clock-warp.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/error-printf.o
  CC      stubs/fdset.o
  CC      stubs/gdbstub.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/monitor.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.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/qmp_pc_dimm_device_list.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/vmgenid.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      block.o
  CC      blockjob.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw-format.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/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.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/file-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/hmac.o
  CC      crypto/hmac-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/dns-resolver.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      iothread.o
  CC      blockdev-nbd.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      os-posix.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      cpus-common.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/wctablet.o
  CC      backends/testdev.o
  CC      backends/hostmem.o
  CC      backends/tpm.o
  CC      backends/hostmem-ram.o
  CC      backends/hostmem-file.o
  CC      backends/cryptodev.o
  CC      backends/cryptodev-builtin.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      fsdev/qemu-fsdev-throttle.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/cpu.o
  CC      hw/acpi/nvdimm.o
  CC      hw/acpi/vmgenid.o
  CC      hw/acpi/acpi_interface.o
  CC      hw/acpi/aml-build.o
  CC      hw/acpi/bios-linker-loader.o
  CC      hw/acpi/ipmi.o
  CC      hw/acpi/acpi-stub.o
  CC      hw/acpi/ipmi-stub.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/audio/marvell_88w8618.o
  CC      hw/block/block.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/debugcon.o
  CC      hw/char/cadence_uart.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/reset.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/loader.o
  CC      hw/core/qdev-properties-system.o
  CC      hw/core/register.o
  CC      hw/core/or-irq.o
  CC      hw/core/platform-bus.o
  CC      hw/core/security-policy.o
  CC      hw/display/ads7846.o
  CC      hw/display/cirrus_vga.o
  CC      hw/display/ssd0303.o
  CC      hw/display/pl110.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/bitbang_i2c.o
  CC      hw/i2c/pm_smbus.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/intc/arm_gicv3_its_common.o
  CC      hw/intc/intc.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/unimp.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/nvram/chrp_nvram.o
  CC      hw/pci-bridge/pci_bridge_dev.o
  CC      hw/pci-bridge/pcie_root_port.o
  CC      hw/pci-bridge/gen_pcie_root_port.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_bridge.o
  CC      hw/pci/pci.o
  CC      hw/pci/msix.o
  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/smbios/smbios-stub.o
  CC      hw/smbios/smbios_type_38-stub.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/ssi/stm32f2xx_spi.o
  CC      hw/timer/arm_timer.o
  CC      hw/timer/arm_mptimer.o
  CC      hw/timer/armv7m_systick.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/virtio/vhost-stub.o
  CC      hw/watchdog/watchdog.o
  CC      hw/watchdog/wdt_i6300esb.o
  CC      hw/watchdog/wdt_ib700.o
  CC      hw/watchdog/wdt_aspeed.o
  CC      migration/migration.o
  CC      migration/socket.o
  CC      migration/fd.o
  CC      migration/exec.o
  CC      migration/tls.o
  CC      migration/colo-comm.o
  CC      migration/colo.o
  CC      migration/colo-failover.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-mirror.o
  CC      net/filter-buffer.o
  CC      net/colo-compare.o
  CC      net/colo.o
  CC      net/filter-rewriter.o
  CC      net/filter-replay.o
  CC      qom/cpu.o
  CC      replay/replay.o
  CC      replay/replay-internal.o
  CC      replay/replay-events.o
  CC      replay/replay-input.o
  CC      replay/replay-time.o
  CC      replay/replay-char.o
  CC      replay/replay-snapshot.o
  CC      replay/replay-net.o
  CC      replay/replay-audio.o
  CC      slirp/cksum.o
  CC      slirp/if.o
  CC      slirp/ip_icmp.o
  CC      slirp/ip6_icmp.o
  CC      slirp/ip6_input.o
  CC      slirp/ip6_output.o
  CC      slirp/ip_input.o
  CC      slirp/ip_output.o
  CC      slirp/dnssearch.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:65: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  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/udp6.o
  CC      slirp/udp.o
  CC      slirp/bootp.o
  CC      slirp/tftp.o
  CC      slirp/arp_table.o
  CC      slirp/ndp_table.o
  CC      ui/keymaps.o
  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
/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/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-jobs.o
  CC      ui/vnc-ws.o
  CC      chardev/char.o
  CC      chardev/char-fd.o
  CC      chardev/char-file.o
  CC      chardev/char-io.o
  CC      chardev/char-mux.o
  CC      chardev/char-null.o
  CC      chardev/char-parallel.o
  CC      chardev/char-pipe.o
  CC      chardev/char-pty.o
  CC      chardev/char-ringbuf.o
  CC      chardev/char-serial.o
  CC      chardev/char-socket.o
  CC      chardev/char-stdio.o
  CC      chardev/char-udp.o
  LINK    tests/qemu-iotests/socket_scm_helper
  CC      qga/commands.o
  CC      qga/guest-agent-command-state.o
  CC      qga/main.o
  CC      qga/commands-posix.o
  AS      optionrom/multiboot.o
  AS      optionrom/linuxboot.o
  CC      qga/channel-posix.o
  CC      optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
  AS      optionrom/kvmvapic.o
  CC      qga/qapi-generated/qga-qapi-types.o
  BUILD   optionrom/multiboot.img
  CC      qga/qapi-generated/qga-qapi-visit.o
  BUILD   optionrom/linuxboot.img
  BUILD   optionrom/linuxboot_dma.img
  BUILD   optionrom/kvmvapic.img
  BUILD   optionrom/multiboot.raw
  BUILD   optionrom/linuxboot.raw
  BUILD   optionrom/linuxboot_dma.raw
  BUILD   optionrom/kvmvapic.raw
  SIGN    optionrom/multiboot.bin
  SIGN    optionrom/linuxboot.bin
  SIGN    optionrom/linuxboot_dma.bin
  CC      qga/qapi-generated/qga-qmp-marshal.o
  SIGN    optionrom/kvmvapic.bin
  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-root.o
  CC      util/trace.o
  CC      crypto/trace.o
  CC      io/trace.o
  CC      migration/trace.o
  CC      block/trace.o
  CC      backends/trace.o
  CC      hw/block/trace.o
  CC      hw/block/dataplane/trace.o
  CC      hw/char/trace.o
  CC      hw/intc/trace.o
  CC      hw/net/trace.o
  CC      hw/virtio/trace.o
  CC      hw/audio/trace.o
  CC      hw/misc/trace.o
  CC      hw/usb/trace.o
  CC      hw/scsi/trace.o
  CC      hw/nvram/trace.o
  CC      hw/display/trace.o
  CC      hw/input/trace.o
  CC      hw/timer/trace.o
  CC      hw/dma/trace.o
  CC      hw/sparc/trace.o
  CC      hw/sd/trace.o
  CC      hw/isa/trace.o
  CC      hw/mem/trace.o
  CC      hw/i386/trace.o
  CC      hw/i386/xen/trace.o
  CC      hw/9pfs/trace.o
  CC      hw/ppc/trace.o
  CC      hw/pci/trace.o
  CC      hw/s390x/trace.o
  CC      hw/vfio/trace.o
  CC      hw/acpi/trace.o
  CC      hw/arm/trace.o
  CC      hw/alpha/trace.o
  CC      hw/xen/trace.o
  CC      ui/trace.o
  CC      audio/trace.o
  CC      net/trace.o
  CC      target/arm/trace.o
  CC      target/i386/trace.o
  CC      target/sparc/trace.o
  CC      target/s390x/trace.o
  CC      target/ppc/trace.o
  CC      qom/trace.o
  CC      linux-user/trace.o
  CC      qapi/trace.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.h
  GEN     x86_64-softmmu/hmp-commands-info.h
  GEN     x86_64-softmmu/config-target.h
  GEN     aarch64-softmmu/hmp-commands.h
  GEN     aarch64-softmmu/hmp-commands-info.h
  GEN     aarch64-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/tcg/tcg-op.o
  CC      x86_64-softmmu/translate-common.o
  CC      x86_64-softmmu/cpu-exec-common.o
  CC      x86_64-softmmu/tcg/tcg.o
  CC      x86_64-softmmu/tcg/optimize.o
  CC      x86_64-softmmu/tcg/tcg-common.o
  CC      x86_64-softmmu/fpu/softfloat.o
  CC      x86_64-softmmu/disas.o
  CC      x86_64-softmmu/tcg-runtime.o
  CC      x86_64-softmmu/hax-stub.o
  CC      x86_64-softmmu/arch_init.o
  CC      x86_64-softmmu/cpus.o
  CC      x86_64-softmmu/monitor.o
  CC      aarch64-softmmu/exec.o
  CC      aarch64-softmmu/translate-all.o
  CC      x86_64-softmmu/gdbstub.o
  CC      x86_64-softmmu/balloon.o
  CC      aarch64-softmmu/cpu-exec.o
  CC      aarch64-softmmu/translate-common.o
  CC      aarch64-softmmu/cpu-exec-common.o
  CC      x86_64-softmmu/ioport.o
  CC      x86_64-softmmu/numa.o
  CC      x86_64-softmmu/qtest.o
  CC      x86_64-softmmu/bootdevice.o
  CC      aarch64-softmmu/tcg/tcg.o
  CC      x86_64-softmmu/kvm-all.o
  CC      aarch64-softmmu/tcg/tcg-op.o
  CC      x86_64-softmmu/sev.o
  CC      x86_64-softmmu/memory.o
  CC      x86_64-softmmu/cputlb.o
  CC      x86_64-softmmu/memory_mapping.o
  CC      aarch64-softmmu/tcg/optimize.o
  CC      aarch64-softmmu/tcg/tcg-common.o
/tmp/qemu-test/src/sev.c:21:19: error: trace.h: No such file or directory
make[1]: *** [sev.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  CC      aarch64-softmmu/fpu/softfloat.o
  CC      aarch64-softmmu/disas.o
  CC      aarch64-softmmu/tcg-runtime.o
  GEN     aarch64-softmmu/gdbstub-xml.c
  CC      aarch64-softmmu/hax-stub.o
  CC      aarch64-softmmu/kvm-stub.o
  CC      aarch64-softmmu/cpus.o
  CC      aarch64-softmmu/arch_init.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
  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/adc/stm32f2xx_adc.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
make: *** [subdir-x86_64-softmmu] Error 2
make: *** Waiting for unfinished jobs....
  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/core/generic-loader.o
  CC      aarch64-softmmu/hw/core/null-machine.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/gpio/bcm2835_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/exynos4210_clk.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/bcm2835_rng.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/sd/bcm2835_sdhost.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/virtio/virtio-crypto.o
  CC      aarch64-softmmu/hw/virtio/virtio-crypto-pci.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/pxa2xx.o
  CC      aarch64-softmmu/hw/arm/exynos4210.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/aspeed_soc.o
  CC      aarch64-softmmu/hw/arm/aspeed.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/iwmmxt_helper.o
  CC      aarch64-softmmu/target/arm/neon_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:6359: 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:8086: warning: ‘rmode’ may be used uninitialized in this function
  LINK    aarch64-softmmu/qemu-system-aarch64
make[1]: *** [docker-run] Error 2
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-0dx45yo9/src'
make: *** [docker-run-test-quick@centos6] Error 2
=== 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] 41+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute
  2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute Brijesh Singh
@ 2017-03-23 11:29   ` Stefan Hajnoczi
  2017-03-23 18:14     ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Stefan Hajnoczi @ 2017-03-23 11:29 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth, Thomas.Lendacky

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

On Wed, Mar 08, 2017 at 03:51:28PM -0500, Brijesh Singh wrote:
> Add a new debug attribute, the attribute should be set when guest memory
> accesses are performed for debug purposes.
> The attribute will be used in SEV guest, where we need to distinguish normal
> vs debug access to guest memory. In debug mode, we need to use SEV commands
> to access the guest memory.
> 
> 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 */

What does "debug purposes" mean?  gdbstub?  Can the guest initiate debug
memory accesses or is the purely QEMU-internal?

> +    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
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object Brijesh Singh
@ 2017-03-23 11:35   ` Stefan Hajnoczi
  2017-03-23 18:59     ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Stefan Hajnoczi @ 2017-03-23 11:35 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth, Thomas.Lendacky

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

On Wed, Mar 08, 2017 at 03:52:09PM -0500, Brijesh Singh wrote:
> The object can be used to define global security policy for the guest.

"security-policy" is very vague.  Lots of parts of QEMU have security
related options (e.g. VNC display, networking, etc).

I'd prefer a
-machine memory-encryption=on|off,memory-encryption-debug=on|off
or -m encryption=on|off,encryption-debug=on|off switch instead of a new
security policy object with questionable scope.

> object provides two properties:
> 
>  1) debug: can be used to disable guest memory access from hypervisor.
> 
>    e.g to disable guest memory debug accesses
> 
>     # $QEMU \
>           -object security-policy,debug=false,id=mypolicy \
>           -machine ...,security-policy=mypolicy
> 
>  2) memory-encryption: if hypervisor supports memory encryption then this
>     property can be used to define object for encryption.
> 
>     # $QEMU \
>         -object sev-guest,id=sev0 \
>         -object security-policy,id=memory-encryption=sev0,id=mypolicy \

s/id=memory-encryption=/id=mypolicy,memory-encryption=/

>         -machine ...,security-policy=mypolicy
> 
> The memory-encryption property will be used for enabling AMD's SEV feature.
> 
> 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        |  165 ++++++++++++++++++++++++++++++++++++++
>  include/hw/boards.h              |    1 
>  include/sysemu/security-policy.h |   75 +++++++++++++++++
>  qemu-options.hx                  |   21 +++++
>  7 files changed, 292 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 772a959..2c7c891 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -40,6 +40,7 @@
>  #else /* !CONFIG_USER_ONLY */
>  #include "hw/hw.h"
>  #include "exec/memory.h"
> +#include "sysemu/security-policy.h"
>  #include "exec/ioport.h"
>  #include "sysemu/dma.h"
>  #include "sysemu/numa.h"
> @@ -2926,6 +2927,12 @@ static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
>      hwaddr addr1;
>      MemoryRegion *mr;
>  
> +    /* Check if debug accesses is allowed */
> +    if (attrs.debug &&
> +        !security_policy_debug_allowed(current_machine->security_policy)) {
> +        return;
> +    }
> +
>      rcu_read_lock();
>      while (len > 0) {
>          l = len;
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index 91450b2..3c413b1 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -18,6 +18,7 @@ common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
>  common-obj-$(CONFIG_SOFTMMU) += register.o
>  common-obj-$(CONFIG_SOFTMMU) += or-irq.o
>  common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
> +common-obj-$(CONFIG_SOFTMMU) += security-policy.o
>  
>  obj-$(CONFIG_SOFTMMU) += generic-loader.o
>  obj-$(CONFIG_SOFTMMU) += null-machine.o
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 0699750..c14f59c 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -332,6 +332,23 @@ 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 void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
>  {
>      error_report("Option '-device %s' cannot be handled by this machine",
> @@ -493,6 +510,11 @@ static void machine_class_init(ObjectClass *oc, void *data)
>          &error_abort);
>      object_class_property_set_description(oc, "enforce-config-section",
>          "Set on to enforce configuration section migration", &error_abort);
> +
> +    object_class_property_add_str(oc, "security-policy",
> +            machine_get_security_policy, machine_set_security_policy, NULL);
> +    object_class_property_set_description(oc, "security-policy",
> +            "Set the security policy for the machine", NULL);
>  }
>  
>  static void machine_class_base_init(ObjectClass *oc, void *data)
> diff --git a/hw/core/security-policy.c b/hw/core/security-policy.c
> new file mode 100644
> index 0000000..4d4658e
> --- /dev/null
> +++ b/hw/core/security-policy.c
> @@ -0,0 +1,165 @@
> +/*
> + * 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 "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 269d0ba..a1c99a0 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -153,6 +153,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 2292438..536db1b 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -4140,6 +4140,27 @@ contents of @code{iv.b64} to the second secret
>  
>  @end table
>  
> +@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' object.
> +
>  ETEXI
>  
>  
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute
  2017-03-23 11:29   ` Stefan Hajnoczi
@ 2017-03-23 18:14     ` Brijesh Singh
  2017-03-24 15:36       ` Stefan Hajnoczi
  0 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-23 18:14 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky

Hi Stefan,


On 03/23/2017 06:29 AM, Stefan Hajnoczi wrote:
> On Wed, Mar 08, 2017 at 03:51:28PM -0500, Brijesh Singh wrote:
>> Add a new debug attribute, the attribute should be set when guest memory
>> accesses are performed for debug purposes.
>> The attribute will be used in SEV guest, where we need to distinguish normal
>> vs debug access to guest memory. In debug mode, we need to use SEV commands
>> to access the guest memory.
>>
>> 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 */
>
> What does "debug purposes" mean?  gdbstub?  Can the guest initiate debug
> memory accesses or is the purely QEMU-internal?
>

What I mean by that is, any access to the guest memory within Qemu internal functions
(e.g gdbstub, qemu monitor's memory dump, info mem, info tlb etc). I have also introduced
debug version of ldl_phys, ldq_phys, cpu_physical_memory_* [1] and have updated hmp monitor
code to use the debug version api's when accessing the guest memory [2].

[1] http://marc.info/?l=qemu-devel&m=148900832814697&w=2
[2] http://marc.info/?l=qemu-devel&m=148900831414693&w=2


Note: SEV debug API's are meant to be used by hypervisor to decrypt/encrypt guest memory.
But when you are inside the guest, the  guest will have access to decrypted data and does
not need to call down to hypervisor for debug access.


>> +    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	[flat|nested] 41+ messages in thread

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-23 11:35   ` Stefan Hajnoczi
@ 2017-03-23 18:59     ` Brijesh Singh
  2017-03-24 15:40       ` Stefan Hajnoczi
  0 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-23 18:59 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky

Hi Stefan,


On 03/23/2017 06:35 AM, Stefan Hajnoczi wrote:
> On Wed, Mar 08, 2017 at 03:52:09PM -0500, Brijesh Singh wrote:
>> The object can be used to define global security policy for the guest.
>
> "security-policy" is very vague.  Lots of parts of QEMU have security
> related options (e.g. VNC display, networking, etc).
>
> I'd prefer a
> -machine memory-encryption=on|off,memory-encryption-debug=on|off
> or -m encryption=on|off,encryption-debug=on|off switch instead of a new
> security policy object with questionable scope.
>

In v1 [1], I had something similar but not exactly the same. I had a new command
line switch but the overall feedback was to consider creating new security object
which can be used to define a machine security policy.

[1] http://marc.info/?t=147378617700002&r=1&w=2

some more discussion here [2]

[2] http://marc.info/?t=147378241700011&r=1&w=2

IMHO, a new object is helpful because it provide options to launch a guest without
memory encryption support but still can take a advantage of disabling the debug
feature. e.g on non SEV platform we can launch guest with "-object security-policy,id=secure0,debug=off'
which will reject the guest memory accesses via gdbstub or qemu monitor command line interface.

-Brijesh

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

* Re: [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute
  2017-03-23 18:14     ` Brijesh Singh
@ 2017-03-24 15:36       ` Stefan Hajnoczi
  2017-03-24 16:43         ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Stefan Hajnoczi @ 2017-03-24 15:36 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth, Thomas.Lendacky

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

On Thu, Mar 23, 2017 at 01:14:17PM -0500, Brijesh Singh wrote:
> Hi Stefan,
> 
> 
> On 03/23/2017 06:29 AM, Stefan Hajnoczi wrote:
> > On Wed, Mar 08, 2017 at 03:51:28PM -0500, Brijesh Singh wrote:
> > > Add a new debug attribute, the attribute should be set when guest memory
> > > accesses are performed for debug purposes.
> > > The attribute will be used in SEV guest, where we need to distinguish normal
> > > vs debug access to guest memory. In debug mode, we need to use SEV commands
> > > to access the guest memory.
> > > 
> > > 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 */
> > 
> > What does "debug purposes" mean?  gdbstub?  Can the guest initiate debug
> > memory accesses or is the purely QEMU-internal?
> > 
> 
> What I mean by that is, any access to the guest memory within Qemu internal functions
> (e.g gdbstub, qemu monitor's memory dump, info mem, info tlb etc). I have also introduced
> debug version of ldl_phys, ldq_phys, cpu_physical_memory_* [1] and have updated hmp monitor
> code to use the debug version api's when accessing the guest memory [2].
> 
> [1] http://marc.info/?l=qemu-devel&m=148900832814697&w=2
> [2] http://marc.info/?l=qemu-devel&m=148900831414693&w=2
> 
> 
> Note: SEV debug API's are meant to be used by hypervisor to decrypt/encrypt guest memory.
> But when you are inside the guest, the  guest will have access to decrypted data and does
> not need to call down to hypervisor for debug access.

People reading the code in memattrs.h aren't thinking about AMD SEV, so
"debug purposes" isn't meaningful in this context.

I suggest something like this instead:

  /* Debug memory access for AMD SEV */

That way it's clear this "debug" flag has a very specific meaning in the
context of memory encryption.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-23 18:59     ` Brijesh Singh
@ 2017-03-24 15:40       ` Stefan Hajnoczi
  2017-03-24 19:42         ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Stefan Hajnoczi @ 2017-03-24 15:40 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth, Thomas.Lendacky

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

On Thu, Mar 23, 2017 at 01:59:48PM -0500, Brijesh Singh wrote:
> Hi Stefan,
> 
> 
> On 03/23/2017 06:35 AM, Stefan Hajnoczi wrote:
> > On Wed, Mar 08, 2017 at 03:52:09PM -0500, Brijesh Singh wrote:
> > > The object can be used to define global security policy for the guest.
> > 
> > "security-policy" is very vague.  Lots of parts of QEMU have security
> > related options (e.g. VNC display, networking, etc).
> > 
> > I'd prefer a
> > -machine memory-encryption=on|off,memory-encryption-debug=on|off
> > or -m encryption=on|off,encryption-debug=on|off switch instead of a new
> > security policy object with questionable scope.
> > 
> 
> In v1 [1], I had something similar but not exactly the same. I had a new command
> line switch but the overall feedback was to consider creating new security object
> which can be used to define a machine security policy.
> 
> [1] http://marc.info/?t=147378617700002&r=1&w=2
> 
> some more discussion here [2]
> 
> [2] http://marc.info/?t=147378241700011&r=1&w=2
> 
> IMHO, a new object is helpful because it provide options to launch a guest without
> memory encryption support but still can take a advantage of disabling the debug
> feature. e.g on non SEV platform we can launch guest with "-object security-policy,id=secure0,debug=off'
> which will reject the guest memory accesses via gdbstub or qemu monitor command line interface.

Having one security policy doesn't make sense to me.  As mentioned,
there are many different areas of QEMU that have security relevant
configuration.  They are all unrelated so combining them into one object
with vague parameter names like "debug" makes for a confusing
command-line interface.

If the object is called sev-security-policy then I'm happy.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute
  2017-03-24 15:36       ` Stefan Hajnoczi
@ 2017-03-24 16:43         ` Brijesh Singh
  0 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-24 16:43 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky



On 03/24/2017 10:36 AM, Stefan Hajnoczi wrote:
>
> I suggest something like this instead:
>
>   /* Debug memory access for AMD SEV */
>
> That way it's clear this "debug" flag has a very specific meaning in the
> context of memory encryption.
>

Sure, will update comments.

-Brijesh

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

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-24 15:40       ` Stefan Hajnoczi
@ 2017-03-24 19:42         ` Brijesh Singh
  2017-03-27 12:04           ` Stefan Hajnoczi
  0 siblings, 1 reply; 41+ messages in thread
From: Brijesh Singh @ 2017-03-24 19:42 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky


On 03/24/2017 10:40 AM, Stefan Hajnoczi wrote:

>
> Having one security policy doesn't make sense to me.  As mentioned,
> there are many different areas of QEMU that have security relevant
> configuration.  They are all unrelated so combining them into one object
> with vague parameter names like "debug" makes for a confusing
> command-line interface.
>
> If the object is called sev-security-policy then I'm happy.
>

Works for with me but one of the feedback was to use security-policy [1].
IIRC, the main reason for using 'security-policy' instead of 'sev-security-policy'
was to add a layer of abstraction so that in future if other platforms supports
memory encryption in slightly different way then all we need to do is to create
new object without needing to add a new parameter in -machine.

[1] http://marc.info/?l=qemu-devel&m=147388592213137&w=2

How about using 'memory-encryption-id' instead of security-policy ? If user wants
to launch SEV guest then memory-encryption-id should be set SEV specific object.
Something like this:

-machine ..,memory-encryption-id=sev0 \
-object sev-guest,id=sev,debug=off,launch=launch0 \
-object sev-launch-info,id=launch0 \


Thanks
Brijesh

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

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-24 19:42         ` Brijesh Singh
@ 2017-03-27 12:04           ` Stefan Hajnoczi
  2017-03-27 16:11             ` Brijesh Singh
  0 siblings, 1 reply; 41+ messages in thread
From: Stefan Hajnoczi @ 2017-03-27 12:04 UTC (permalink / raw)
  To: Brijesh Singh
  Cc: ehabkost, crosthwaite.peter, armbru, mst, p.fedin, qemu-devel,
	lcapitulino, pbonzini, rth, Thomas.Lendacky

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

On Fri, Mar 24, 2017 at 02:42:47PM -0500, Brijesh Singh wrote:
> 
> On 03/24/2017 10:40 AM, Stefan Hajnoczi wrote:
> 
> > 
> > Having one security policy doesn't make sense to me.  As mentioned,
> > there are many different areas of QEMU that have security relevant
> > configuration.  They are all unrelated so combining them into one object
> > with vague parameter names like "debug" makes for a confusing
> > command-line interface.
> > 
> > If the object is called sev-security-policy then I'm happy.
> > 
> 
> Works for with me but one of the feedback was to use security-policy [1].
> IIRC, the main reason for using 'security-policy' instead of 'sev-security-policy'
> was to add a layer of abstraction so that in future if other platforms supports
> memory encryption in slightly different way then all we need to do is to create
> new object without needing to add a new parameter in -machine.
> 
> [1] http://marc.info/?l=qemu-devel&m=147388592213137&w=2
> 
> How about using 'memory-encryption-id' instead of security-policy ? If user wants
> to launch SEV guest then memory-encryption-id should be set SEV specific object.
> Something like this:
> 
> -machine ..,memory-encryption-id=sev0 \
> -object sev-guest,id=sev,debug=off,launch=launch0 \
> -object sev-launch-info,id=launch0 \

Something like that sounds good.  I think "-id" typically isn't included
in the option name.

So just the following is fine:

 -machine memory-encryption=sev0 \
 ...

Other examples: -device virtio-blk-pci,drive=drive0 and -device
e1000,netdev=netdev0.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
  2017-03-27 12:04           ` Stefan Hajnoczi
@ 2017-03-27 16:11             ` Brijesh Singh
  0 siblings, 0 replies; 41+ messages in thread
From: Brijesh Singh @ 2017-03-27 16:11 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: brijesh.singh, ehabkost, crosthwaite.peter, armbru, mst, p.fedin,
	qemu-devel, lcapitulino, pbonzini, rth, Thomas.Lendacky


On 03/27/2017 07:04 AM, Stefan Hajnoczi wrote:
> On Fri, Mar 24, 2017 at 02:42:47PM -0500, Brijesh Singh wrote:
>>
>> On 03/24/2017 10:40 AM, Stefan Hajnoczi wrote:
>>
>>>
>>> Having one security policy doesn't make sense to me.  As mentioned,
>>> there are many different areas of QEMU that have security relevant
>>> configuration.  They are all unrelated so combining them into one object
>>> with vague parameter names like "debug" makes for a confusing
>>> command-line interface.
>>>
>>> If the object is called sev-security-policy then I'm happy.
>>>
>>
>> Works for with me but one of the feedback was to use security-policy [1].
>> IIRC, the main reason for using 'security-policy' instead of 'sev-security-policy'
>> was to add a layer of abstraction so that in future if other platforms supports
>> memory encryption in slightly different way then all we need to do is to create
>> new object without needing to add a new parameter in -machine.
>>
>> [1] http://marc.info/?l=qemu-devel&m=147388592213137&w=2
>>
>> How about using 'memory-encryption-id' instead of security-policy ? If user wants
>> to launch SEV guest then memory-encryption-id should be set SEV specific object.
>> Something like this:
>>
>> -machine ..,memory-encryption-id=sev0 \
>> -object sev-guest,id=sev,debug=off,launch=launch0 \
>> -object sev-launch-info,id=launch0 \
>
> Something like that sounds good.  I think "-id" typically isn't included
> in the option name.
>
> So just the following is fine:
>
>  -machine memory-encryption=sev0 \
>  ...
>
> Other examples: -device virtio-blk-pci,drive=drive0 and -device
> e1000,netdev=netdev0.


Sounds good. I will take care of this in next rev. thanks for review

-Brijesh

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

end of thread, other threads:[~2017-03-27 16:11 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-08 20:51 [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file Brijesh Singh
2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute Brijesh Singh
2017-03-23 11:29   ` Stefan Hajnoczi
2017-03-23 18:14     ` Brijesh Singh
2017-03-24 15:36       ` Stefan Hajnoczi
2017-03-24 16:43         ` Brijesh Singh
2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 03/20] exec: add guest RAM read and write ops Brijesh Singh
2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 04/20] exec: add debug version of physical memory read and write api Brijesh Singh
2017-03-08 20:51 ` [Qemu-devel] [RFC PATCH v4 05/20] monitor/i386: use debug apis when accessing guest memory Brijesh Singh
2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object Brijesh Singh
2017-03-23 11:35   ` Stefan Hajnoczi
2017-03-23 18:59     ` Brijesh Singh
2017-03-24 15:40       ` Stefan Hajnoczi
2017-03-24 19:42         ` Brijesh Singh
2017-03-27 12:04           ` Stefan Hajnoczi
2017-03-27 16:11             ` Brijesh Singh
2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 07/20] kvm: add memory encryption api support Brijesh Singh
2017-03-08 21:06   ` Eduardo Habkost
2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 08/20] sev: add Secure Encrypted Virtulization (SEV) support Brijesh Singh
2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 09/20] hmp: display memory encryption support in 'info kvm' Brijesh Singh
2017-03-08 21:43   ` Eric Blake
2017-03-08 20:52 ` [Qemu-devel] [RFC PATCH v4 10/20] vl: add memory encryption support Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command Brijesh Singh
2017-03-08 21:13   ` Eduardo Habkost
2017-03-08 21:39     ` Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 12/20] SEV: add GUEST_STATUS command Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 13/20] sev: add LAUNCH_UPDATE_DATA command Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 14/20] sev: add LAUNCH_FINISH command Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 15/20] sev: add DEBUG_DECRYPT command Brijesh Singh
2017-03-08 20:53 ` [Qemu-devel] [RFC PATCH v4 16/20] sev: add DEBUG_ENCRYPT command Brijesh Singh
2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 17/20] target/i386: encrypt bios rom when memory encryption is enabled Brijesh Singh
2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 18/20] target/i386: add cpuid Fn8000_001f Brijesh Singh
2017-03-08 21:29   ` Eduardo Habkost
2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 19/20] target/i386: clear memory encryption bit when walking SEV guest page table Brijesh Singh
2017-03-08 20:54 ` [Qemu-devel] [RFC PATCH v4 20/20] migration: disable save/restore and migration when SEV is active Brijesh Singh
2017-03-08 21:32   ` Eduardo Habkost
2017-03-08 21:40     ` Brijesh Singh
2017-03-08 21:27 ` [Qemu-devel] [RFC PATCH v4 00/20] x86: Secure Encrypted Virtualization (AMD) Eduardo Habkost
2017-03-08 21:37   ` Brijesh Singh
2017-03-08 22:29 ` 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.