[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops
From: |
Brijesh Singh |
Subject: |
[Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops |
Date: |
Thu, 22 Sep 2016 10:52:10 -0400 |
User-agent: |
StGit/0.17.1-dirty |
In current implementation, read and write of the guest RAM is
performed using using memcpy(). This patch adds support to register
a callback which can override the memcpy() with something else.
This feature will be used in Secure Encrypted Virtualization (SEV)
guests in which read and write of guest memory should be performed
using the SEV commands.
a typical usage:
mem_read(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
mem_write(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
MemoryRegionRAMReadWriteOps ops;
ops.read = mem_read;
ops.write = mem_write;
memory_region_init_ram(mem, NULL, "memory", size, NULL);
memory_region_set_ram_ops(mem, ops);
Signed-off-by: Brijesh Singh <address@hidden>
---
exec.c | 57 ++++++++++++++++++++++++++++++++-------------
include/exec/cpu-common.h | 2 +-
include/exec/memory.h | 25 ++++++++++++++++++++
3 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/exec.c b/exec.c
index 8ffde75..0989933 100644
--- a/exec.c
+++ b/exec.c
@@ -2715,11 +2715,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
enum write_rom_type {
WRITE_DATA,
+ READ_DATA,
FLUSH_CACHE,
};
-static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
- hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
+static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
+ hwaddr addr, uint8_t *buf, int len, MemTxAttrs attrs,
+ enum write_rom_type type)
{
hwaddr l;
uint8_t *ptr;
@@ -2733,13 +2735,33 @@ static inline void
cpu_physical_memory_write_rom_internal(AddressSpace *as,
if (!(memory_region_is_ram(mr) ||
memory_region_is_romd(mr))) {
- l = memory_access_size(mr, l, addr1);
+ /* Pass MMIO down to address address_space_rw */
+ switch (type) {
+ case READ_DATA:
+ case WRITE_DATA:
+ address_space_rw(as, addr, attrs, buf, l,
+ type == WRITE_DATA);
+ break;
+ case FLUSH_CACHE:
+ break;
+ }
} else {
/* ROM/RAM case */
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
switch (type) {
+ case READ_DATA:
+ if (mr->ram_ops) {
+ mr->ram_ops->read(buf, ptr, l, attrs);
+ } else {
+ memcpy(buf, ptr, l);
+ }
+ break;
case WRITE_DATA:
- memcpy(ptr, buf, l);
+ if (mr->ram_ops) {
+ mr->ram_ops->write(ptr, buf, l, attrs);
+ } else {
+ memcpy(ptr, buf, l);
+ }
invalidate_and_set_dirty(mr, addr1, l);
break;
case FLUSH_CACHE:
@@ -2756,9 +2778,10 @@ static inline void
cpu_physical_memory_write_rom_internal(AddressSpace *as,
/* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
- const uint8_t *buf, int len)
+ uint8_t *buf, int len)
{
- cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
+ cpu_physical_memory_rw_debug_internal(as, addr, buf, len,
+ MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
}
void cpu_flush_icache_range(hwaddr start, int len)
@@ -2773,8 +2796,10 @@ void cpu_flush_icache_range(hwaddr start, int len)
return;
}
- cpu_physical_memory_write_rom_internal(&address_space_memory,
- start, NULL, len, FLUSH_CACHE);
+ cpu_physical_memory_rw_debug_internal(&address_space_memory,
+ start, NULL, len,
+ MEMTXATTRS_UNSPECIFIED,
+ FLUSH_CACHE);
}
typedef struct {
@@ -3597,6 +3622,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
int l;
hwaddr phys_addr;
target_ulong page;
+ int type = is_write ? WRITE_DATA : READ_DATA;
while (len > 0) {
int asidx;
@@ -3605,6 +3631,10 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
page = addr & TARGET_PAGE_MASK;
phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs);
asidx = cpu_asidx_from_attrs(cpu, attrs);
+
+ /* set debug attribute */
+ attrs.debug = 1;
+
/* if no physical page mapped, return an error */
if (phys_addr == -1)
return -1;
@@ -3612,14 +3642,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
if (l > len)
l = len;
phys_addr += (addr & ~TARGET_PAGE_MASK);
- if (is_write) {
- cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as,
- phys_addr, buf, l);
- } else {
- address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
- MEMTXATTRS_UNSPECIFIED,
- buf, l, 0);
- }
+ cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as,
+ phys_addr, buf, l, attrs,
+ type);
len -= l;
buf += l;
addr += l;
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 952bcfe..520dae0 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -104,7 +104,7 @@ void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t
val);
void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
- const uint8_t *buf, int len);
+ uint8_t *buf, int len);
void cpu_flush_icache_range(hwaddr start, int len);
extern struct MemoryRegion io_mem_rom;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3e4d416..80af3b0 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -146,6 +146,18 @@ struct MemoryRegionOps {
const MemoryRegionMmio old_mmio;
};
+/* Memory Region RAM callback */
+typedef struct MemoryRegionRAMReadWriteOps MemoryRegionRAMReadWriteOps;
+
+struct MemoryRegionRAMReadWriteOps {
+ /* Write data into guest memory */
+ int (*write) (uint8_t *dest, const uint8_t *src,
+ uint32_t len, MemTxAttrs attrs);
+ /* Read data from guest memory */
+ int (*read) (uint8_t *dest, const uint8_t *src,
+ uint32_t len, MemTxAttrs attrs);
+};
+
typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps;
struct MemoryRegionIOMMUOps {
@@ -179,6 +191,7 @@ struct MemoryRegion {
RAMBlock *ram_block;
Object *owner;
const MemoryRegionIOMMUOps *iommu_ops;
+ const MemoryRegionRAMReadWriteOps *ram_ops;
const MemoryRegionOps *ops;
void *opaque;
@@ -506,6 +519,18 @@ static inline void
memory_region_init_reservation(MemoryRegion *mr,
}
/**
+ * memory_region_set_ram_ops: Set the Read/Write ops for accessing the RAM
+ *
+ * @mr: the #MemoryRegion to be initialized
+ * @ops: a function that will be used to read/write @target region
+ */
+static inline void memory_region_set_ram_ops(MemoryRegion *mr,
+ const MemoryRegionRAMReadWriteOps *ops)
+{
+ mr->ram_ops = ops;
+}
+
+/**
* memory_region_init_iommu: Initialize a memory region that translates
* addresses
*
- [Qemu-devel] [RFC PATCH v2 00/16] x86: Secure Encrypted Virtualization (AMD), Brijesh Singh, 2016/09/22
- [Qemu-devel] [RFC PATCH v2 01/16] memattrs: add debug attrs, Brijesh Singh, 2016/09/22
- [Qemu-devel] [RFC PATCH v2 02/16] exec: add guest RAM read and write ops,
Brijesh Singh <=
- [Qemu-devel] [RFC PATCH v2 03/16] exec: add debug version of physical memory read and write apis, Brijesh Singh, 2016/09/22
- [Qemu-devel] [RFC PATCH v2 04/16] monitor: use debug version of memory access apis, Brijesh Singh, 2016/09/22
- [Qemu-devel] [RFC PATCH v2 05/16] core: add new security-policy object, Brijesh Singh, 2016/09/22
- [Qemu-devel] [RFC PATCH v2 06/16] sev: add Secure Encrypted Virtulization (SEV) support, Brijesh Singh, 2016/09/22