[PATCH v11 18/26] virt: gunyah: Translate gh_rm_hyp_resource into gunyah_resource
Elliot Berman
quic_eberman at quicinc.com
Mon Apr 17 17:25:57 PDT 2023
On 3/31/2023 7:26 AM, Alex Elder wrote:
> On 3/3/23 7:06 PM, Elliot Berman wrote:
>> When booting a Gunyah virtual machine, the host VM may gain capabilities
>> to interact with resources for the guest virtual machine. Examples of
>> such resources are vCPUs or message queues. To use those resources, we
>> need to translate the RM response into a gunyah_resource structure which
>> are useful to Linux drivers. Presently, Linux drivers need only to know
>> the type of resource, the capability ID, and an interrupt.
>>
>> On ARM64 systems, the interrupt reported by Gunyah is the GIC interrupt
>> ID number and always a SPI.
>>
>> Signed-off-by: Elliot Berman <quic_eberman at quicinc.com>
>
> Several comments here, nothing major. -Alex
>
>> ---
>> arch/arm64/include/asm/gunyah.h | 23 +++++
>> drivers/virt/gunyah/rsc_mgr.c | 163 +++++++++++++++++++++++++++++++-
>> include/linux/gunyah.h | 4 +
>> include/linux/gunyah_rsc_mgr.h | 3 +
>> 4 files changed, 192 insertions(+), 1 deletion(-)
>> create mode 100644 arch/arm64/include/asm/gunyah.h
>>
>> diff --git a/arch/arm64/include/asm/gunyah.h
>> b/arch/arm64/include/asm/gunyah.h
>> new file mode 100644
>> index 000000000000..64cfb964efee
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/gunyah.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + */
>> +#ifndef __ASM_GUNYAH_H_
>> +#define __ASM_GUNYAH_H_
>
> Maybe just one _ at the beginning and none at the end?
> Follow the same convention across all your header files.
> (Maybe you're looking at other files in the same directory
> as this one, but that's not consistent.)
>
>> +
>> +#include <linux/irq.h>
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +static inline int arch_gh_fill_irq_fwspec_params(u32 virq, struct
>> irq_fwspec *fwspec)
>> +{
>> + if (virq < 32 || virq > 1019)
>> + return -EINVAL;
>
> What is special about VIRQs greater than 1019 (minus 32)?
>
> It's probably documented somewhere but it's worth adding a
> comment here to explain the check.
>
> You would know better than I, but could/should the caller
> be responsible for this check? (Not a big deal.)
>
I think definitely not the caller should be responsible for this check.
On arm systems, the IRQ # that is returned is the hwirq # for the GIC.
Presently, Gunyah only gives us SPI interrupts [32,1019] so I've written
a translation to a SPI fwspec.
>> +
>> + fwspec->param_count = 3;
>> + fwspec->param[0] = GIC_SPI;
>> + fwspec->param[1] = virq - 32;
>
> And why is 32 subtracted?
>
GIC driver expects the SPI #, not the hwirq #.
>> + fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
>> + return 0;
>> +}
>> +
>> +#endif
>> diff --git a/drivers/virt/gunyah/rsc_mgr.c
>> b/drivers/virt/gunyah/rsc_mgr.c
>> index d7ce692d0067..383be5ac0f44 100644
>> --- a/drivers/virt/gunyah/rsc_mgr.c
>> +++ b/drivers/virt/gunyah/rsc_mgr.c
>> @@ -17,6 +17,8 @@
>> #include <linux/platform_device.h>
>> #include <linux/miscdevice.h>
>> +#include <asm/gunyah.h>
>> +
>> #include "rsc_mgr.h"
>> #include "vm_mgr.h"
>> @@ -132,6 +134,7 @@ struct gh_rm_connection {
>> * @send_lock: synchronization to allow only one request to be sent
>> at a time
>> * @nh: notifier chain for clients interested in RM notification
>> messages
>> * @miscdev: /dev/gunyah
>> + * @irq_domain: Domain to translate Gunyah hwirqs to Linux irqs
>> */
>> struct gh_rm {
>> struct device *dev;
>> @@ -150,6 +153,7 @@ struct gh_rm {
>> struct blocking_notifier_head nh;
>> struct miscdevice miscdev;
>> + struct irq_domain *irq_domain;
>> };
>> /**
>> @@ -190,6 +194,134 @@ static inline int gh_rm_remap_error(enum
>> gh_rm_error rm_error)
>> }
>> }
>> +struct gh_irq_chip_data {
>> + u32 gh_virq;
>> +};
>> +
>> +static struct irq_chip gh_rm_irq_chip = {
>> + .name = "Gunyah",
>> + .irq_enable = irq_chip_enable_parent,
>> + .irq_disable = irq_chip_disable_parent,
>> + .irq_ack = irq_chip_ack_parent,
>> + .irq_mask = irq_chip_mask_parent,
>> + .irq_mask_ack = irq_chip_mask_ack_parent,
>> + .irq_unmask = irq_chip_unmask_parent,
>> + .irq_eoi = irq_chip_eoi_parent,
>> + .irq_set_affinity = irq_chip_set_affinity_parent,
>> + .irq_set_type = irq_chip_set_type_parent,
>> + .irq_set_wake = irq_chip_set_wake_parent,
>> + .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent,
>> + .irq_retrigger = irq_chip_retrigger_hierarchy,
>> + .irq_get_irqchip_state = irq_chip_get_parent_state,
>> + .irq_set_irqchip_state = irq_chip_set_parent_state,
>> + .flags = IRQCHIP_SET_TYPE_MASKED |
>> + IRQCHIP_SKIP_SET_WAKE |
>> + IRQCHIP_MASK_ON_SUSPEND,
>> +};
>> +
>> +static int gh_rm_irq_domain_alloc(struct irq_domain *d, unsigned int
>> virq, unsigned int nr_irqs,
>> + void *arg)
>> +{
>> + struct gh_irq_chip_data *chip_data, *spec = arg;
>> + struct irq_fwspec parent_fwspec;
>> + struct gh_rm *rm = d->host_data;
>> + u32 gh_virq = spec->gh_virq;
>> + int ret;
>> +
>> + if (nr_irqs != 1 || gh_virq == U32_MAX)
>
> Does U32_MAX have special meaning? Why are you checking for it?
> Whatever it is, you should explain why this is invalid here.
>
This was holdover from deprecated Gunyah code. Since there are new
features/version checks it's not possible for Linux to encounter these
values. I've dropped it in v12.
Thanks,
Elliot
More information about the linux-arm-kernel
mailing list