diff options
| author | Christoffer Dall <christoffer.dall@linaro.org> | 2014-09-18 21:15:32 -0400 |
|---|---|---|
| committer | Christoffer Dall <christoffer.dall@linaro.org> | 2014-09-18 21:15:32 -0400 |
| commit | a875dafcf9b6b266c855e1f9b0aa060ef585d38a (patch) | |
| tree | 1903cb0a39ac1cade1940ccb559591cddf3660a0 /virt | |
| parent | 0ba09511ddc3ff0b462f37b4fe4b9c4dccc054ec (diff) | |
| parent | f51770ed465e6eb41da7fa16fd92eb67069600cf (diff) | |
Merge remote-tracking branch 'kvm/next' into queue
Conflicts:
arch/arm64/include/asm/kvm_host.h
virt/kvm/arm/vgic.c
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/arm/vgic.c | 157 | ||||
| -rw-r--r-- | virt/kvm/ioapic.c | 46 | ||||
| -rw-r--r-- | virt/kvm/ioapic.h | 2 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 101 | ||||
| -rw-r--r-- | virt/kvm/vfio.c | 22 |
5 files changed, 195 insertions, 133 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index efe6eee2e7eb..eeb23b37f87c 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c | |||
| @@ -1522,83 +1522,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1522 | return 0; | 1522 | return 0; |
| 1523 | } | 1523 | } |
| 1524 | 1524 | ||
| 1525 | static void vgic_init_maintenance_interrupt(void *info) | ||
| 1526 | { | ||
| 1527 | enable_percpu_irq(vgic->maint_irq, 0); | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | static int vgic_cpu_notify(struct notifier_block *self, | ||
| 1531 | unsigned long action, void *cpu) | ||
| 1532 | { | ||
| 1533 | switch (action) { | ||
| 1534 | case CPU_STARTING: | ||
| 1535 | case CPU_STARTING_FROZEN: | ||
| 1536 | vgic_init_maintenance_interrupt(NULL); | ||
| 1537 | break; | ||
| 1538 | case CPU_DYING: | ||
| 1539 | case CPU_DYING_FROZEN: | ||
| 1540 | disable_percpu_irq(vgic->maint_irq); | ||
| 1541 | break; | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | return NOTIFY_OK; | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | static struct notifier_block vgic_cpu_nb = { | ||
| 1548 | .notifier_call = vgic_cpu_notify, | ||
| 1549 | }; | ||
| 1550 | |||
| 1551 | static const struct of_device_id vgic_ids[] = { | ||
| 1552 | { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, | ||
| 1553 | { .compatible = "arm,gic-v3", .data = vgic_v3_probe, }, | ||
| 1554 | {}, | ||
| 1555 | }; | ||
| 1556 | |||
| 1557 | int kvm_vgic_hyp_init(void) | ||
| 1558 | { | ||
| 1559 | const struct of_device_id *matched_id; | ||
| 1560 | const int (*vgic_probe)(struct device_node *,const struct vgic_ops **, | ||
| 1561 | const struct vgic_params **); | ||
| 1562 | struct device_node *vgic_node; | ||
| 1563 | int ret; | ||
| 1564 | |||
| 1565 | vgic_node = of_find_matching_node_and_match(NULL, | ||
| 1566 | vgic_ids, &matched_id); | ||
| 1567 | if (!vgic_node) { | ||
| 1568 | kvm_err("error: no compatible GIC node found\n"); | ||
| 1569 | return -ENODEV; | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | vgic_probe = matched_id->data; | ||
| 1573 | ret = vgic_probe(vgic_node, &vgic_ops, &vgic); | ||
| 1574 | if (ret) | ||
| 1575 | return ret; | ||
| 1576 | |||
| 1577 | ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler, | ||
| 1578 | "vgic", kvm_get_running_vcpus()); | ||
| 1579 | if (ret) { | ||
| 1580 | kvm_err("Cannot register interrupt %d\n", vgic->maint_irq); | ||
| 1581 | return ret; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | ret = __register_cpu_notifier(&vgic_cpu_nb); | ||
| 1585 | if (ret) { | ||
| 1586 | kvm_err("Cannot register vgic CPU notifier\n"); | ||
| 1587 | goto out_free_irq; | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | /* Callback into for arch code for setup */ | ||
| 1591 | vgic_arch_setup(vgic); | ||
| 1592 | |||
| 1593 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); | ||
| 1594 | |||
| 1595 | return 0; | ||
| 1596 | |||
| 1597 | out_free_irq: | ||
| 1598 | free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); | ||
| 1599 | return ret; | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | /** | 1525 | /** |
| 1603 | * kvm_vgic_init - Initialize global VGIC state before running any VCPUs | 1526 | * kvm_vgic_init - Initialize global VGIC state before running any VCPUs |
| 1604 | * @kvm: pointer to the kvm struct | 1527 | * @kvm: pointer to the kvm struct |
| @@ -2062,7 +1985,7 @@ static int vgic_create(struct kvm_device *dev, u32 type) | |||
| 2062 | return kvm_vgic_create(dev->kvm); | 1985 | return kvm_vgic_create(dev->kvm); |
| 2063 | } | 1986 | } |
| 2064 | 1987 | ||
| 2065 | struct kvm_device_ops kvm_arm_vgic_v2_ops = { | 1988 | static struct kvm_device_ops kvm_arm_vgic_v2_ops = { |
| 2066 | .name = "kvm-arm-vgic", | 1989 | .name = "kvm-arm-vgic", |
| 2067 | .create = vgic_create, | 1990 | .create = vgic_create, |
| 2068 | .destroy = vgic_destroy, | 1991 | .destroy = vgic_destroy, |
| @@ -2070,3 +1993,81 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = { | |||
| 2070 | .get_attr = vgic_get_attr, | 1993 | .get_attr = vgic_get_attr, |
| 2071 | .has_attr = vgic_has_attr, | 1994 | .has_attr = vgic_has_attr, |
| 2072 | }; | 1995 | }; |
| 1996 | |||
| 1997 | static void vgic_init_maintenance_interrupt(void *info) | ||
| 1998 | { | ||
| 1999 | enable_percpu_irq(vgic->maint_irq, 0); | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | static int vgic_cpu_notify(struct notifier_block *self, | ||
| 2003 | unsigned long action, void *cpu) | ||
| 2004 | { | ||
| 2005 | switch (action) { | ||
| 2006 | case CPU_STARTING: | ||
| 2007 | case CPU_STARTING_FROZEN: | ||
| 2008 | vgic_init_maintenance_interrupt(NULL); | ||
| 2009 | break; | ||
| 2010 | case CPU_DYING: | ||
| 2011 | case CPU_DYING_FROZEN: | ||
| 2012 | disable_percpu_irq(vgic->maint_irq); | ||
| 2013 | break; | ||
| 2014 | } | ||
| 2015 | |||
| 2016 | return NOTIFY_OK; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | static struct notifier_block vgic_cpu_nb = { | ||
| 2020 | .notifier_call = vgic_cpu_notify, | ||
| 2021 | }; | ||
| 2022 | |||
| 2023 | static const struct of_device_id vgic_ids[] = { | ||
| 2024 | { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, | ||
| 2025 | { .compatible = "arm,gic-v3", .data = vgic_v3_probe, }, | ||
| 2026 | {}, | ||
| 2027 | }; | ||
| 2028 | |||
| 2029 | int kvm_vgic_hyp_init(void) | ||
| 2030 | { | ||
| 2031 | const struct of_device_id *matched_id; | ||
| 2032 | const int (*vgic_probe)(struct device_node *,const struct vgic_ops **, | ||
| 2033 | const struct vgic_params **); | ||
| 2034 | struct device_node *vgic_node; | ||
| 2035 | int ret; | ||
| 2036 | |||
| 2037 | vgic_node = of_find_matching_node_and_match(NULL, | ||
| 2038 | vgic_ids, &matched_id); | ||
| 2039 | if (!vgic_node) { | ||
| 2040 | kvm_err("error: no compatible GIC node found\n"); | ||
| 2041 | return -ENODEV; | ||
| 2042 | } | ||
| 2043 | |||
| 2044 | vgic_probe = matched_id->data; | ||
| 2045 | ret = vgic_probe(vgic_node, &vgic_ops, &vgic); | ||
| 2046 | if (ret) | ||
| 2047 | return ret; | ||
| 2048 | |||
| 2049 | ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler, | ||
| 2050 | "vgic", kvm_get_running_vcpus()); | ||
| 2051 | if (ret) { | ||
| 2052 | kvm_err("Cannot register interrupt %d\n", vgic->maint_irq); | ||
| 2053 | return ret; | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | ret = __register_cpu_notifier(&vgic_cpu_nb); | ||
| 2057 | if (ret) { | ||
| 2058 | kvm_err("Cannot register vgic CPU notifier\n"); | ||
| 2059 | goto out_free_irq; | ||
| 2060 | } | ||
| 2061 | |||
| 2062 | /* Callback into for arch code for setup */ | ||
| 2063 | vgic_arch_setup(vgic); | ||
| 2064 | |||
| 2065 | on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); | ||
| 2066 | |||
| 2067 | return kvm_register_device_ops(&kvm_arm_vgic_v2_ops, | ||
| 2068 | KVM_DEV_TYPE_ARM_VGIC_V2); | ||
| 2069 | |||
| 2070 | out_free_irq: | ||
| 2071 | free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); | ||
| 2072 | return ret; | ||
| 2073 | } | ||
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index e8ce34c9db32..0ba4057d271b 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
| @@ -405,6 +405,26 @@ void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id) | |||
| 405 | spin_unlock(&ioapic->lock); | 405 | spin_unlock(&ioapic->lock); |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | static void kvm_ioapic_eoi_inject_work(struct work_struct *work) | ||
| 409 | { | ||
| 410 | int i; | ||
| 411 | struct kvm_ioapic *ioapic = container_of(work, struct kvm_ioapic, | ||
| 412 | eoi_inject.work); | ||
| 413 | spin_lock(&ioapic->lock); | ||
| 414 | for (i = 0; i < IOAPIC_NUM_PINS; i++) { | ||
