mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180531-1' into staging
target-arm queue: * target/arm: Honour FPCR.FZ in FRECPX * MAINTAINERS: Add entries for newer MPS2 boards and devices * hw/intc/arm_gicv3: Fix APxR<n> register dispatching * arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel GIC state * tcg: Fix helper function vs host abi for float16 * arm: fix qemu crash on startup with -bios option * arm: fix malloc type mismatch * xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors * Correct CPACR reset value for v7 cores * memory.h: Improve IOMMU related documentation * exec: Plumb transaction attributes through various functions in preparation for allowing IOMMUs to see them * vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY * ARM: ACPI: Fix use-after-free due to memory realloc * KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice # gpg: Signature made Thu 31 May 2018 16:54:40 BST # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180531-1: (25 commits) KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice ARM: ACPI: Fix use-after-free due to memory realloc vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY Make address_space_translate_iommu take a MemTxAttrs argument Make flatview_do_translate() take a MemTxAttrs argument Make address_space_get_iotlb_entry() take a MemTxAttrs argument Make flatview_translate() take a MemTxAttrs argument Make flatview_access_valid() take a MemTxAttrs argument Make MemoryRegion valid.accepts callback take a MemTxAttrs argument Make memory_region_access_valid() take a MemTxAttrs argument Make flatview_extend_translation() take a MemTxAttrs argument Make address_space_access_valid() take a MemTxAttrs argument Make address_space_map() take a MemTxAttrs argument Make address_space_translate{, _cached}() take a MemTxAttrs argument Make tb_invalidate_phys_addr() take a MemTxAttrs argument memory.h: Improve IOMMU related documentation Correct CPACR reset value for v7 cores xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors arm: fix malloc type mismatch arm: fix qemu crash on startup with -bios option ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+7
-2
@@ -447,6 +447,8 @@ F: hw/timer/cmsdk-apb-timer.c
|
||||
F: include/hw/timer/cmsdk-apb-timer.h
|
||||
F: hw/char/cmsdk-apb-uart.c
|
||||
F: include/hw/char/cmsdk-apb-uart.h
|
||||
F: hw/misc/tz-ppc.c
|
||||
F: include/hw/misc/tz-ppc.h
|
||||
|
||||
ARM cores
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
@@ -515,8 +517,11 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/mps2.c
|
||||
F: hw/misc/mps2-scc.c
|
||||
F: include/hw/misc/mps2-scc.h
|
||||
F: hw/arm/mps2-tz.c
|
||||
F: hw/misc/mps2-*.c
|
||||
F: include/hw/misc/mps2-*.h
|
||||
F: hw/arm/iotkit.c
|
||||
F: include/hw/arm/iotkit.h
|
||||
|
||||
Musicpal
|
||||
M: Jan Kiszka <jan.kiszka@web.de>
|
||||
|
||||
@@ -1669,14 +1669,14 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
|
||||
{
|
||||
ram_addr_t ram_addr;
|
||||
MemoryRegion *mr;
|
||||
hwaddr l = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(as, addr, &addr, &l, false);
|
||||
mr = address_space_translate(as, addr, &addr, &l, false, attrs);
|
||||
if (!(memory_region_is_ram(mr)
|
||||
|| memory_region_is_romd(mr))) {
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -478,6 +478,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
|
||||
* @is_write: whether the translation operation is for write
|
||||
* @is_mmio: whether this can be MMIO, set true if it can
|
||||
* @target_as: the address space targeted by the IOMMU
|
||||
* @attrs: transaction attributes
|
||||
*
|
||||
* This function is called from RCU critical section. It is the common
|
||||
* part of flatview_do_translate and address_space_translate_cached.
|
||||
@@ -488,7 +489,8 @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
|
||||
hwaddr *page_mask_out,
|
||||
bool is_write,
|
||||
bool is_mmio,
|
||||
AddressSpace **target_as)
|
||||
AddressSpace **target_as,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection *section;
|
||||
hwaddr page_mask = (hwaddr)-1;
|
||||
@@ -541,6 +543,7 @@ unassigned:
|
||||
* @is_write: whether the translation operation is for write
|
||||
* @is_mmio: whether this can be MMIO, set true if it can
|
||||
* @target_as: the address space targeted by the IOMMU
|
||||
* @attrs: memory transaction attributes
|
||||
*
|
||||
* This function is called from RCU critical section
|
||||
*/
|
||||
@@ -551,7 +554,8 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
||||
hwaddr *page_mask_out,
|
||||
bool is_write,
|
||||
bool is_mmio,
|
||||
AddressSpace **target_as)
|
||||
AddressSpace **target_as,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection *section;
|
||||
IOMMUMemoryRegion *iommu_mr;
|
||||
@@ -570,7 +574,7 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
||||
return address_space_translate_iommu(iommu_mr, xlat,
|
||||
plen_out, page_mask_out,
|
||||
is_write, is_mmio,
|
||||
target_as);
|
||||
target_as, attrs);
|
||||
}
|
||||
if (page_mask_out) {
|
||||
/* Not behind an IOMMU, use default page size. */
|
||||
@@ -582,7 +586,7 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
||||
|
||||
/* Called from RCU critical section */
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write)
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
hwaddr xlat, page_mask;
|
||||
@@ -592,7 +596,8 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
* but page mask.
|
||||
*/
|
||||
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
|
||||
NULL, &page_mask, is_write, false, &as);
|
||||
NULL, &page_mask, is_write, false, &as,
|
||||
attrs);
|
||||
|
||||
/* Illegal translation */
|
||||
if (section.mr == &io_mem_unassigned) {
|
||||
@@ -618,7 +623,8 @@ iotlb_fail:
|
||||
|
||||
/* Called from RCU critical section */
|
||||
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen, bool is_write)
|
||||
hwaddr *plen, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
MemoryRegionSection section;
|
||||
@@ -626,7 +632,7 @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
|
||||
|
||||
/* This can be MMIO, so setup MMIO bit. */
|
||||
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
|
||||
is_write, true, &as);
|
||||
is_write, true, &as, attrs);
|
||||
mr = section.mr;
|
||||
|
||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||
@@ -898,7 +904,7 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
if (phys != -1) {
|
||||
/* Locks grabbed by tb_invalidate_phys_addr */
|
||||
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
|
||||
phys | (pc & ~TARGET_PAGE_MASK));
|
||||
phys | (pc & ~TARGET_PAGE_MASK), attrs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2539,7 +2545,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
|
||||
}
|
||||
|
||||
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write;
|
||||
}
|
||||
@@ -2696,7 +2703,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
||||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len);
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write);
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
|
||||
unsigned len, MemTxAttrs attrs)
|
||||
@@ -2762,7 +2769,8 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool subpage_accepts(void *opaque, hwaddr addr,
|
||||
unsigned len, bool is_write)
|
||||
unsigned len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
subpage_t *subpage = opaque;
|
||||
#if defined(DEBUG_SUBPAGE)
|
||||
@@ -2771,7 +2779,7 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
|
||||
#endif
|
||||
|
||||
return flatview_access_valid(subpage->fv, addr + subpage->base,
|
||||
len, is_write);
|
||||
len, is_write, attrs);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps subpage_ops = {
|
||||
@@ -2845,7 +2853,8 @@ static void readonly_mem_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write;
|
||||
}
|
||||
@@ -3149,7 +3158,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
|
||||
}
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -3165,7 +3174,7 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
MemTxResult result = MEMTX_OK;
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
|
||||
result = flatview_write_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
|
||||
@@ -3236,7 +3245,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
||||
}
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -3251,7 +3260,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
||||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
return flatview_read_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
}
|
||||
@@ -3322,7 +3331,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
||||
rcu_read_lock();
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
|
||||
if (!(memory_region_is_ram(mr) ||
|
||||
memory_region_is_romd(mr))) {
|
||||
@@ -3457,17 +3467,17 @@ static void cpu_notify_map_clients(void)
|
||||
}
|
||||
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write)
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
hwaddr l, xlat;
|
||||
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
l = memory_access_size(mr, l, addr);
|
||||
if (!memory_region_access_valid(mr, xlat, l, is_write)) {
|
||||
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3479,23 +3489,24 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
}
|
||||
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
|
||||
int len, bool is_write)
|
||||
int len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
FlatView *fv;
|
||||
bool result;
|
||||
|
||||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
result = flatview_access_valid(fv, addr, len, is_write);
|
||||
result = flatview_access_valid(fv, addr, len, is_write, attrs);
|
||||
rcu_read_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
static hwaddr
|
||||
flatview_extend_translation(FlatView *fv, hwaddr addr,
|
||||
hwaddr target_len,
|
||||
MemoryRegion *mr, hwaddr base, hwaddr len,
|
||||
bool is_write)
|
||||
hwaddr target_len,
|
||||
MemoryRegion *mr, hwaddr base, hwaddr len,
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
hwaddr done = 0;
|
||||
hwaddr xlat;
|
||||
@@ -3511,7 +3522,7 @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
|
||||
|
||||
len = target_len;
|
||||
this_mr = flatview_translate(fv, addr, &xlat,
|
||||
&len, is_write);
|
||||
&len, is_write, attrs);
|
||||
if (this_mr != mr || xlat != base + done) {
|
||||
return done;
|
||||
}
|
||||
@@ -3528,7 +3539,8 @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
|
||||
void *address_space_map(AddressSpace *as,
|
||||
hwaddr addr,
|
||||
hwaddr *plen,
|
||||
bool is_write)
|
||||
bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
hwaddr len = *plen;
|
||||
hwaddr l, xlat;
|
||||
@@ -3543,7 +3555,7 @@ void *address_space_map(AddressSpace *as,
|
||||
l = len;
|
||||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
||||
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
if (atomic_xchg(&bounce.in_use, true)) {
|
||||
@@ -3571,7 +3583,7 @@ void *address_space_map(AddressSpace *as,
|
||||
|
||||
memory_region_ref(mr);
|
||||
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
|
||||
l, is_write);
|
||||
l, is_write, attrs);
|
||||
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -3615,7 +3627,8 @@ void *cpu_physical_memory_map(hwaddr addr,
|
||||
hwaddr *plen,
|
||||
int is_write)
|
||||
{
|
||||
return address_space_map(&address_space_memory, addr, plen, is_write);
|
||||
return address_space_map(&address_space_memory, addr, plen, is_write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
}
|
||||
|
||||
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
|
||||
@@ -3655,8 +3668,13 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
|
||||
mr = cache->mrs.mr;
|
||||
memory_region_ref(mr);
|
||||
if (memory_access_is_direct(mr, is_write)) {
|
||||
/* We don't care about the memory attributes here as we're only
|
||||
* doing this if we found actual RAM, which behaves the same
|
||||
* regardless of attributes; so UNSPECIFIED is fine.
|
||||
*/
|
||||
l = flatview_extend_translation(cache->fv, addr, len, mr,
|
||||
cache->xlat, l, is_write);
|
||||
cache->xlat, l, is_write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
|
||||
} else {
|
||||
cache->ptr = NULL;
|
||||
@@ -3699,7 +3717,7 @@ void address_space_cache_destroy(MemoryRegionCache *cache)
|
||||
*/
|
||||
static inline MemoryRegion *address_space_translate_cached(
|
||||
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen, bool is_write)
|
||||
hwaddr *plen, bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
MemoryRegion *mr;
|
||||
@@ -3718,7 +3736,7 @@ static inline MemoryRegion *address_space_translate_cached(
|
||||
|
||||
section = address_space_translate_iommu(iommu_mr, xlat, plen,
|
||||
NULL, is_write, true,
|
||||
&target_as);
|
||||
&target_as, attrs);
|
||||
return section.mr;
|
||||
}
|
||||
|
||||
@@ -3733,7 +3751,8 @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
flatview_read_continue(cache->fv,
|
||||
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
|
||||
addr1, l, mr);
|
||||
@@ -3750,7 +3769,8 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
flatview_write_continue(cache->fv,
|
||||
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
|
||||
addr1, l, mr);
|
||||
@@ -3848,7 +3868,8 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
|
||||
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(&address_space_memory,
|
||||
phys_addr, &phys_addr, &l, false);
|
||||
phys_addr, &phys_addr, &l, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
|
||||
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
|
||||
rcu_read_unlock();
|
||||
|
||||
+9
-9
@@ -926,6 +926,15 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
||||
static const ARMInsnFixup *primary_loader;
|
||||
AddressSpace *as = arm_boot_address_space(cpu, info);
|
||||
|
||||
/* CPU objects (unlike devices) are not automatically reset on system
|
||||
* reset, so we must always register a handler to do so. If we're
|
||||
* actually loading a kernel, the handler is also responsible for
|
||||
* arranging that we start it correctly.
|
||||
*/
|
||||
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
|
||||
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
|
||||
}
|
||||
|
||||
/* The board code is not supposed to set secure_board_setup unless
|
||||
* running its code in secure mode is actually possible, and KVM
|
||||
* doesn't support secure.
|
||||
@@ -1143,15 +1152,6 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
||||
ARM_CPU(cs)->env.boot_info = info;
|
||||
}
|
||||
|
||||
/* CPU objects (unlike devices) are not automatically reset on system
|
||||
* reset, so we must always register a handler to do so. If we're
|
||||
* actually loading a kernel, the handler is also responsible for
|
||||
* arranging that we start it correctly.
|
||||
*/
|
||||
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
|
||||
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
|
||||
}
|
||||
|
||||
if (!info->skip_dtb_autoload && have_dtb(info)) {
|
||||
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
|
||||
exit(1);
|
||||
|
||||
@@ -400,7 +400,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
AcpiIortItsGroup *its;
|
||||
AcpiIortTable *iort;
|
||||
AcpiIortSmmu3 *smmu;
|
||||
size_t node_size, iort_length, smmu_offset = 0;
|
||||
size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
|
||||
AcpiIortRC *rc;
|
||||
|
||||
iort = acpi_data_push(table_data, sizeof(*iort));
|
||||
@@ -413,7 +413,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
|
||||
iort_length = sizeof(*iort);
|
||||
iort->node_count = cpu_to_le32(nb_nodes);
|
||||
iort->node_offset = cpu_to_le32(sizeof(*iort));
|
||||
/*
|
||||
* Use a copy in case table_data->data moves during acpi_data_push
|
||||
* operations.
|
||||
*/
|
||||
iort_node_offset = sizeof(*iort);
|
||||
iort->node_offset = cpu_to_le32(iort_node_offset);
|
||||
|
||||
/* ITS group node */
|
||||
node_size = sizeof(*its) + sizeof(uint32_t);
|
||||
@@ -429,7 +434,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
int irq = vms->irqmap[VIRT_SMMU];
|
||||
|
||||
/* SMMUv3 node */
|
||||
smmu_offset = iort->node_offset + node_size;
|
||||
smmu_offset = iort_node_offset + node_size;
|
||||
node_size = sizeof(*smmu) + sizeof(*idmap);
|
||||
iort_length += node_size;
|
||||
smmu = acpi_data_push(table_data, node_size);
|
||||
@@ -450,7 +455,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
idmap->id_count = cpu_to_le32(0xFFFF);
|
||||
idmap->output_base = 0;
|
||||
/* output IORT node is the ITS group node (the first node) */
|
||||
idmap->output_reference = cpu_to_le32(iort->node_offset);
|
||||
idmap->output_reference = cpu_to_le32(iort_node_offset);
|
||||
}
|
||||
|
||||
/* Root Complex Node */
|
||||
@@ -479,9 +484,14 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
idmap->output_reference = cpu_to_le32(smmu_offset);
|
||||
} else {
|
||||
/* output IORT node is the ITS group node (the first node) */
|
||||
idmap->output_reference = cpu_to_le32(iort->node_offset);
|
||||
idmap->output_reference = cpu_to_le32(iort_node_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the pointer address in case table_data->data moves during above
|
||||
* acpi_data_push operations.
|
||||
*/
|
||||
iort = (AcpiIortTable *)(table_data->data + iort_start);
|
||||
iort->length = cpu_to_le32(iort_length);
|
||||
|
||||
build_header(linker, table_data, (void *)(table_data->data + iort_start),
|
||||
|
||||
+7
-3
@@ -302,7 +302,7 @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"zdma: unaligned descriptor at %" PRIx64,
|
||||
addr);
|
||||
memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
|
||||
memset(buf, 0x0, sizeof(XlnxZDMADescr));
|
||||
s->error = true;
|
||||
return false;
|
||||
}
|
||||
@@ -707,9 +707,11 @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
|
||||
RegisterInfo *r = &s->regs_info[addr / 4];
|
||||
|
||||
if (!r->data) {
|
||||
gchar *path = object_get_canonical_path(OBJECT(s));
|
||||
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
|
||||
object_get_canonical_path(OBJECT(s)),
|
||||
path,
|
||||
addr);
|
||||
g_free(path);
|
||||
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
|
||||
zdma_ch_imr_update_irq(s);
|
||||
return 0;
|
||||
@@ -724,9 +726,11 @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
|
||||
RegisterInfo *r = &s->regs_info[addr / 4];
|
||||
|
||||
if (!r->data) {
|
||||
gchar *path = object_get_canonical_path(OBJECT(s));
|
||||
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
|
||||
object_get_canonical_path(OBJECT(s)),
|
||||
path,
|
||||
addr, value);
|
||||
g_free(path);
|
||||
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
|
||||
zdma_ch_imr_update_irq(s);
|
||||
return;
|
||||
|
||||
+2
-1
@@ -137,7 +137,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
|
||||
}
|
||||
|
||||
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
switch (addr) {
|
||||
case DINO_IAR0:
|
||||
|
||||
@@ -572,7 +572,6 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
if (kvm_has_gsi_routing()) {
|
||||
/* set up irq routing */
|
||||
kvm_init_irq_routing(kvm_state);
|
||||
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
|
||||
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
uint64_t value = cs->ich_apr[grp][regno];
|
||||
|
||||
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
@@ -439,7 +439,7 @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
|
||||
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
|
||||
@@ -1461,7 +1461,7 @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
uint64_t value;
|
||||
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
|
||||
|
||||
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
|
||||
return icv_ap_read(env, ri);
|
||||
@@ -1483,7 +1483,7 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
|
||||
|
||||
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
|
||||
icv_ap_write(env, ri, value);
|
||||
@@ -2292,7 +2292,7 @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
uint64_t value;
|
||||
|
||||
value = cs->ich_apr[grp][regno];
|
||||
@@ -2305,7 +2305,7 @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
|
||||
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
|
||||
if (clroffset != 0) {
|
||||
reg = 0;
|
||||
kvm_gicd_access(s, clroffset, ®, true);
|
||||
clroffset += 4;
|
||||
}
|
||||
reg = *gic_bmp_ptr32(bmp, irq);
|
||||
kvm_gicd_access(s, offset, ®, true);
|
||||
@@ -760,7 +761,6 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
if (kvm_has_gsi_routing()) {
|
||||
/* set up irq routing */
|
||||
kvm_init_irq_routing(kvm_state);
|
||||
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
|
||||
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
}
|
||||
|
||||
+8
-4
@@ -420,14 +420,16 @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
|
||||
(size == 8 && addr == 0));
|
||||
}
|
||||
|
||||
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return addr == 0;
|
||||
}
|
||||
@@ -439,7 +441,8 @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write && size == 2;
|
||||
}
|
||||
@@ -458,7 +461,8 @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return (size == 1) || (is_write && size == 2);
|
||||
}
|
||||
|
||||
@@ -762,7 +762,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
|
||||
mr = s390_get_subregion(mr, offset, len);
|
||||
offset -= mr->addr;
|
||||
|
||||
if (!memory_region_access_valid(mr, offset, len, true)) {
|
||||
if (!memory_region_access_valid(mr, offset, len, true,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-1
@@ -564,7 +564,8 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
||||
}
|
||||
|
||||
static bool esp_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return (size == 1) || (is_write && size == 4);
|
||||
}
|
||||
|
||||
+2
-1
@@ -324,7 +324,8 @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
|
||||
*/
|
||||
mr = address_space_translate(&address_space_memory,
|
||||
iotlb->translated_addr,
|
||||
&xlat, &len, writable);
|
||||
&xlat, &len, writable,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (!memory_region_is_ram(mr)) {
|
||||
error_report("iommu map to non memory area %"HWADDR_PRIx"",
|
||||
xlat);
|
||||
|
||||
+2
-1
@@ -897,7 +897,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
|
||||
trace_vhost_iotlb_miss(dev, 1);
|
||||
|
||||
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
|
||||
iova, write);
|
||||
iova, write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (iotlb.target_as != NULL) {
|
||||
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
|
||||
&uaddr, &len);
|
||||
|
||||
+2
-1
@@ -498,7 +498,8 @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static bool pci_msix_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return !(addr & (size - 1));
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
|
||||
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||
hwaddr paddr, int prot,
|
||||
int mmu_idx, target_ulong size);
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
|
||||
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
|
||||
uintptr_t retaddr);
|
||||
#else
|
||||
@@ -303,7 +303,8 @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
|
||||
uint16_t idxmap)
|
||||
{
|
||||
}
|
||||
static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
|
||||
static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define dh_ctype_int int
|
||||
#define dh_ctype_i64 uint64_t
|
||||
#define dh_ctype_s64 int64_t
|
||||
#define dh_ctype_f16 float16
|
||||
#define dh_ctype_f16 uint32_t
|
||||
#define dh_ctype_f32 float32
|
||||
#define dh_ctype_f64 float64
|
||||
#define dh_ctype_ptr void *
|
||||
|
||||
@@ -37,7 +37,8 @@ void flatview_unref(FlatView *view);
|
||||
extern const MemoryRegionOps unassigned_mem_ops;
|
||||
|
||||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
|
||||
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
|
||||
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
|
||||
|
||||
+110
-18
@@ -166,7 +166,8 @@ struct MemoryRegionOps {
|
||||
* as a machine check exception).
|
||||
*/
|
||||
bool (*accepts)(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
} valid;
|
||||
/* Internal implementation constraints: */
|
||||
struct {
|
||||
@@ -194,29 +195,100 @@ enum IOMMUMemoryRegionAttr {
|
||||
IOMMU_ATTR_SPAPR_TCE_FD
|
||||
};
|
||||
|
||||
/**
|
||||
* IOMMUMemoryRegionClass:
|
||||
*
|
||||
* All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
|
||||
* and provide an implementation of at least the @translate method here
|
||||
* to handle requests to the memory region. Other methods are optional.
|
||||
*
|
||||
* The IOMMU implementation must use the IOMMU notifier infrastructure
|
||||
* to report whenever mappings are changed, by calling
|
||||
* memory_region_notify_iommu() (or, if necessary, by calling
|
||||
* memory_region_notify_one() for each registered notifier).
|
||||
*/
|
||||
typedef struct IOMMUMemoryRegionClass {
|
||||
/* private */
|
||||
struct DeviceClass parent_class;
|
||||
|
||||
/*
|
||||
* Return a TLB entry that contains a given address. Flag should
|
||||
* be the access permission of this translation operation. We can
|
||||
* set flag to IOMMU_NONE to mean that we don't need any
|
||||
* read/write permission checks, like, when for region replay.
|
||||
* Return a TLB entry that contains a given address.
|
||||
*
|
||||
* The IOMMUAccessFlags indicated via @flag are optional and may
|
||||
* be specified as IOMMU_NONE to indicate that the caller needs
|
||||
* the full translation information for both reads and writes. If
|
||||
* the access flags are specified then the IOMMU implementation
|
||||
* may use this as an optimization, to stop doing a page table
|
||||
* walk as soon as it knows that the requested permissions are not
|
||||
* allowed. If IOMMU_NONE is passed then the IOMMU must do the
|
||||
* full page table walk and report the permissions in the returned
|
||||
* IOMMUTLBEntry. (Note that this implies that an IOMMU may not
|
||||
* return different mappings for reads and writes.)
|
||||
*
|
||||
* The returned information remains valid while the caller is
|
||||
* holding the big QEMU lock or is inside an RCU critical section;
|
||||
* if the caller wishes to cache the mapping beyond that it must
|
||||
* register an IOMMU notifier so it can invalidate its cached
|
||||
* information when the IOMMU mapping changes.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @hwaddr: address to be translated within the memory region
|
||||
* @flag: requested access permissions
|
||||
*/
|
||||
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
|
||||
IOMMUAccessFlags flag);
|
||||
/* Returns minimum supported page size */
|
||||
/* Returns minimum supported page size in bytes.
|
||||
* If this method is not provided then the minimum is assumed to
|
||||
* be TARGET_PAGE_SIZE.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
*/
|
||||
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
|
||||
/* Called when IOMMU Notifier flag changed */
|
||||
/* Called when IOMMU Notifier flag changes (ie when the set of
|
||||
* events which IOMMU users are requesting notification for changes).
|
||||
* Optional method -- need not be provided if the IOMMU does not
|
||||
* need to know exactly which events must be notified.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @old_flags: events which previously needed to be notified
|
||||
* @new_flags: events which now need to be notified
|
||||
*/
|
||||
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
|
||||
IOMMUNotifierFlag old_flags,
|
||||
IOMMUNotifierFlag new_flags);
|
||||
/* Set this up to provide customized IOMMU replay function */
|
||||
/* Called to handle memory_region_iommu_replay().
|
||||
*
|
||||
* The default implementation of memory_region_iommu_replay() is to
|
||||
* call the IOMMU translate method for every page in the address space
|
||||
* with flag == IOMMU_NONE and then call the notifier if translate
|
||||
* returns a valid mapping. If this method is implemented then it
|
||||
* overrides the default behaviour, and must provide the full semantics
|
||||
* of memory_region_iommu_replay(), by calling @notifier for every
|
||||
* translation present in the IOMMU.
|
||||
*
|
||||
* Optional method -- an IOMMU only needs to provide this method
|
||||
* if the default is inefficient or produces undesirable side effects.
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*/
|
||||
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
|
||||
|
||||
/* Get IOMMU misc attributes */
|
||||
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
|
||||
/* Get IOMMU misc attributes. This is an optional method that
|
||||
* can be used to allow users of the IOMMU to get implementation-specific
|
||||
* information. The IOMMU implements this method to handle calls
|
||||
* by IOMMU users to memory_region_iommu_get_attr() by filling in
|
||||
* the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
|
||||
* the IOMMU supports. If the method is unimplemented then
|
||||
* memory_region_iommu_get_attr() will always return -EINVAL.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @attr: attribute being queried
|
||||
* @data: memory to fill in with the attribute data
|
||||
*
|
||||
* Returns 0 on success, or a negative errno; in particular
|
||||
* returns -EINVAL for unrecognized or unimplemented attribute types.
|
||||
*/
|
||||
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
|
||||
void *data);
|
||||
} IOMMUMemoryRegionClass;
|
||||
|
||||
@@ -705,6 +777,14 @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
|
||||
* An IOMMU region translates addresses and forwards accesses to a target
|
||||
* memory region.
|
||||
*
|
||||
* The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
|
||||
* @_iommu_mr should be a pointer to enough memory for an instance of
|
||||
* that subclass, @instance_size is the size of that subclass, and
|
||||
* @mrtypename is its name. This function will initialize @_iommu_mr as an
|
||||
* instance of the subclass, and its methods will then be called to handle
|
||||
* accesses to the memory region. See the documentation of
|
||||
* #IOMMUMemoryRegionClass for further details.
|
||||
*
|
||||
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
|
||||
* @instance_size: the IOMMUMemoryRegion subclass instance size
|
||||
* @mrtypename: the type name of the #IOMMUMemoryRegion
|
||||
@@ -953,6 +1033,8 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
|
||||
* a notifier with the minimum page granularity returned by
|
||||
* mr->iommu_ops->get_page_size().
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*
|
||||
* @iommu_mr: the memory region to observe
|
||||
* @n: the notifier to which to replay iommu mappings
|
||||
*/
|
||||
@@ -962,6 +1044,8 @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
|
||||
* memory_region_iommu_replay_all: replay existing IOMMU translations
|
||||
* to all the notifiers registered.
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*
|
||||
* @iommu_mr: the memory region to observe
|
||||
*/
|
||||
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
|
||||
@@ -981,7 +1065,9 @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
|
||||
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
|
||||
* defined on the IOMMU.
|
||||
*
|
||||
* Returns 0 if succeded, error code otherwise.
|
||||
* Returns 0 on success, or a negative errno otherwise. In particular,
|
||||
* -EINVAL indicates that the IOMMU does not support the requested
|
||||
* attribute.
|
||||
*
|
||||
* @iommu_mr: the memory region
|
||||
* @attr: the requested attribute
|
||||
@@ -1810,7 +1896,7 @@ void address_space_cache_destroy(MemoryRegionCache *cache);
|
||||
* entry. Should be called from an RCU critical section.
|
||||
*/
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write);
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_translate: translate an address range into an address space
|
||||
* into a MemoryRegion and an address range into that section. Should be
|
||||
@@ -1823,17 +1909,20 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
* #MemoryRegion.
|
||||
* @len: pointer to length
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
MemoryRegion *flatview_translate(FlatView *fv,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write);
|
||||
hwaddr *len, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
|
||||
static inline MemoryRegion *address_space_translate(AddressSpace *as,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write)
|
||||
hwaddr *len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return flatview_translate(address_space_to_flatview(as),
|
||||
addr, xlat, len, is_write);
|
||||
addr, xlat, len, is_write, attrs);
|
||||
}
|
||||
|
||||
/* address_space_access_valid: check for validity of accessing an address
|
||||
@@ -1850,8 +1939,10 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
|
||||
* @addr: address within that address space
|
||||
* @len: length of the area to be checked
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_map: map a physical memory region into a host virtual address
|
||||
*
|
||||
@@ -1865,9 +1956,10 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
|
||||
* @addr: address within that address space
|
||||
* @plen: pointer to length of buffer; updated on return
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
void *address_space_map(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *plen, bool is_write);
|
||||
hwaddr *plen, bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
|
||||
*
|
||||
@@ -1939,7 +2031,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
||||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
if (len == l && memory_access_is_direct(mr, false)) {
|
||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||
memcpy(buf, ptr, len);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user