diff options
| author | Anthony Liguori <aliguori@us.ibm.com> | 2013-06-20 16:53:39 -0500 |
|---|---|---|
| committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-06-20 16:53:39 -0500 |
| commit | 576156ffed72ab4feb0b752979db86ff8759a2a1 (patch) | |
| tree | 840956ef1f6138f7a0be8d497f8baad6a31d7722 /include/exec/memory.h | |
| parent | b1588c3fd6daf6e23ba727c758f84ada279ae731 (diff) | |
| parent | 2eb74e1a1ef145034aa41255c4a6f469d560c96d (diff) | |
| download | focaccia-qemu-576156ffed72ab4feb0b752979db86ff8759a2a1.tar.gz focaccia-qemu-576156ffed72ab4feb0b752979db86ff8759a2a1.zip | |
Merge remote-tracking branch 'bonzini/iommu-for-anthony' into staging
# By Paolo Bonzini (12) and others # Via Paolo Bonzini * bonzini/iommu-for-anthony: (25 commits) memory: render_memory_region: factor out fr constant setters memory: as_update_topology_pass: Improve comments memory: Fix comment typo memory: give name to every AddressSpace dma: eliminate DMAContext spapr_vio: take care of creating our own AddressSpace/DMAContext pci: use memory core for iommu support dma: eliminate old-style IOMMU support spapr: use memory core for iommu support spapr: make IOMMU translation go through IOMMUTLBEntry spapr: convert TCE API to use an opaque type vfio: abort if an emulated iommu is used memory: Add iommu map/unmap notifiers memory: iommu support memory: make section size a 128-bit integer exec: reorganize mem_add to match Int128 version Revert "s390x: reduce TARGET_PHYS_ADDR_SPACE_BITS to 62" Revert "memory: limit sections in the radix tree to the actual address space size" exec: return MemoryRegion from address_space_translate exec: Implement subpage_read/write via address_space_rw ... Message-id: 1371739493-10187-1-git-send-email-pbonzini@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'include/exec/memory.h')
| -rw-r--r-- | include/exec/memory.h | 114 |
1 files changed, 103 insertions, 11 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h index d53a6a1b88..3598c4f914 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -25,6 +25,7 @@ #include "exec/iorange.h" #include "exec/ioport.h" #include "qemu/int128.h" +#include "qemu/notify.h" #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) @@ -53,6 +54,24 @@ struct MemoryRegionIORange { hwaddr offset; }; +typedef struct IOMMUTLBEntry IOMMUTLBEntry; + +/* See address_space_translate: bit 0 is read, bit 1 is write. */ +typedef enum { + IOMMU_NONE = 0, + IOMMU_RO = 1, + IOMMU_WO = 2, + IOMMU_RW = 3, +} IOMMUAccessFlags; + +struct IOMMUTLBEntry { + AddressSpace *target_as; + hwaddr iova; + hwaddr translated_addr; + hwaddr addr_mask; /* 0xfff = 4k translation */ + IOMMUAccessFlags perm; +}; + /* * Memory region callbacks */ @@ -115,12 +134,20 @@ struct MemoryRegionOps { const MemoryRegionMmio old_mmio; }; +typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps; + +struct MemoryRegionIOMMUOps { + /* Return a TLB entry that contains a given address. */ + IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr); +}; + typedef struct CoalescedMemoryRange CoalescedMemoryRange; typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; struct MemoryRegion { /* All fields are private - violators will be prosecuted */ const MemoryRegionOps *ops; + const MemoryRegionIOMMUOps *iommu_ops; void *opaque; MemoryRegion *parent; Int128 size; @@ -147,6 +174,7 @@ struct MemoryRegion { uint8_t dirty_log_mask; unsigned ioeventfd_nb; MemoryRegionIoeventfd *ioeventfds; + NotifierList iommu_notify; }; struct MemoryRegionPortio { @@ -164,7 +192,7 @@ struct MemoryRegionPortio { */ struct AddressSpace { /* All fields are private. */ - const char *name; + char *name; MemoryRegion *root; struct FlatView *current_map; int ioeventfd_nb; @@ -188,7 +216,7 @@ struct MemoryRegionSection { MemoryRegion *mr; AddressSpace *address_space; hwaddr offset_within_region; - uint64_t size; + Int128 size; hwaddr offset_within_address_space; bool readonly; }; @@ -332,6 +360,24 @@ void memory_region_init_rom_device(MemoryRegion *mr, void memory_region_init_reservation(MemoryRegion *mr, const char *name, uint64_t size); + +/** + * memory_region_init_iommu: Initialize a memory region that translates + * addresses + * + * An IOMMU region translates addresses and forwards accesses to a target + * memory region. + * + * @mr: the #MemoryRegion to be initialized + * @ops: a function that translates addresses into the @target region + * @name: used for debugging; not visible to the user or ABI + * @size: size of the region. + */ +void memory_region_init_iommu(MemoryRegion *mr, + const MemoryRegionIOMMUOps *ops, + const char *name, + uint64_t size); + /** * memory_region_destroy: Destroy a memory region and reclaim all resources. * @@ -371,6 +417,45 @@ static inline bool memory_region_is_romd(MemoryRegion *mr) } /** + * memory_region_is_iommu: check whether a memory region is an iommu + * + * Returns %true is a memory region is an iommu. + * + * @mr: the memory region being queried + */ +bool memory_region_is_iommu(MemoryRegion *mr); + +/** + * memory_region_notify_iommu: notify a change in an IOMMU translation entry. + * + * @mr: the memory region that was changed + * @entry: the new entry in the IOMMU translation table. The entry + * replaces all old entries for the same virtual I/O address range. + * Deleted entries have .@perm == 0. + */ +void memory_region_notify_iommu(MemoryRegion *mr, + IOMMUTLBEntry entry); + +/** + * memory_region_register_iommu_notifier: register a notifier for changes to + * IOMMU translation entries. + * + * @mr: the memory region to observe + * @n: the notifier to be added; the notifier receives a pointer to an + * #IOMMUTLBEntry as the opaque value; the pointer ceases to be + * valid on exit from the notifier. + */ +void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n); + +/** + * memory_region_unregister_iommu_notifier: unregister a notifier for + * changes to IOMMU translation entries. + * + * @n: the notifier to be removed. + */ +void memory_region_unregister_iommu_notifier(Notifier *n); + +/** * memory_region_name: get a memory region's name * * Returns the string that was used to initialize the memory region. @@ -807,8 +892,10 @@ void mtree_info(fprintf_function mon_printf, void *f); * * @as: an uninitialized #AddressSpace * @root: a #MemoryRegion that routes addesses for the address space + * @name: an address space name. The name is only used for debugging + * output. */ -void address_space_init(AddressSpace *as, MemoryRegion *root); +void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name); /** @@ -825,7 +912,8 @@ void address_space_destroy(AddressSpace *as); /** * address_space_rw: read from or write to an address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -838,7 +926,8 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, /** * address_space_write: write to address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -850,7 +939,8 @@ bool address_space_write(AddressSpace *as, hwaddr addr, /** * address_space_read: read from an address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -859,7 +949,7 @@ bool address_space_write(AddressSpace *as, hwaddr addr, bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len); /* address_space_translate: translate an address range into an address space - * into a MemoryRegionSection and an address range into that section + * into a MemoryRegion and an address range into that section * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -868,14 +958,16 @@ bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len); * @len: pointer to length * @is_write: indicates the transfer direction */ -MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr, - hwaddr *xlat, hwaddr *len, - bool is_write); +MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, + hwaddr *xlat, hwaddr *len, + bool is_write); /* address_space_access_valid: check for validity of accessing an address * space range * - * Check whether memory is assigned to the given address space range. + * Check whether memory is assigned to the given address space range, and + * access is permitted by any IOMMU regions that are active for the address + * space. * * For now, addr and len should be aligned to a page size. This limitation * will be lifted in the future. |