mirror of https://gitee.com/openkylin/qemu.git
plugins: Expose physical addresses instead of device offsets
This allows plugins to query for full virtual-to-physical address translation for a given `qemu_plugin_hwaddr` and stops exposing the offset within the device itself. As this change breaks the API, QEMU_PLUGIN_VERSION is incremented. Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210309202802.211756-1-aaron@os.amperecomputing.com> Message-Id: <20210312172821.31647-3-alex.bennee@linaro.org>
This commit is contained in:
parent
279d0a5b1e
commit
787148bf92
|
@ -122,7 +122,7 @@ static void vcpu_haddr(unsigned int cpu_index, qemu_plugin_meminfo_t meminfo,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hwaddr && !qemu_plugin_hwaddr_is_io(hwaddr)) {
|
if (hwaddr && !qemu_plugin_hwaddr_is_io(hwaddr)) {
|
||||||
page = (uint64_t) qemu_plugin_hwaddr_device_offset(hwaddr);
|
page = (uint64_t) qemu_plugin_hwaddr_phys_addr(hwaddr);
|
||||||
} else {
|
} else {
|
||||||
page = vaddr;
|
page = vaddr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ static void vcpu_haddr(unsigned int cpu_index, qemu_plugin_meminfo_t meminfo,
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const char *name = qemu_plugin_hwaddr_device_name(hwaddr);
|
const char *name = qemu_plugin_hwaddr_device_name(hwaddr);
|
||||||
uint64_t off = qemu_plugin_hwaddr_device_offset(hwaddr);
|
uint64_t off = qemu_plugin_hwaddr_phys_addr(hwaddr);
|
||||||
bool is_write = qemu_plugin_mem_is_store(meminfo);
|
bool is_write = qemu_plugin_mem_is_store(meminfo);
|
||||||
DeviceCounts *counts;
|
DeviceCounts *counts;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ typedef uint64_t qemu_plugin_id_t;
|
||||||
|
|
||||||
extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
|
extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
|
||||||
|
|
||||||
#define QEMU_PLUGIN_VERSION 0
|
#define QEMU_PLUGIN_VERSION 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* string describing architecture */
|
/* string describing architecture */
|
||||||
|
@ -307,8 +307,8 @@ bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
|
||||||
bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
|
bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
|
||||||
bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
|
bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* qemu_plugin_get_hwaddr():
|
* qemu_plugin_get_hwaddr() - return handle for memory operation
|
||||||
* @vaddr: the virtual address of the memory operation
|
* @vaddr: the virtual address of the memory operation
|
||||||
*
|
*
|
||||||
* For system emulation returns a qemu_plugin_hwaddr handle to query
|
* For system emulation returns a qemu_plugin_hwaddr handle to query
|
||||||
|
@ -323,12 +323,30 @@ struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
|
||||||
uint64_t vaddr);
|
uint64_t vaddr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following additional queries can be run on the hwaddr structure
|
* The following additional queries can be run on the hwaddr structure to
|
||||||
* to return information about it. For non-IO accesses the device
|
* return information about it - namely whether it is for an IO access and the
|
||||||
* offset will be into the appropriate block of RAM.
|
* physical address associated with the access.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_plugin_hwaddr_is_io() - query whether memory operation is IO
|
||||||
|
* @haddr: address handle from qemu_plugin_get_hwaddr()
|
||||||
|
*
|
||||||
|
* Returns true if the handle's memory operation is to memory-mapped IO, or
|
||||||
|
* false if it is to RAM
|
||||||
*/
|
*/
|
||||||
bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr);
|
bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr);
|
||||||
uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr);
|
|
||||||
|
/**
|
||||||
|
* qemu_plugin_hwaddr_phys_addr() - query physical address for memory operation
|
||||||
|
* @haddr: address handle from qemu_plugin_get_hwaddr()
|
||||||
|
*
|
||||||
|
* Returns the physical address associated with the memory operation
|
||||||
|
*
|
||||||
|
* Note that the returned physical address may not be unique if you are dealing
|
||||||
|
* with multiple address spaces.
|
||||||
|
*/
|
||||||
|
uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a string representing the device. The string is valid for
|
* Returns a string representing the device. The string is valid for
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
#include "exec/ram_addr.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
@ -298,19 +299,25 @@ bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr)
|
uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SOFTMMU
|
#ifdef CONFIG_SOFTMMU
|
||||||
if (haddr) {
|
if (haddr) {
|
||||||
if (!haddr->is_io) {
|
if (!haddr->is_io) {
|
||||||
ram_addr_t ram_addr = qemu_ram_addr_from_host((void *) haddr->v.ram.hostaddr);
|
RAMBlock *block;
|
||||||
if (ram_addr == RAM_ADDR_INVALID) {
|
ram_addr_t offset;
|
||||||
|
void *hostaddr = (void *) haddr->v.ram.hostaddr;
|
||||||
|
|
||||||
|
block = qemu_ram_block_from_host(hostaddr, false, &offset);
|
||||||
|
if (!block) {
|
||||||
error_report("Bad ram pointer %"PRIx64"", haddr->v.ram.hostaddr);
|
error_report("Bad ram pointer %"PRIx64"", haddr->v.ram.hostaddr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
return ram_addr;
|
|
||||||
|
return block->offset + offset + block->mr->addr;
|
||||||
} else {
|
} else {
|
||||||
return haddr->v.io.offset;
|
MemoryRegionSection *mrs = haddr->v.io.section;
|
||||||
|
return haddr->v.io.offset + mrs->mr->addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue