|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 22/30] ARM: vITS: handle MAPD command
On Thu, 6 Apr 2017, Andre Przywara wrote:
> The MAPD command maps a device by associating a memory region for
> storing ITEs with a certain device ID.
> We store the given guest physical address in the device table, and, if
> this command comes from Dom0, tell the host ITS driver about this new
> mapping, so it can issue the corresponding host MAPD command and create
> the required tables.
> We simply use our existing guest memory access function to find the
> right ITT entry and store the mapping there.
>
> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
> ---
> xen/arch/arm/vgic-v3-its.c | 59
> ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
> index bbca5cf..0372ed0 100644
> --- a/xen/arch/arm/vgic-v3-its.c
> +++ b/xen/arch/arm/vgic-v3-its.c
> @@ -42,6 +42,7 @@
> */
> struct virt_its {
> struct domain *d;
> + paddr_t doorbell_address;
> unsigned int devid_bits;
> unsigned int intid_bits;
> spinlock_t vcmd_lock; /* Protects the virtual command buffer,
> which */
> @@ -144,6 +145,20 @@ static struct vcpu *get_vcpu_from_collection(struct
> virt_its *its,
> #define DEV_TABLE_ENTRY(addr, bits) \
> (((addr) & GENMASK_ULL(51, 8)) | (((bits) - 1) & GENMASK_ULL(7, 0)))
>
> +/* Set the address of an ITT for a given device ID. */
> +static int its_set_itt_address(struct virt_its *its, uint32_t devid,
> + paddr_t itt_address, uint32_t nr_bits)
> +{
> + paddr_t addr = get_baser_phys_addr(its->baser_dev);
> + uint64_t itt_entry = DEV_TABLE_ENTRY(itt_address, nr_bits);
> +
> + if ( devid >= its->max_devices )
> + return -ENOENT;
> +
> + return vgic_access_guest_memory(its->d, addr + devid * sizeof(uint64_t),
> + &itt_entry, sizeof(itt_entry), true);
> +}
> +
> /*
> * Lookup the address of the Interrupt Translation Table associated with
> * a device ID and return the address of the ITTE belonging to the event ID
> @@ -384,6 +399,47 @@ static int its_handle_mapc(struct virt_its *its,
> uint64_t *cmdptr)
> return 0;
> }
>
> +static int its_handle_mapd(struct virt_its *its, uint64_t *cmdptr)
> +{
> + /* size and devid get validated by the functions called below. */
> + uint32_t devid = its_cmd_get_deviceid(cmdptr);
> + unsigned int size = its_cmd_get_size(cmdptr) + 1;
> + bool valid = its_cmd_get_validbit(cmdptr);
> + paddr_t itt_addr = its_cmd_get_ittaddr(cmdptr);
> + int ret;
The size should be sanitized against the number of event support by the
vITS
> + /*
> + * There is no easy and clean way for Xen to know the ITS device ID of a
> + * particular (PCI) device, so we have to rely on the guest telling
> + * us about it. For *now* we are just using the device ID *Dom0* uses,
> + * because the driver there has the actual knowledge.
> + * Eventually this will be replaced with a dedicated hypercall to
> + * announce pass-through of devices.
> + */
> + if ( is_hardware_domain(its->d) )
> + {
> + /*
> + * Dom0's ITSes are mapped 1:1, so both addresses are the same.
> + * Also the device IDs are equal.
> + */
> + ret = gicv3_its_map_guest_device(its->d, its->doorbell_address,
> devid,
> + its->doorbell_address, devid,
> + BIT(size), valid);
> + if ( ret )
> + return ret;
> + }
> +
> + spin_lock(&its->its_lock);
> + if ( valid )
> + ret = its_set_itt_address(its, devid, itt_addr, size);
> + else
> + ret = its_set_itt_address(its, devid, INVALID_PADDR, 1);
> +
> + spin_unlock(&its->its_lock);
> +
> + return ret;
> +}
> +
> #define ITS_CMD_BUFFER_SIZE(baser) ((((baser) & 0xff) + 1) << 12)
>
> /*
> @@ -421,6 +477,9 @@ static int vgic_its_handle_cmds(struct domain *d, struct
> virt_its *its)
> case GITS_CMD_MAPC:
> ret = its_handle_mapc(its, command);
> break;
> + case GITS_CMD_MAPD:
> + ret = its_handle_mapd(its, command);
> + break;
> case GITS_CMD_SYNC:
> /* We handle ITS commands synchronously, so we ignore SYNC. */
> break;
> --
> 2.8.2
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |