diff mbox series

[v3,1/4] KVM: arm64: GICv4.1: Add function to get VLPI state

Message ID 20210127121337.1092-2-lushenming@huawei.com (mailing list archive)
State New, archived
Headers show
Series KVM: arm64: Add VLPI migration support on GICv4.1 | expand

Commit Message

Shenming Lu Jan. 27, 2021, 12:13 p.m. UTC
With GICv4.1 and the vPE unmapped, which indicates the invalidation
of any VPT caches associated with the vPE, we can get the VLPI state
by peeking at the VPT. So we add a function for this.

Signed-off-by: Shenming Lu <lushenming@huawei.com>
---
 arch/arm64/kvm/vgic/vgic-v4.c | 19 +++++++++++++++++++
 arch/arm64/kvm/vgic/vgic.h    |  1 +
 2 files changed, 20 insertions(+)

Comments

Marc Zyngier March 11, 2021, 8:57 a.m. UTC | #1
On Wed, 27 Jan 2021 12:13:34 +0000,
Shenming Lu <lushenming@huawei.com> wrote:
> 
> With GICv4.1 and the vPE unmapped, which indicates the invalidation
> of any VPT caches associated with the vPE, we can get the VLPI state
> by peeking at the VPT. So we add a function for this.
> 
> Signed-off-by: Shenming Lu <lushenming@huawei.com>
> ---
>  arch/arm64/kvm/vgic/vgic-v4.c | 19 +++++++++++++++++++
>  arch/arm64/kvm/vgic/vgic.h    |  1 +
>  2 files changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
> index 66508b03094f..ac029ba3d337 100644
> --- a/arch/arm64/kvm/vgic/vgic-v4.c
> +++ b/arch/arm64/kvm/vgic/vgic-v4.c
> @@ -203,6 +203,25 @@ void vgic_v4_configure_vsgis(struct kvm *kvm)
>  	kvm_arm_resume_guest(kvm);
>  }
>  
> +/*
> + * Must be called with GICv4.1 and the vPE unmapped, which
> + * indicates the invalidation of any VPT caches associated
> + * with the vPE, thus we can get the VLPI state by peeking
> + * at the VPT.
> + */
> +void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
> +{
> +	struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
> +	int mask = BIT(irq->intid % BITS_PER_BYTE);
> +	void *va;
> +	u8 *ptr;
> +
> +	va = page_address(vpe->vpt_page);
> +	ptr = va + irq->intid / BITS_PER_BYTE;
> +
> +	*val = !!(*ptr & mask);

What guarantees that you can actually read anything valid? Yes, the
VPT caches are clean. But that doesn't make them coherent with CPU
caches.

You need some level of cache maintenance here.

Thanks,

	M.
Shenming Lu March 11, 2021, 12:26 p.m. UTC | #2
On 2021/3/11 16:57, Marc Zyngier wrote:
> On Wed, 27 Jan 2021 12:13:34 +0000,
> Shenming Lu <lushenming@huawei.com> wrote:
>>
>> With GICv4.1 and the vPE unmapped, which indicates the invalidation
>> of any VPT caches associated with the vPE, we can get the VLPI state
>> by peeking at the VPT. So we add a function for this.
>>
>> Signed-off-by: Shenming Lu <lushenming@huawei.com>
>> ---
>>  arch/arm64/kvm/vgic/vgic-v4.c | 19 +++++++++++++++++++
>>  arch/arm64/kvm/vgic/vgic.h    |  1 +
>>  2 files changed, 20 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
>> index 66508b03094f..ac029ba3d337 100644
>> --- a/arch/arm64/kvm/vgic/vgic-v4.c
>> +++ b/arch/arm64/kvm/vgic/vgic-v4.c
>> @@ -203,6 +203,25 @@ void vgic_v4_configure_vsgis(struct kvm *kvm)
>>  	kvm_arm_resume_guest(kvm);
>>  }
>>  
>> +/*
>> + * Must be called with GICv4.1 and the vPE unmapped, which
>> + * indicates the invalidation of any VPT caches associated
>> + * with the vPE, thus we can get the VLPI state by peeking
>> + * at the VPT.
>> + */
>> +void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
>> +{
>> +	struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
>> +	int mask = BIT(irq->intid % BITS_PER_BYTE);
>> +	void *va;
>> +	u8 *ptr;
>> +
>> +	va = page_address(vpe->vpt_page);
>> +	ptr = va + irq->intid / BITS_PER_BYTE;
>> +
>> +	*val = !!(*ptr & mask);
> 
> What guarantees that you can actually read anything valid? Yes, the
> VPT caches are clean. But that doesn't make them coherent with CPU
> caches.
> 
> You need some level of cache maintenance here.

Yeah, and you have come up with some codes for this in v2:

diff --git a/drivers/irqchip/irq-gic-v3-its.c
b/drivers/irqchip/irq-gic-v3-its.c
index 7db602434ac5..2dbef127ca15 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -4552,6 +4552,10 @@ static void its_vpe_irq_domain_deactivate(struct
irq_domain *domain,

  		its_send_vmapp(its, vpe, false);
  	}
+
+	if (find_4_1_its() && !atomic_read(vpe->vmapp_count))
+		gic_flush_dcache_to_poc(page_address(vpe->vpt_page),
+					LPI_PENDBASE_SZ);
  }

  static const struct irq_domain_ops its_vpe_domain_ops = {

Could I add it to this series? :-)

Thanks,
Shenming

> 
> Thanks,
> 
> 	M.
>
Marc Zyngier March 12, 2021, 8:52 a.m. UTC | #3
On Thu, 11 Mar 2021 12:26:38 +0000,
Shenming Lu <lushenming@huawei.com> wrote:
> 
> On 2021/3/11 16:57, Marc Zyngier wrote:
> > On Wed, 27 Jan 2021 12:13:34 +0000,
> > Shenming Lu <lushenming@huawei.com> wrote:
> >>
> >> With GICv4.1 and the vPE unmapped, which indicates the invalidation
> >> of any VPT caches associated with the vPE, we can get the VLPI state
> >> by peeking at the VPT. So we add a function for this.
> >>
> >> Signed-off-by: Shenming Lu <lushenming@huawei.com>
> >> ---
> >>  arch/arm64/kvm/vgic/vgic-v4.c | 19 +++++++++++++++++++
> >>  arch/arm64/kvm/vgic/vgic.h    |  1 +
> >>  2 files changed, 20 insertions(+)
> >>
> >> diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
> >> index 66508b03094f..ac029ba3d337 100644
> >> --- a/arch/arm64/kvm/vgic/vgic-v4.c
> >> +++ b/arch/arm64/kvm/vgic/vgic-v4.c
> >> @@ -203,6 +203,25 @@ void vgic_v4_configure_vsgis(struct kvm *kvm)
> >>  	kvm_arm_resume_guest(kvm);
> >>  }
> >>  
> >> +/*
> >> + * Must be called with GICv4.1 and the vPE unmapped, which
> >> + * indicates the invalidation of any VPT caches associated
> >> + * with the vPE, thus we can get the VLPI state by peeking
> >> + * at the VPT.
> >> + */
> >> +void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
> >> +{
> >> +	struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
> >> +	int mask = BIT(irq->intid % BITS_PER_BYTE);
> >> +	void *va;
> >> +	u8 *ptr;
> >> +
> >> +	va = page_address(vpe->vpt_page);
> >> +	ptr = va + irq->intid / BITS_PER_BYTE;
> >> +
> >> +	*val = !!(*ptr & mask);
> > 
> > What guarantees that you can actually read anything valid? Yes, the
> > VPT caches are clean. But that doesn't make them coherent with CPU
> > caches.
> > 
> > You need some level of cache maintenance here.
> 
> Yeah, and you have come up with some codes for this in v2:
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c
> b/drivers/irqchip/irq-gic-v3-its.c
> index 7db602434ac5..2dbef127ca15 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -4552,6 +4552,10 @@ static void its_vpe_irq_domain_deactivate(struct
> irq_domain *domain,
> 
>   		its_send_vmapp(its, vpe, false);
>   	}
> +
> +	if (find_4_1_its() && !atomic_read(vpe->vmapp_count))
> +		gic_flush_dcache_to_poc(page_address(vpe->vpt_page),
> +					LPI_PENDBASE_SZ);
>   }
> 
>   static const struct irq_domain_ops its_vpe_domain_ops = {
> 
> Could I add it to this series? :-)

Yes, please.

	M.
diff mbox series

Patch

diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
index 66508b03094f..ac029ba3d337 100644
--- a/arch/arm64/kvm/vgic/vgic-v4.c
+++ b/arch/arm64/kvm/vgic/vgic-v4.c
@@ -203,6 +203,25 @@  void vgic_v4_configure_vsgis(struct kvm *kvm)
 	kvm_arm_resume_guest(kvm);
 }
 
+/*
+ * Must be called with GICv4.1 and the vPE unmapped, which
+ * indicates the invalidation of any VPT caches associated
+ * with the vPE, thus we can get the VLPI state by peeking
+ * at the VPT.
+ */
+void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
+{
+	struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
+	int mask = BIT(irq->intid % BITS_PER_BYTE);
+	void *va;
+	u8 *ptr;
+
+	va = page_address(vpe->vpt_page);
+	ptr = va + irq->intid / BITS_PER_BYTE;
+
+	*val = !!(*ptr & mask);
+}
+
 /**
  * vgic_v4_init - Initialize the GICv4 data structures
  * @kvm:	Pointer to the VM being initialized
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 64fcd7511110..d8cfd360838c 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -317,5 +317,6 @@  bool vgic_supports_direct_msis(struct kvm *kvm);
 int vgic_v4_init(struct kvm *kvm);
 void vgic_v4_teardown(struct kvm *kvm);
 void vgic_v4_configure_vsgis(struct kvm *kvm);
+void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
 
 #endif