qemu/0047-exec-add-ram_debug_ops-support.patch

205 lines
7.6 KiB
Diff

From a8955ac9aa33e2d3edb4ea948d74cf52fc9771a2 Mon Sep 17 00:00:00 2001
From: Brijesh Singh <brijesh.singh@amd.com>
Date: Thu, 15 Feb 2018 09:03:19 -0600
Subject: [PATCH] exec: add ram_debug_ops support
Currently, the guest memory access for the debug purpose is performed
using the memcpy(). Lets extend the 'struct MemoryRegion' to include
ram_debug_ops callbacks. The ram_debug_ops can be used to override
memcpy() with something else.
The feature can be used by encrypted guest -- which can register
callbacks to override memcpy() with memory encryption/decryption APIs.
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);
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[BR: FATE#322124]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
exec.c | 43 ++++++++++++++++++++++++++++++++-----------
include/exec/memory.h | 30 +++++++++++++++++++++++++++++-
2 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/exec.c b/exec.c
index 1ca0f9e0ab..fe49807f58 100644
--- a/exec.c
+++ b/exec.c
@@ -2983,7 +2983,11 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
} else {
/* RAM case */
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
- memcpy(ptr, buf, l);
+ if (attrs.debug && 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);
}
@@ -3081,7 +3085,11 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
} else {
/* RAM case */
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
- memcpy(buf, ptr, l);
+ if (attrs.debug && mr->ram_debug_ops) {
+ mr->ram_debug_ops->read(buf, ptr, l, attrs);
+ } else {
+ memcpy(buf, ptr, l);
+ }
}
if (release_lock) {
@@ -3155,7 +3163,8 @@ enum write_rom_type {
};
static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
- hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
+ hwaddr addr, const uint8_t *buf, int len, MemTxAttrs attrs,
+ enum write_rom_type type)
{
hwaddr l;
uint8_t *ptr;
@@ -3175,7 +3184,11 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
switch (type) {
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:
@@ -3194,7 +3207,9 @@ 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_write_rom_internal(as, addr, buf, len,
+ MEMTXATTRS_UNSPECIFIED,
+ WRITE_DATA);
}
void cpu_flush_icache_range(hwaddr start, int len)
@@ -3209,8 +3224,9 @@ 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_write_rom_internal(&address_space_memory, start, NULL,
+ len, MEMTXATTRS_UNSPECIFIED,
+ FLUSH_CACHE);
}
typedef struct {
@@ -3525,6 +3541,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 attrs to indicate memory access is from the debugger */
+ attrs.debug = 1;
+
/* if no physical page mapped, return an error */
if (phys_addr == -1)
return -1;
@@ -3533,13 +3553,14 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
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);
+ cpu_physical_memory_write_rom_internal(cpu->cpu_ases[asidx].as,
+ phys_addr, buf, l, attrs,
+ WRITE_DATA);
} else {
address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
- MEMTXATTRS_UNSPECIFIED,
- buf, l, 0);
+ attrs, buf, l, 0);
}
+
len -= l;
buf += l;
addr += l;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 5ed4042f87..8d3b99cba8 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -215,6 +215,18 @@ typedef struct IOMMUMemoryRegionClass {
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
+/* Memory Region RAM debug 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);
+};
+
struct MemoryRegion {
Object parent_obj;
@@ -254,6 +266,7 @@ struct MemoryRegion {
const char *name;
unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds;
+ const MemoryRegionRAMReadWriteOps *ram_debug_ops;
};
struct IOMMUMemoryRegion {
@@ -620,6 +633,21 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
uint64_t size,
Error **errp);
+/**
+ * memory_region_set_ram_debug_ops: Set debug access ops for a given memory
+ * region.
+ *
+ * @mr: the #MemoryRegion to be initialized
+ * @ops: a function that will be used for when accessing @target region during
+ * debug
+ */
+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.
@@ -1928,7 +1956,7 @@ MemTxResult flatview_read(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
void *ptr;
MemoryRegion *mr;
- if (__builtin_constant_p(len)) {
+ if (__builtin_constant_p(len) && !attrs.debug) {
if (len) {
rcu_read_lock();
l = len;