This is the boot message of the virtual machine related to IRQ.
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GICv3: 224 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: no VLPI support, no direct LPI support
[    0.000000] GICv3: CPU0: found redistributor 0 region
0:0x00000000080a0000
Somehow the NR_IRQS is 64.
So I tried using SPI 15 which was not assigned. (32 internal IRQs + 15 < 64)
and now request_irq returns 0.
So this irq_desc problem was solved(?) for now. (I don't know why this is so
small when CONFIG_SPARSE_IRQS=y).
And still the handler is not called even when I set qemu_set_irq.
                _____________________________________________
                From: Chan Kim <c...@etri.re.kr> 
                Sent: Wednesday, April 6, 2022 10:46 AM
                To: 'qemu-discuss' <qemu-discuss@nongnu.org>;
kernelnewb...@kernelnewbies.org
                Subject: irq_desc not found for my interrupt number during
request_irq (radix tree of irq_desc has only 64 entries..)
                
                
                Hello all, 

                I'm doing an linux driver and application test on a qemu
arm64 virtual machine.
                My virtual machine is slightly modified version of arm
'virt' machine and it has our device model included.
                When I do request_irq for INTID 208 (SPI 176) in linux on my
arm64 virtual machine, it returns -EINVAL.
                I poked into that function and found the desc is returning
NULL in function request_threaded_irq.

                        int request_threaded_irq(unsigned int irq,
irq_handler_t handler,
                                     irq_handler_t thread_fn, unsigned long
irqflags,
                                     const char *devname, void *dev_id)
                        {
                            struct irqaction *action;
                            struct irq_desc *desc;
                            int retval;
                        ...
                        desc = irq_to_desc(irq);
                            if (!desc) 
                                return -EINVAL;
                        ...
                        }
                
                and irq_to_desc is supposed to return an irq_desc from the
irq_radix_tree as shown below.

                        struct irq_desc *irq_to_desc(unsigned int irq)
                        {
                            return radix_tree_lookup(&irq_desc_tree, irq);
                        }

                        void *radix_tree_lookup(const struct radix_tree_root
*root, unsigned long index)
                        {
                            return __radix_tree_lookup(root, index, NULL,
NULL);
                        }

                        void *__radix_tree_lookup(const struct
radix_tree_root *root,
                                      unsigned long index, struct
radix_tree_node **nodep,
                                      void __rcu ***slotp)
                        {
                            struct radix_tree_node *node, *parent;
                            unsigned long maxindex;
                            void __rcu **slot;

                         restart:
                            parent = NULL;
                            slot = (void __rcu **)&root->xa_head;
                            radix_tree_load_root(root, &node, &maxindex);
                            if (index > maxindex)
                                return NULL;
                        ...
                        }

                and I found my request index is 208 but the maxindex of the
radix tree is 63. 
                So it looks like the radix tree of irq_desc has been set to
have maximum 64 irq_descs. 
                Where and how can I set this radix tree size?
                I looked at qemu's hw/arm/ab21q-build-acpi.c for MADT or
DSDT table parts but couldn't find what to add.
                I have my devices address range and irq added in the DSDT
and MADT.

                static void
                build_dsdt(GArray *table_data, BIOSLinker *linker,
Ab21qMachineState *vms)
                {
                ...
                acpi_dsdt_add_axpu(scope, &memmap[AB21Q_AXPU],
                                       (irqmap[AB21Q_AXPU] + ARM_SPI_BASE));
                ...
                }
                static void acpi_dsdt_add_axpu(Aml *scope, const MemMapEntry
*axpu_memmap,
                                                           uint32_t irq)
                {
                    Aml *dev = aml_device("AXPU");
                    aml_append(dev, aml_name_decl("_HID",
aml_string("AXPU0011")));
                    aml_append(dev, aml_name_decl("_UID", aml_int(0)));

                    Aml *crs = aml_resource_template();
                    aml_append(crs, aml_memory32_fixed(axpu_memmap->base,
                                                       axpu_memmap->size,
AML_READ_WRITE));
                    aml_append(crs,
                               aml_interrupt(AML_CONSUMER, AML_LEVEL,
AML_ACTIVE_HIGH,
                                             AML_EXCLUSIVE, &irq, 1));
                    aml_append(dev, aml_name_decl("_CRS", crs));

                    aml_append(scope, dev);
                }

                I'm not sure if I can just use _HID value as "AXPU0011". 
                If you see anything wrong and have a suggestion, please tell
me.

                Thank you!
                Chan Kim
                

Reply via email to