On 1/29/20 6:57 PM, Julien Thierry wrote:
On 1/29/20 3:46 AM, Gavin Shan wrote:
On 1/28/20 7:29 PM, Julien Thierry wrote:

.../...


Julien, thanks for the explanation. The question we're not sure if NMI should
be injected on receiving HMP/QMP "nmi" command. It means it's not clear what
behavior we should have for this command on ARM. However, I have one more
unrelated question: "pseudo" NMI on ARM64 should be PPI? I mean SPI can't
be "pseudo" NMI.


I'm not sure I understand why you say "SPI can't be "pseudo" NMI". Currently both PPI and 
SPI are supported in the "pseudo" NMI scheme. Do you think that should not be the case? If so, can 
you elaborate?

Thanks,


Julien, NMI interrupt is connected to the system by request_nmi() where we have
a check as below. -EINVAL will be returned from request_nmi() on those 
interrupts
whose descriptors aren't marked with IRQ_NOAUTOEN. SPI falls into this category.
Please refer to below code snippet extracted from gic_irq_domain_map() for more
details.

kernel/irq/manage.c::request_nmi()

int request_nmi(unsigned int irq, irq_handler_t handler,
                unsigned long irqflags, const char *name, void *dev_id)
{
        :
        if (!desc || irq_settings_can_autoenable(desc) ||
            !irq_settings_can_request(desc) ||
            WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
            !irq_supports_nmi(desc))
                return -EINVAL;
        :
}


acpi_register_gsi
   irq_create_fwspec_mapping
      irq_domain_alloc_irqs
         __irq_domain_alloc_irqs
            irq_domain_alloc_irqs_hierarchy
               gic_irq_domain_alloc                  # irq_domain_ops::alloc
                  gic_irq_domain_map

drivers/irqchip/irq-gic-v3.c::gic_irq_domain_map()

static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
                              irq_hw_number_t hw)
{
        :
       switch (__get_intid_range(hw)) {
        case PPI_RANGE:
        case EPPI_RANGE:
                irq_set_percpu_devid(irq);
                irq_domain_set_info(d, irq, hw, chip, d->host_data,
                                    handle_percpu_devid_irq, NULL, NULL);
                irq_set_status_flags(irq, IRQ_NOAUTOEN);                      
<<<< this flag
                break;

        case SPI_RANGE:
        case ESPI_RANGE:
                irq_domain_set_info(d, irq, hw, chip, d->host_data,
                                    handle_fasteoi_irq, NULL, NULL);
                irq_set_probe(irq);
                irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
                break;
           :
        }
        :
}

Thanks,
Gavin


Reply via email to