aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 14:27:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-19 14:27:09 -0400
commit7beaa24ba49717419e24d1f6321e8b3c265a719c (patch)
treea5c5433d3c7bfc4c23e67174463ccf519c8406f0 /drivers/irqchip/irq-gic.c
parent07b75260ebc2c789724c594d7eaf0194fa47b3be (diff)
parent9842df62004f366b9fed2423e24df10542ee0dc5 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Paolo Bonzini: "Small release overall. x86: - miscellaneous fixes - AVIC support (local APIC virtualization, AMD version) s390: - polling for interrupts after a VCPU goes to halted state is now enabled for s390 - use hardware provided information about facility bits that do not need any hypervisor activity, and other fixes for cpu models and facilities - improve perf output - floating interrupt controller improvements. MIPS: - miscellaneous fixes PPC: - bugfixes only ARM: - 16K page size support - generic firmware probing layer for timer and GIC Christoffer Dall (KVM-ARM maintainer) says: "There are a few changes in this pull request touching things outside KVM, but they should all carry the necessary acks and it made the merge process much easier to do it this way." though actually the irqchip maintainers' acks didn't make it into the patches. Marc Zyngier, who is both irqchip and KVM-ARM maintainer, later acked at http://mid.gmane.org/573351D1.4060303@arm.com ('more formally and for documentation purposes')" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (82 commits) KVM: MTRR: remove MSR 0x2f8 KVM: x86: make hwapic_isr_update and hwapic_irr_update look the same svm: Manage vcpu load/unload when enable AVIC svm: Do not intercept CR8 when enable AVIC svm: Do not expose x2APIC when enable AVIC KVM: x86: Introducing kvm_x86_ops.apicv_post_state_restore svm: Add VMEXIT handlers for AVIC svm: Add interrupt injection via AVIC KVM: x86: Detect and Initialize AVIC support svm: Introduce new AVIC VMCB registers KVM: split kvm_vcpu_wake_up from kvm_vcpu_kick KVM: x86: Introducing kvm_x86_ops VCPU blocking/unblocking hooks KVM: x86: Introducing kvm_x86_ops VM init/destroy hooks KVM: x86: Rename kvm_apic_get_reg to kvm_lapic_get_reg KVM: x86: Misc LAPIC changes to expose helper functions KVM: shrink halt polling even more for invalid wakeups KVM: s390: set halt polling to 80 microseconds KVM: halt_polling: provide a way to qualify wakeups during poll KVM: PPC: Book3S HV: Re-enable XICS fast path for irqfd-generated interrupts kvm: Conditionally register IRQ bypass consumer ...
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c89
1 files changed, 83 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 1de20e14a721..b4e647179346 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -105,6 +105,8 @@ static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
105 105
106static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; 106static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly;
107 107
108static struct gic_kvm_info gic_v2_kvm_info;
109
108#ifdef CONFIG_GIC_NON_BANKED 110#ifdef CONFIG_GIC_NON_BANKED
109static void __iomem *gic_get_percpu_base(union gic_base *base) 111static void __iomem *gic_get_percpu_base(union gic_base *base)
110{ 112{
@@ -1248,7 +1250,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
1248 return true; 1250 return true;
1249} 1251}
1250 1252
1251static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node) 1253static int __init gic_of_setup(struct gic_chip_data *gic, struct device_node *node)
1252{ 1254{
1253 if (!gic || !node) 1255 if (!gic || !node)
1254 return -EINVAL; 1256 return -EINVAL;
@@ -1272,6 +1274,29 @@ error:
1272 return -ENOMEM; 1274 return -ENOMEM;
1273} 1275}
1274 1276
1277static void __init gic_of_setup_kvm_info(struct device_node *node)
1278{
1279 int ret;
1280 struct resource *vctrl_res = &gic_v2_kvm_info.vctrl;
1281 struct resource *vcpu_res = &gic_v2_kvm_info.vcpu;
1282
1283 gic_v2_kvm_info.type = GIC_V2;
1284
1285 gic_v2_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
1286 if (!gic_v2_kvm_info.maint_irq)
1287 return;
1288
1289 ret = of_address_to_resource(node, 2, vctrl_res);
1290 if (ret)
1291 return;
1292
1293 ret = of_address_to_resource(node, 3, vcpu_res);
1294 if (ret)
1295 return;
1296
1297 gic_set_kvm_info(&gic_v2_kvm_info);
1298}
1299
1275int __init 1300int __init
1276gic_of_init(struct device_node *node, struct device_node *parent) 1301gic_of_init(struct device_node *node, struct device_node *parent)
1277{ 1302{
@@ -1303,8 +1328,10 @@ gic_of_init(struct device_node *node, struct device_node *parent)
1303 return ret; 1328 return ret;
1304 } 1329 }
1305 1330
1306 if (!gic_cnt) 1331 if (!gic_cnt) {
1307 gic_init_physaddr(node); 1332 gic_init_physaddr(node);
1333 gic_of_setup_kvm_info(node);
1334 }
1308 1335
1309 if (parent) { 1336 if (parent) {
1310 irq = irq_of_parse_and_map(node, 0); 1337 irq = irq_of_parse_and_map(node, 0);
@@ -1330,7 +1357,14 @@ IRQCHIP_DECLARE(pl390, "arm,pl390", gic_of_init);
1330#endif 1357#endif
1331 1358
1332#ifdef CONFIG_ACPI 1359#ifdef CONFIG_ACPI
1333static phys_addr_t cpu_phy_base __initdata; 1360static struct
1361{
1362 phys_addr_t cpu_phys_base;
1363 u32 maint_irq;
1364 int maint_irq_mode;
1365 phys_addr_t vctrl_base;
1366 phys_addr_t vcpu_base;
1367} acpi_data __initdata;
1334 1368
1335static int __init 1369static int __init
1336gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header, 1370gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
@@ -1350,10 +1384,16 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
1350 * All CPU interface addresses have to be the same. 1384 * All CPU interface addresses have to be the same.
1351 */ 1385 */
1352 gic_cpu_base = processor->base_address; 1386 gic_cpu_base = processor->base_address;
1353 if (cpu_base_assigned && gic_cpu_base != cpu_phy_base) 1387 if (cpu_base_assigned && gic_cpu_base != acpi_data.cpu_phys_base)
1354 return -EINVAL; 1388 return -EINVAL;
1355 1389
1356 cpu_phy_base = gic_cpu_base; 1390 acpi_data.cpu_phys_base = gic_cpu_base;
1391 acpi_data.maint_irq = processor->vgic_interrupt;
1392 acpi_data.maint_irq_mode = (processor->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
1393 ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
1394 acpi_data.vctrl_base = processor->gich_base_address;
1395 acpi_data.vcpu_base = processor->gicv_base_address;
1396
1357 cpu_base_assigned = 1; 1397 cpu_base_assigned = 1;
1358 return 0; 1398 return 0;
1359} 1399}
@@ -1384,6 +1424,41 @@ static bool __init gic_validate_dist(struct acpi_subtable_header *header,
1384 1424
1385#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K) 1425#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K)
1386#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K) 1426#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K)
1427#define ACPI_GICV2_VCTRL_MEM_SIZE (SZ_4K)
1428#define ACPI_GICV2_VCPU_MEM_SIZE (SZ_8K)
1429
1430static void __init gic_acpi_setup_kvm_info(void)
1431{
1432 int irq;
1433 struct resource *vctrl_res = &gic_v2_kvm_info.vctrl;
1434 struct resource *vcpu_res = &gic_v2_kvm_info.vcpu;
1435
1436 gic_v2_kvm_info.type = GIC_V2;
1437
1438 if (!acpi_data.vctrl_base)
1439 return;
1440
1441 vctrl_res->flags = IORESOURCE_MEM;
1442 vctrl_res->start = acpi_data.vctrl_base;
1443 vctrl_res->end = vctrl_res->start + ACPI_GICV2_VCTRL_MEM_SIZE - 1;
1444
1445 if (!acpi_data.vcpu_base)
1446 return;
1447
1448 vcpu_res->flags = IORESOURCE_MEM;
1449 vcpu_res->start = acpi_data.vcpu_base;
1450 vcpu_res->end = vcpu_res->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
1451
1452 irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
1453 acpi_data.maint_irq_mode,
1454 ACPI_ACTIVE_HIGH);
1455 if (irq <= 0)
1456 return;
1457
1458 gic_v2_kvm_info.maint_irq = irq;
1459
1460 gic_set_kvm_info(&gic_v2_kvm_info);
1461}
1387 1462
1388static int __init gic_v2_acpi_init(struct acpi_subtable_header *header, 1463static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1389 const unsigned long end) 1464 const unsigned long end)
@@ -1401,7 +1476,7 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1401 return -EINVAL; 1476 return -EINVAL;
1402 } 1477 }
1403 1478
1404 gic->raw_cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE); 1479 gic->raw_cpu_base = ioremap(acpi_data.cpu_phys_base, ACPI_GIC_CPU_IF_MEM_SIZE);
1405 if (!gic->raw_cpu_base) { 1480 if (!gic->raw_cpu_base) {
1406 pr_err("Unable to map GICC registers\n"); 1481 pr_err("Unable to map GICC registers\n");
1407 return -ENOMEM; 1482 return -ENOMEM;
@@ -1447,6 +1522,8 @@ static int __init gic_v2_acpi_init(struct acpi_subtable_header *header,
1447 if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) 1522 if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
1448 gicv2m_init(NULL, gic_data[0].domain); 1523 gicv2m_init(NULL, gic_data[0].domain);
1449 1524
1525 gic_acpi_setup_kvm_info();
1526
1450 return 0; 1527 return 0;
1451} 1528}
1452IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 1529IRQCHIP_ACPI_DECLARE(gic_v2, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,