2021-06-22 06:13:52

by Zhangshaokun

[permalink] [raw]
Subject: [PATCH v2] irqchip/irq-gic-v3-its: Add the checking of ITS version for KVM

From: wangwudi <[email protected]>

The version of GIC used by KVM is provided by gic_v3_kvm_info. The
KVM that supports GICv4 or GICv4.1 only checks GIC version. Actually,
the GIC and ITS need to work together. If we have multiple ITSs and
GIC supports v4, there are two cases:
1. None of the ITS supports GICv4, gic_v3_kvm_info.has_v4is false,
so the KVM will use GICv3;
2. At least one ITS supports GICv4, gic_v3_kvm_info has_v4 is true,
so the KVM can use GICv4;

It is the same as GICv4.1. For the first case that the KVM can use
GICv4, it seems non-sensible. If we do check the ITS version, it
will give correct version for KVM. So add the checking of ITS
version for KVM: If and only if both GIC & ITS support GICv4,
gic_kvm_info.has_v4 is true. If and only if both GIC & ITS support
GICv4.1, gic_kvm_info.has_v4_1 is true.

Cc: Thomas Gleixner <[email protected]>
Cc: Marc Zyngier <[email protected]>
Signed-off-by: Wudi Wang <[email protected]>
Signed-off-by: Shaokun Zhang <[email protected]>
---
ChangeLog:
v1-->v2:
1. Rebase to linux-next(Jun 21)
2. Rewrite the commit log

drivers/irqchip/irq-gic-common.h | 2 ++
drivers/irqchip/irq-gic-v3-its.c | 3 +++
drivers/irqchip/irq-gic-v3.c | 10 +++++-----
3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index 27e3d4ed4f32..7a360cb4a4c9 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -28,4 +28,6 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
void gic_enable_of_quirks(const struct device_node *np,
const struct gic_quirk *quirks, void *data);

+extern struct gic_kvm_info gic_v3_kvm_info;
+
#endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index ba39668c3e08..f65b13c4a08b 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -5415,6 +5415,9 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
has_v4_1 |= is_v4_1(its);
}

+ gic_v3_kvm_info.has_v4 = has_v4;
+ gic_v3_kvm_info.has_v4_1 = has_v4_1;
+
/* Don't bother with inconsistent systems */
if (WARN_ON(!has_v4_1 && rdists->has_rvpeid))
rdists->has_rvpeid = false;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e0f4debe64e1..d4fa44d4765e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -103,7 +103,7 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
static refcount_t *ppi_nmi_refs;

-static struct gic_kvm_info gic_v3_kvm_info __initdata;
+struct gic_kvm_info gic_v3_kvm_info __initdata;
static DEFINE_PER_CPU(bool, has_rss);

#define MPIDR_RS(mpidr) (((mpidr) & 0xF0UL) >> 4)
@@ -1884,8 +1884,8 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
if (!ret)
gic_v3_kvm_info.vcpu = r;

- gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
- gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
+ gic_v3_kvm_info.has_v4 &= gic_data.rdists.has_vlpis;
+ gic_v3_kvm_info.has_v4_1 &= gic_data.rdists.has_rvpeid;
vgic_set_kvm_info(&gic_v3_kvm_info);
}

@@ -2200,8 +2200,8 @@ static void __init gic_acpi_setup_kvm_info(void)
vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
}

- gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
- gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
+ gic_v3_kvm_info.has_v4 &= gic_data.rdists.has_vlpis;
+ gic_v3_kvm_info.has_v4_1 &= gic_data.rdists.has_rvpeid;
vgic_set_kvm_info(&gic_v3_kvm_info);
}

--
2.7.4


2021-07-19 05:41:11

by Zhangshaokun

[permalink] [raw]
Subject: Re: [PATCH v2] irqchip/irq-gic-v3-its: Add the checking of ITS version for KVM

Hi Marc,

A gentle ping.

Thanks,
Shaokun

On 2021/6/22 14:12, Shaokun Zhang wrote:
> From: wangwudi <[email protected]>
>
> The version of GIC used by KVM is provided by gic_v3_kvm_info. The
> KVM that supports GICv4 or GICv4.1 only checks GIC version. Actually,
> the GIC and ITS need to work together. If we have multiple ITSs and
> GIC supports v4, there are two cases:
> 1. None of the ITS supports GICv4, gic_v3_kvm_info.has_v4is false,
> so the KVM will use GICv3;
> 2. At least one ITS supports GICv4, gic_v3_kvm_info has_v4 is true,
> so the KVM can use GICv4;
>
> It is the same as GICv4.1. For the first case that the KVM can use
> GICv4, it seems non-sensible. If we do check the ITS version, it
> will give correct version for KVM. So add the checking of ITS
> version for KVM: If and only if both GIC & ITS support GICv4,
> gic_kvm_info.has_v4 is true. If and only if both GIC & ITS support
> GICv4.1, gic_kvm_info.has_v4_1 is true.
>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Marc Zyngier <[email protected]>
> Signed-off-by: Wudi Wang <[email protected]>
> Signed-off-by: Shaokun Zhang <[email protected]>
> ---
> ChangeLog:
> v1-->v2:
> 1. Rebase to linux-next(Jun 21)
> 2. Rewrite the commit log
>
> drivers/irqchip/irq-gic-common.h | 2 ++
> drivers/irqchip/irq-gic-v3-its.c | 3 +++
> drivers/irqchip/irq-gic-v3.c | 10 +++++-----
> 3 files changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
> index 27e3d4ed4f32..7a360cb4a4c9 100644
> --- a/drivers/irqchip/irq-gic-common.h
> +++ b/drivers/irqchip/irq-gic-common.h
> @@ -28,4 +28,6 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks,
> void gic_enable_of_quirks(const struct device_node *np,
> const struct gic_quirk *quirks, void *data);
>
> +extern struct gic_kvm_info gic_v3_kvm_info;
> +
> #endif /* _IRQ_GIC_COMMON_H */
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index ba39668c3e08..f65b13c4a08b 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -5415,6 +5415,9 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
> has_v4_1 |= is_v4_1(its);
> }
>
> + gic_v3_kvm_info.has_v4 = has_v4;
> + gic_v3_kvm_info.has_v4_1 = has_v4_1;
> +
> /* Don't bother with inconsistent systems */
> if (WARN_ON(!has_v4_1 && rdists->has_rvpeid))
> rdists->has_rvpeid = false;
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index e0f4debe64e1..d4fa44d4765e 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -103,7 +103,7 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
> /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> static refcount_t *ppi_nmi_refs;
>
> -static struct gic_kvm_info gic_v3_kvm_info __initdata;
> +struct gic_kvm_info gic_v3_kvm_info __initdata;
> static DEFINE_PER_CPU(bool, has_rss);
>
> #define MPIDR_RS(mpidr) (((mpidr) & 0xF0UL) >> 4)
> @@ -1884,8 +1884,8 @@ static void __init gic_of_setup_kvm_info(struct device_node *node)
> if (!ret)
> gic_v3_kvm_info.vcpu = r;
>
> - gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
> - gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
> + gic_v3_kvm_info.has_v4 &= gic_data.rdists.has_vlpis;
> + gic_v3_kvm_info.has_v4_1 &= gic_data.rdists.has_rvpeid;
> vgic_set_kvm_info(&gic_v3_kvm_info);
> }
>
> @@ -2200,8 +2200,8 @@ static void __init gic_acpi_setup_kvm_info(void)
> vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
> }
>
> - gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
> - gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
> + gic_v3_kvm_info.has_v4 &= gic_data.rdists.has_vlpis;
> + gic_v3_kvm_info.has_v4_1 &= gic_data.rdists.has_rvpeid;
> vgic_set_kvm_info(&gic_v3_kvm_info);
> }
>
>

2021-07-19 10:41:38

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH v2] irqchip/irq-gic-v3-its: Add the checking of ITS version for KVM

On Mon, 19 Jul 2021 06:39:50 +0100,
Shaokun Zhang <[email protected]> wrote:
>
> Hi Marc,
>
> A gentle ping.
>
> Thanks,
> Shaokun
>
> On 2021/6/22 14:12, Shaokun Zhang wrote:
> > From: wangwudi <[email protected]>
> >
> > The version of GIC used by KVM is provided by gic_v3_kvm_info. The
> > KVM that supports GICv4 or GICv4.1 only checks GIC version. Actually,
> > the GIC and ITS need to work together. If we have multiple ITSs and
> > GIC supports v4, there are two cases:
> > 1. None of the ITS supports GICv4, gic_v3_kvm_info.has_v4is false,
> > so the KVM will use GICv3;
> > 2. At least one ITS supports GICv4, gic_v3_kvm_info has_v4 is true,
> > so the KVM can use GICv4;
> >
> > It is the same as GICv4.1. For the first case that the KVM can use
> > GICv4, it seems non-sensible. If we do check the ITS version, it
> > will give correct version for KVM. So add the checking of ITS
> > version for KVM: If and only if both GIC & ITS support GICv4,
> > gic_kvm_info.has_v4 is true. If and only if both GIC & ITS support
> > GICv4.1, gic_kvm_info.has_v4_1 is true.

What you don't explain here is what goes wrong. If there is no ITS
that supports GICv4.1 while the CPU interfaces and the RDs are
advertising this support, so be it.

So please explain what goes wrong, and whether there is any platform
in the wild that is showing this problem.

Thanks,

M.

--
Without deviation from the norm, progress is not possible.

2021-07-20 02:07:20

by Zhangshaokun

[permalink] [raw]
Subject: Re: [PATCH v2] irqchip/irq-gic-v3-its: Add the checking of ITS version for KVM

Hi Marc,

On 2021/7/19 18:39, Marc Zyngier wrote:
> On Mon, 19 Jul 2021 06:39:50 +0100,
> Shaokun Zhang <[email protected]> wrote:
>>
>> Hi Marc,
>>
>> A gentle ping.
>>
>> Thanks,
>> Shaokun
>>
>> On 2021/6/22 14:12, Shaokun Zhang wrote:
>>> From: wangwudi <[email protected]>
>>>
>>> The version of GIC used by KVM is provided by gic_v3_kvm_info. The
>>> KVM that supports GICv4 or GICv4.1 only checks GIC version. Actually,
>>> the GIC and ITS need to work together. If we have multiple ITSs and
>>> GIC supports v4, there are two cases:
>>> 1. None of the ITS supports GICv4, gic_v3_kvm_info.has_v4is false,
>>> so the KVM will use GICv3;
>>> 2. At least one ITS supports GICv4, gic_v3_kvm_info has_v4 is true,
>>> so the KVM can use GICv4;
>>>
>>> It is the same as GICv4.1. For the first case that the KVM can use
>>> GICv4, it seems non-sensible. If we do check the ITS version, it
>>> will give correct version for KVM. So add the checking of ITS
>>> version for KVM: If and only if both GIC & ITS support GICv4,
>>> gic_kvm_info.has_v4 is true. If and only if both GIC & ITS support
>>> GICv4.1, gic_kvm_info.has_v4_1 is true.
>
> What you don't explain here is what goes wrong. If there is no ITS

That's not completely wrong, we only want to make it more reasonable as
we said that in commit log.

> that supports GICv4.1 while the CPU interfaces and the RDs are
> advertising this support, so be it.
>
> So please explain what goes wrong, and whether there is any platform
> in the wild that is showing this problem.

To be honest, I'm not sure that some platform has this issue. It is
detected by code reading.

Thanks,
Shaokun

>
> Thanks,
>
> M.
>