aplic
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static bool aplic_read_pending(struct aplic *aplic, u32 irq)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static bool aplic_read_enabled(struct aplic *aplic, u32 irq)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static bool aplic_read_input(struct aplic *aplic, u32 irq)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
struct aplic *aplic = kvm->arch.aia.aplic_state;
if (!(aplic->domaincfg & APLIC_DOMAINCFG_IE))
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
struct aplic *aplic = kvm->arch.aia.aplic_state;
if (!aplic || !source || (aplic->nr_irqs <= source))
irqd = &aplic->irqs[array_index_nospec(source, aplic->nr_irqs)];
ie = (aplic->domaincfg & APLIC_DOMAINCFG_IE) ? true : false;
static u32 aplic_read_input_word(struct aplic *aplic, u32 word)
ret |= aplic_read_input(aplic, word * 32 + i) ? BIT(i) : 0;
static u32 aplic_read_pending_word(struct aplic *aplic, u32 word)
ret |= aplic_read_pending(aplic, word * 32 + i) ? BIT(i) : 0;
static void aplic_write_pending_word(struct aplic *aplic, u32 word,
aplic_write_pending(aplic, word * 32 + i, pending);
static u32 aplic_read_enabled_word(struct aplic *aplic, u32 word)
ret |= aplic_read_enabled(aplic, word * 32 + i) ? BIT(i) : 0;
static void aplic_write_enabled_word(struct aplic *aplic, u32 word,
aplic_write_enabled(aplic, word * 32 + i, enabled);
struct aplic *aplic = kvm->arch.aia.aplic_state;
aplic->domaincfg | APLIC_DOMAINCFG_DM;
(off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) {
*val32 = aplic_read_sourcecfg(aplic, i);
(off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) {
*val32 = aplic_read_pending_word(aplic, i);
static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq)
(off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) {
*val32 = aplic_read_input_word(aplic, i);
(off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) {
*val32 = aplic_read_enabled_word(aplic, i);
(off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) {
*val32 = aplic->genmsi;
(off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) {
*val32 = aplic_read_target(aplic, i);
struct aplic *aplic = kvm->arch.aia.aplic_state;
aplic->domaincfg = val32 & APLIC_DOMAINCFG_IE;
(off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) {
aplic_write_sourcecfg(aplic, i, val32);
if (!irq || aplic->nr_irqs <= irq)
(off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) {
aplic_write_pending_word(aplic, i, val32, true);
aplic_write_pending(aplic, val32, true);
(off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) {
aplic_write_pending_word(aplic, i, val32, false);
aplic_write_pending(aplic, val32, false);
(off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) {
aplic_write_enabled_word(aplic, i, val32, true);
aplic_write_enabled(aplic, val32, true);
(off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) {
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
aplic_write_enabled_word(aplic, i, val32, false);
aplic_write_enabled(aplic, val32, false);
aplic_write_pending(aplic, val32, true);
aplic_write_pending(aplic, __swab32(val32), true);
aplic->genmsi = val32 & ~(APLIC_TARGET_GUEST_IDX_MASK <<
(off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) {
aplic_write_target(aplic, i, val32);
aplic_update_irq_range(kvm, 1, aplic->nr_irqs - 1);
struct aplic *aplic;
static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val)
aplic = kzalloc_obj(*aplic);
if (!aplic)
kvm->arch.aia.aplic_state = aplic;
aplic->nr_irqs = kvm->arch.aia.nr_sources + 1;
aplic->nr_words = DIV_ROUND_UP(aplic->nr_irqs, 32);
aplic->irqs = kzalloc_objs(*aplic->irqs, aplic->nr_irqs);
if (!aplic->irqs) {
for (i = 0; i < aplic->nr_irqs; i++)
raw_spin_lock_init(&aplic->irqs[i].lock);
kvm_iodevice_init(&aplic->iodev, &aplic_iodoev_ops);
&aplic->iodev);
ret = kvm_riscv_setup_default_irq_routing(kvm, aplic->nr_irqs);
kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev);
kfree(aplic->irqs);
kfree(aplic);
if (!irq || aplic->nr_irqs <= irq)
struct aplic *aplic = kvm->arch.aia.aplic_state;
if (!aplic)
kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev);
kfree(aplic->irqs);
kfree(aplic);
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static u32 aplic_read_target(struct aplic *aplic, u32 irq)
if (!irq || aplic->nr_irqs <= irq)
irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)];
static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val)
if (!irq || aplic->nr_irqs <= irq)
struct acpi_madt_aplic *aplic = (struct acpi_madt_aplic *)header;
return riscv_acpi_register_ext_intc(aplic->gsi_base, aplic->num_sources, aplic->num_idcs,
aplic->id, ACPI_RISCV_IRQCHIP_APLIC);