Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/gic: Split vGIC probing information from the GIC code

The vGIC advertising code is unsurprisingly very much tied to
the GIC implementations. However, we are about to extend the
support to lesser implementations.

Let's dissociate the vgic registration from the GIC code and
move it into KVM, where it makes a bit more sense. This also
allows us to mark the gic_kvm_info structures as __initdata.

Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>

+63 -48
+15 -3
arch/arm64/kvm/vgic/vgic-init.c
··· 482 482 return IRQ_HANDLED; 483 483 } 484 484 485 + static struct gic_kvm_info *gic_kvm_info; 486 + 487 + void __init vgic_set_kvm_info(const struct gic_kvm_info *info) 488 + { 489 + BUG_ON(gic_kvm_info != NULL); 490 + gic_kvm_info = kmalloc(sizeof(*info), GFP_KERNEL); 491 + if (gic_kvm_info) 492 + *gic_kvm_info = *info; 493 + } 494 + 485 495 /** 486 496 * kvm_vgic_init_cpu_hardware - initialize the GIC VE hardware 487 497 * ··· 519 509 */ 520 510 int kvm_vgic_hyp_init(void) 521 511 { 522 - const struct gic_kvm_info *gic_kvm_info; 523 512 int ret; 524 513 525 - gic_kvm_info = gic_get_kvm_info(); 526 514 if (!gic_kvm_info) 527 515 return -ENODEV; 528 516 ··· 544 536 ret = -ENODEV; 545 537 } 546 538 539 + kvm_vgic_global_state.maint_irq = gic_kvm_info->maint_irq; 540 + 541 + kfree(gic_kvm_info); 542 + gic_kvm_info = NULL; 543 + 547 544 if (ret) 548 545 return ret; 549 546 550 - kvm_vgic_global_state.maint_irq = gic_kvm_info->maint_irq; 551 547 ret = request_percpu_irq(kvm_vgic_global_state.maint_irq, 552 548 vgic_maintenance_handler, 553 549 "vgic", kvm_get_running_vcpus());
-13
drivers/irqchip/irq-gic-common.c
··· 12 12 13 13 static DEFINE_RAW_SPINLOCK(irq_controller_lock); 14 14 15 - static const struct gic_kvm_info *gic_kvm_info; 16 - 17 - const struct gic_kvm_info *gic_get_kvm_info(void) 18 - { 19 - return gic_kvm_info; 20 - } 21 - 22 - void gic_set_kvm_info(const struct gic_kvm_info *info) 23 - { 24 - BUG_ON(gic_kvm_info != NULL); 25 - gic_kvm_info = info; 26 - } 27 - 28 15 void gic_enable_of_quirks(const struct device_node *np, 29 16 const struct gic_quirk *quirks, void *data) 30 17 {
-2
drivers/irqchip/irq-gic-common.h
··· 28 28 void gic_enable_of_quirks(const struct device_node *np, 29 29 const struct gic_quirk *quirks, void *data); 30 30 31 - void gic_set_kvm_info(const struct gic_kvm_info *info); 32 - 33 31 #endif /* _IRQ_GIC_COMMON_H */
+3 -3
drivers/irqchip/irq-gic-v3.c
··· 103 103 /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */ 104 104 static refcount_t *ppi_nmi_refs; 105 105 106 - static struct gic_kvm_info gic_v3_kvm_info; 106 + static struct gic_kvm_info gic_v3_kvm_info __initdata; 107 107 static DEFINE_PER_CPU(bool, has_rss); 108 108 109 109 #define MPIDR_RS(mpidr) (((mpidr) & 0xF0UL) >> 4) ··· 1852 1852 1853 1853 gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis; 1854 1854 gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid; 1855 - gic_set_kvm_info(&gic_v3_kvm_info); 1855 + vgic_set_kvm_info(&gic_v3_kvm_info); 1856 1856 } 1857 1857 1858 1858 static int __init gic_of_init(struct device_node *node, struct device_node *parent) ··· 2168 2168 2169 2169 gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis; 2170 2170 gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid; 2171 - gic_set_kvm_info(&gic_v3_kvm_info); 2171 + vgic_set_kvm_info(&gic_v3_kvm_info); 2172 2172 } 2173 2173 2174 2174 static int __init
+3 -3
drivers/irqchip/irq-gic.c
··· 119 119 120 120 static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; 121 121 122 - static struct gic_kvm_info gic_v2_kvm_info; 122 + static struct gic_kvm_info gic_v2_kvm_info __initdata; 123 123 124 124 static DEFINE_PER_CPU(u32, sgi_intid); 125 125 ··· 1451 1451 return; 1452 1452 1453 1453 if (static_branch_likely(&supports_deactivate_key)) 1454 - gic_set_kvm_info(&gic_v2_kvm_info); 1454 + vgic_set_kvm_info(&gic_v2_kvm_info); 1455 1455 } 1456 1456 1457 1457 int __init ··· 1618 1618 1619 1619 gic_v2_kvm_info.maint_irq = irq; 1620 1620 1621 - gic_set_kvm_info(&gic_v2_kvm_info); 1621 + vgic_set_kvm_info(&gic_v2_kvm_info); 1622 1622 } 1623 1623 1624 1624 static int __init gic_v2_acpi_init(union acpi_subtable_headers *header,
+1 -24
include/linux/irqchip/arm-gic-common.h
··· 7 7 #ifndef __LINUX_IRQCHIP_ARM_GIC_COMMON_H 8 8 #define __LINUX_IRQCHIP_ARM_GIC_COMMON_H 9 9 10 - #include <linux/types.h> 11 - #include <linux/ioport.h> 10 + #include <linux/irqchip/arm-vgic-info.h> 12 11 13 12 #define GICD_INT_DEF_PRI 0xa0 14 13 #define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\ 15 14 (GICD_INT_DEF_PRI << 16) |\ 16 15 (GICD_INT_DEF_PRI << 8) |\ 17 16 GICD_INT_DEF_PRI) 18 - 19 - enum gic_type { 20 - GIC_V2, 21 - GIC_V3, 22 - }; 23 - 24 - struct gic_kvm_info { 25 - /* GIC type */ 26 - enum gic_type type; 27 - /* Virtual CPU interface */ 28 - struct resource vcpu; 29 - /* Interrupt number */ 30 - unsigned int maint_irq; 31 - /* Virtual control interface */ 32 - struct resource vctrl; 33 - /* vlpi support */ 34 - bool has_v4; 35 - /* rvpeid support */ 36 - bool has_v4_1; 37 - }; 38 - 39 - const struct gic_kvm_info *gic_get_kvm_info(void); 40 17 41 18 struct irq_domain; 42 19 struct fwnode_handle;
+41
include/linux/irqchip/arm-vgic-info.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * include/linux/irqchip/arm-vgic-info.h 4 + * 5 + * Copyright (C) 2016 ARM Limited, All Rights Reserved. 6 + */ 7 + #ifndef __LINUX_IRQCHIP_ARM_VGIC_INFO_H 8 + #define __LINUX_IRQCHIP_ARM_VGIC_INFO_H 9 + 10 + #include <linux/types.h> 11 + #include <linux/ioport.h> 12 + 13 + enum gic_type { 14 + /* Full GICv2 */ 15 + GIC_V2, 16 + /* Full GICv3, optionally with v2 compat */ 17 + GIC_V3, 18 + }; 19 + 20 + struct gic_kvm_info { 21 + /* GIC type */ 22 + enum gic_type type; 23 + /* Virtual CPU interface */ 24 + struct resource vcpu; 25 + /* Interrupt number */ 26 + unsigned int maint_irq; 27 + /* Virtual control interface */ 28 + struct resource vctrl; 29 + /* vlpi support */ 30 + bool has_v4; 31 + /* rvpeid support */ 32 + bool has_v4_1; 33 + }; 34 + 35 + #ifdef CONFIG_KVM 36 + void vgic_set_kvm_info(const struct gic_kvm_info *info); 37 + #else 38 + static inline void vgic_set_kvm_info(const struct gic_kvm_info *info) {} 39 + #endif 40 + 41 + #endif