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