Hi Andre,
On 03/04/17 21:28, Andre Przywara wrote:
This introduces the ITS command handler for the CLEAR command, which
clears the pending state of an LPI.
This removes a not-yet injected, but already queued IRQ from a VCPU.
As read_itte() is now eventually used, we add the static keyword.
Signed-off-by: Andre Przywara <andre.przyw...@arm.com>
---
xen/arch/arm/vgic-v3-its.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index fcfea3b..cc1d7a0 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -186,8 +186,8 @@ static void put_itte(struct virt_its *its, struct vits_itte
*itte)
* This function takes care of the locking by taking the its_lock itself, so
* a caller shall not hold this. Upon returning, the lock is dropped again.
*/
-bool read_itte(struct virt_its *its, uint32_t devid, uint32_t evid,
- struct vcpu **vcpu, uint32_t *vlpi)
+static bool read_itte(struct virt_its *its, uint32_t devid, uint32_t evid,
+ struct vcpu **vcpu, uint32_t *vlpi)
{
struct vits_itte *itte;
uint16_t collid;
@@ -273,6 +273,30 @@ static uint64_t its_cmd_mask_field(uint64_t *its_cmd,
unsigned int word,
#define its_cmd_get_target_addr(cmd) its_cmd_mask_field(cmd, 2, 16, 32)
#define its_cmd_get_validbit(cmd) its_cmd_mask_field(cmd, 2, 63, 1)
+static int its_handle_clear(struct virt_its *its, uint64_t *cmdptr)
+{
+ uint32_t devid = its_cmd_get_deviceid(cmdptr);
+ uint32_t eventid = its_cmd_get_id(cmdptr);
+ struct pending_irq *p;
+ struct vcpu *vcpu;
+ uint32_t vlpi;
+
+ if ( !read_itte(its, devid, eventid, &vcpu, &vlpi) )
+ return -1;
+
+ p = lpi_to_pending(its->d, vlpi);
+ if ( !p )
+ return -1;
+
+ clear_bit(GIC_IRQ_GUEST_LPI_PENDING, &p->status);
+
+ /* Remove a pending, but not yet injected guest IRQ. */
Copying Stefano's comment from last year:
"We need to check that the vlpi hasn't already been added to an LR
register. We can do that with GIC_IRQ_GUEST_VISIBLE.
In case GIC_IRQ_GUEST_VISIBLE is set, we need to clear the lr
(clear_lr). If we don't handle this case, we should at least print a
warning."
I will let Stefano comments more here.
+ clear_bit(GIC_IRQ_GUEST_QUEUED, &p->status);
+ gic_remove_from_queues(vcpu, vlpi);
+
+ return 0;
+}
+
#define ITS_CMD_BUFFER_SIZE(baser) ((((baser) & 0xff) + 1) << 12)
static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its,
@@ -310,6 +334,9 @@ static int vgic_its_handle_cmds(struct domain *d, struct
virt_its *its,
switch ( its_cmd_get_command(cmdptr) )
{
+ case GITS_CMD_CLEAR:
+ ret = its_handle_clear(its, cmdptr);
+ break;
case GITS_CMD_SYNC:
/* We handle ITS commands synchronously, so we ignore SYNC. */
break;
Regards,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel