]> xenbits.xensource.com Git - people/pauldu/qemu.git/commitdiff
tpm: clear RAM when "memory overwrite" requested
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Mon, 14 Jan 2019 22:27:54 +0000 (02:27 +0400)
committerMichael S. Tsirkin <mst@redhat.com>
Fri, 18 Jan 2019 02:10:57 +0000 (21:10 -0500)
Note: the "Platform Reset Attack Mitigation" specification isn't
explicit about NVDIMM, since they could have different usages. It uses
the term "system memory" generally (and also "volatile memory RAM" in
its introduction). For initial support, I propose to consider
non-volatile memory as not being subject to the memory clear. There is
an on-going discussion in the TCG "pcclientwg" working group for
future revisions.

CPU cache clearing is done unconditionally in edk2 since commit
d20ae95a13e851 (edk2-stable201811).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
hw/tpm/tpm_crb.c
hw/tpm/tpm_ppi.c
hw/tpm/tpm_ppi.h
hw/tpm/tpm_tis.c
hw/tpm/trace-events

index 012ec686d4b57f6bf0d0ead71227c83992b67ba8..3087acc4ab7ea6a788483f2518c3f73fd55de003 100644 (file)
@@ -233,6 +233,9 @@ static void tpm_crb_reset(void *dev)
 {
     CRBState *s = CRB(dev);
 
+    if (s->ppi_enabled) {
+        tpm_ppi_reset(&s->ppi);
+    }
     tpm_backend_reset(s->tpmbe);
 
     memset(s->regs, 0, sizeof(s->regs));
index cf17779c20f41f15563f86c2304312f89d88936b..cd8205f212096a24c6b2574bf2779a5277518b95 100644 (file)
 #include "qapi/error.h"
 #include "cpu.h"
 #include "sysemu/memory_mapping.h"
+#include "sysemu/reset.h"
 #include "migration/vmstate.h"
 #include "tpm_ppi.h"
+#include "trace.h"
+
+void tpm_ppi_reset(TPMPPI *tpmppi)
+{
+    if (tpmppi->buf[0x15a /* movv, docs/specs/tpm.txt */] & 0x1) {
+        GuestPhysBlockList guest_phys_blocks;
+        GuestPhysBlock *block;
+
+        guest_phys_blocks_init(&guest_phys_blocks);
+        guest_phys_blocks_append(&guest_phys_blocks);
+        QTAILQ_FOREACH(block, &guest_phys_blocks.head, next) {
+            trace_tpm_ppi_memset(block->host_addr,
+                                 block->target_end - block->target_start);
+            memset(block->host_addr, 0,
+                   block->target_end - block->target_start);
+            memory_region_set_dirty(block->mr, 0,
+                                    block->target_end - block->target_start);
+        }
+        guest_phys_blocks_free(&guest_phys_blocks);
+    }
+}
 
 void tpm_ppi_init(TPMPPI *tpmppi, struct MemoryRegion *m,
                   hwaddr addr, Object *obj)
index c5e555fe2c73a95086fbe7c2dbc73198214d012e..d33ef27de6d685df8a12c3f8daa24bceb47e22a8 100644 (file)
@@ -33,4 +33,14 @@ typedef struct TPMPPI {
 void tpm_ppi_init(TPMPPI *tpmppi, struct MemoryRegion *m,
                   hwaddr addr, Object *obj);
 
+/**
+ * tpm_ppi_reset:
+ * @tpmppi: a TPMPPI
+ *
+ * Function to call on machine reset. It will check if the "Memory
+ * overwrite" variable is set, and perform a memory clear on volatile
+ * memory if requested.
+ **/
+void tpm_ppi_reset(TPMPPI *tpmppi);
+
 #endif /* TPM_TPM_PPI_H */
index 02d9d5c911d709ba7ff86f90c4aca71f49889311..fd6bb9b59a96a27324d4fb48ab143d91ec70225e 100644 (file)
@@ -872,6 +872,9 @@ static void tpm_tis_reset(DeviceState *dev)
     s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver),
                             TPM_TIS_BUFFER_MAX);
 
+    if (s->ppi_enabled) {
+        tpm_ppi_reset(&s->ppi);
+    }
     tpm_backend_reset(s->be_driver);
 
     s->active_locty = TPM_TIS_NO_LOCALITY;
index 25bee0cecf9eb966f80b6b2640ea05c8d0241eac..920d32ad5514deeeec0a43a30f674ebda3872d4f 100644 (file)
@@ -51,3 +51,6 @@ tpm_tis_mmio_write_init_abort(void) "Initiating abort"
 tpm_tis_mmio_write_lowering_irq(void) "Lowering IRQ"
 tpm_tis_mmio_write_data2send(uint32_t value, unsigned size) "Data to send to TPM: 0x%08x (size=%d)"
 tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
+
+# hw/tpm/tpm_ppi.c
+tpm_ppi_memset(uint8_t *ptr, size_t size) "memset: %p %zu"