summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2019-08-23 13:33:30 -0400
committerMarc Zyngier <maz@kernel.org>2019-08-25 06:02:52 -0400
commit3109741a8d773b91eec4a1f7764c97a1176ec32d (patch)
treeeaf4b6f30e5d5d290bf2b4ad51d52263c549b3b2 /virt
parent926c61568d0b2e57254e92290369d4539568f8cc (diff)
KVM: arm/arm64: vgic: Use a single IO device per redistributor
At the moment we use 2 IO devices per GICv3 redistributor: one one for the RD_base frame and one for the SGI_base frame. Instead we can use a single IO device per redistributor (the 2 frames are contiguous). This saves slots on the KVM_MMIO_BUS which is currently limited to NR_IOBUS_DEVS (1000). This change allows to instantiate up to 512 redistributors and may speed the guest boot with a large number of VCPUs. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic-init.c1
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v3.c81
2 files changed, 24 insertions, 58 deletions
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 9175bfd83263..958e2f0d2207 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -193,7 +193,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
193 int i; 193 int i;
194 194
195 vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; 195 vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
196 vgic_cpu->sgi_iodev.base_addr = VGIC_ADDR_UNDEF;
197 196
198 INIT_LIST_HEAD(&vgic_cpu->ap_list_head); 197 INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
199 raw_spin_lock_init(&vgic_cpu->ap_list_lock); 198 raw_spin_lock_init(&vgic_cpu->ap_list_lock);
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index fdcfb7ae4491..7dfd15dbb308 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -517,7 +517,8 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = {
517 VGIC_ACCESS_32bit), 517 VGIC_ACCESS_32bit),
518}; 518};
519 519
520static const struct vgic_register_region vgic_v3_rdbase_registers[] = { 520static const struct vgic_register_region vgic_v3_rd_registers[] = {
521 /* RD_base registers */
521 REGISTER_DESC_WITH_LENGTH(GICR_CTLR, 522 REGISTER_DESC_WITH_LENGTH(GICR_CTLR,
522 vgic_mmio_read_v3r_ctlr, vgic_mmio_write_v3r_ctlr, 4, 523 vgic_mmio_read_v3r_ctlr, vgic_mmio_write_v3r_ctlr, 4,
523 VGIC_ACCESS_32bit), 524 VGIC_ACCESS_32bit),
@@ -542,44 +543,42 @@ static const struct vgic_register_region vgic_v3_rdbase_registers[] = {
542 REGISTER_DESC_WITH_LENGTH(GICR_IDREGS, 543 REGISTER_DESC_WITH_LENGTH(GICR_IDREGS,
543 vgic_mmio_read_v3_idregs, vgic_mmio_write_wi, 48, 544 vgic_mmio_read_v3_idregs, vgic_mmio_write_wi, 48,
544 VGIC_ACCESS_32bit), 545 VGIC_ACCESS_32bit),
545}; 546 /* SGI_base registers */
546 547 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_IGROUPR0,
547static const struct vgic_register_region vgic_v3_sgibase_registers[] = {
548 REGISTER_DESC_WITH_LENGTH(GICR_IGROUPR0,
549 vgic_mmio_read_group, vgic_mmio_write_group, 4, 548 vgic_mmio_read_group, vgic_mmio_write_group, 4,
550 VGIC_ACCESS_32bit), 549 VGIC_ACCESS_32bit),
551 REGISTER_DESC_WITH_LENGTH(GICR_ISENABLER0, 550 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_ISENABLER0,
552 vgic_mmio_read_enable, vgic_mmio_write_senable, 4, 551 vgic_mmio_read_enable, vgic_mmio_write_senable, 4,
553 VGIC_ACCESS_32bit), 552 VGIC_ACCESS_32bit),
554 REGISTER_DESC_WITH_LENGTH(GICR_ICENABLER0, 553 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_ICENABLER0,
555 vgic_mmio_read_enable, vgic_mmio_write_cenable, 4, 554 vgic_mmio_read_enable, vgic_mmio_write_cenable, 4,
556 VGIC_ACCESS_32bit), 555 VGIC_ACCESS_32bit),
557 REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ISPENDR0, 556 REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISPENDR0,
558 vgic_mmio_read_pending, vgic_mmio_write_spending, 557 vgic_mmio_read_pending, vgic_mmio_write_spending,
559 vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4, 558 vgic_v3_uaccess_read_pending, vgic_v3_uaccess_write_pending, 4,
560 VGIC_ACCESS_32bit), 559 VGIC_ACCESS_32bit),
561 REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ICPENDR0, 560 REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICPENDR0,
562 vgic_mmio_read_pending, vgic_mmio_write_cpending, 561 vgic_mmio_read_pending, vgic_mmio_write_cpending,
563 vgic_mmio_read_raz, vgic_mmio_uaccess_write_wi, 4, 562 vgic_mmio_read_raz, vgic_mmio_uaccess_write_wi, 4,
564 VGIC_ACCESS_32bit), 563 VGIC_ACCESS_32bit),
565 REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ISACTIVER0, 564 REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ISACTIVER0,
566 vgic_mmio_read_active, vgic_mmio_write_sactive, 565 vgic_mmio_read_active, vgic_mmio_write_sactive,
567 NULL, vgic_mmio_uaccess_write_sactive, 566 NULL, vgic_mmio_uaccess_write_sactive,
568 4, VGIC_ACCESS_32bit), 567 4, VGIC_ACCESS_32bit),
569 REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ICACTIVER0, 568 REGISTER_DESC_WITH_LENGTH_UACCESS(SZ_64K + GICR_ICACTIVER0,
570 vgic_mmio_read_active, vgic_mmio_write_cactive, 569 vgic_mmio_read_active, vgic_mmio_write_cactive,
571 NULL, vgic_mmio_uaccess_write_cactive, 570 NULL, vgic_mmio_uaccess_write_cactive,
572 4, VGIC_ACCESS_32bit), 571 4, VGIC_ACCESS_32bit),
573 REGISTER_DESC_WITH_LENGTH(GICR_IPRIORITYR0, 572 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_IPRIORITYR0,
574 vgic_mmio_read_priority, vgic_mmio_write_priority, 32, 573 vgic_mmio_read_priority, vgic_mmio_write_priority, 32,
575 VGIC_ACCESS_32bit | VGIC_ACCESS_8bit), 574 VGIC_ACCESS_32bit | VGIC_ACCESS_8bit),
576 REGISTER_DESC_WITH_LENGTH(GICR_ICFGR0, 575 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_ICFGR0,
577 vgic_mmio_read_config, vgic_mmio_write_config, 8, 576 vgic_mmio_read_config, vgic_mmio_write_config, 8,
578 VGIC_ACCESS_32bit), 577 VGIC_ACCESS_32bit),
579 REGISTER_DESC_WITH_LENGTH(GICR_IGRPMODR0, 578 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_IGRPMODR0,
580 vgic_mmio_read_raz, vgic_mmio_write_wi, 4, 579 vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
581 VGIC_ACCESS_32bit), 580 VGIC_ACCESS_32bit),
582 REGISTER_DESC_WITH_LENGTH(GICR_NSACR, 581 REGISTER_DESC_WITH_LENGTH(SZ_64K + GICR_NSACR,
583 vgic_mmio_read_raz, vgic_mmio_write_wi, 4, 582 vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
584 VGIC_ACCESS_32bit), 583 VGIC_ACCESS_32bit),
585}; 584};
@@ -609,9 +608,8 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
609 struct vgic_dist *vgic = &kvm->arch.vgic; 608 struct vgic_dist *vgic = &kvm->arch.vgic;
610 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 609 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
611 struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev; 610 struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev;
612 struct vgic_io_device *sgi_dev = &vcpu->arch.vgic_cpu.sgi_iodev;
613 struct vgic_redist_region *rdreg; 611 struct vgic_redist_region *rdreg;
614 gpa_t rd_base, sgi_base; 612 gpa_t rd_base;
615 int ret; 613 int ret;
616 614
617 if (!IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr)) 615 if (!IS_VGIC_ADDR_UNDEF(vgic_cpu->rd_iodev.base_addr))
@@ -633,52 +631,31 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
633 vgic_cpu->rdreg = rdreg; 631 vgic_cpu->rdreg = rdreg;
634 632
635 rd_base = rdreg->base + rdreg->free_index * KVM_VGIC_V3_REDIST_SIZE; 633 rd_base = rdreg->base + rdreg->free_index * KVM_VGIC_V3_REDIST_SIZE;
636 sgi_base = rd_base + SZ_64K;
637 634
638 kvm_iodevice_init(&rd_dev->dev, &kvm_io_gic_ops); 635 kvm_iodevice_init(&rd_dev->dev, &kvm_io_gic_ops);
639 rd_dev->base_addr = rd_base; 636 rd_dev->base_addr = rd_base;
640 rd_dev->iodev_type = IODEV_REDIST; 637 rd_dev->iodev_type = IODEV_REDIST;
641 rd_dev->regions = vgic_v3_rdbase_registers; 638 rd_dev->regions = vgic_v3_rd_registers;
642 rd_dev->nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers); 639 rd_dev->nr_regions = ARRAY_SIZE(vgic_v3_rd_registers);
643 rd_dev->redist_vcpu = vcpu; 640 rd_dev->redist_vcpu = vcpu;
644 641
645 mutex_lock(&kvm->slots_lock); 642 mutex_lock(&kvm->slots_lock);
646 ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, rd_base, 643 ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, rd_base,
647 SZ_64K, &rd_dev->dev); 644 2 * SZ_64K, &rd_dev->dev);
648 mutex_unlock(&kvm->slots_lock); 645 mutex_unlock(&kvm->slots_lock);
649 646
650 if (ret) 647 if (ret)
651 return ret; 648 return ret;
652 649
653 kvm_iodevice_init(&sgi_dev->dev, &kvm_io_gic_ops);
654 sgi_dev->base_addr = sgi_base;
655 sgi_dev->iodev_type = IODEV_REDIST;
656 sgi_dev->regions = vgic_v3_sgibase_registers;
657 sgi_dev->nr_regions = ARRAY_SIZE(vgic_v3_sgibase_registers);
658 sgi_dev->redist_vcpu = vcpu;
659
660 mutex_lock(&kvm->slots_lock);
661 ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, sgi_base,
662 SZ_64K, &sgi_dev->dev);
663 if (ret) {
664 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS,
665 &rd_dev->dev);
666 goto out;
667 }
668
669 rdreg->free_index++; 650 rdreg->free_index++;
670out: 651 return 0;
671 mutex_unlock(&kvm->slots_lock);
672 return ret;
673} 652}
674 653
675static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu) 654static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
676{ 655{
677 struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev; 656 struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev;
678 struct vgic_io_device *sgi_dev = &vcpu->arch.vgic_cpu.sgi_iodev;
679 657
680 kvm_io_bus_unregister_dev(vcpu->kvm, KVM_MMIO_BUS, &rd_dev->dev); 658 kvm_io_bus_unregister_dev(vcpu->kvm, KVM_MMIO_BUS, &rd_dev->dev);
681 kvm_io_bus_unregister_dev(vcpu->kvm, KVM_MMIO_BUS, &sgi_dev->dev);
682} 659}
683 660
684static int vgic_register_all_redist_iodevs(struct kvm *kvm) 661static int vgic_register_all_redist_iodevs(struct kvm *kvm)
@@ -828,8 +805,8 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
828 iodev.base_addr = 0; 805 iodev.base_addr = 0;
829 break; 806 break;
830 case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:{ 807 case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:{
831 iodev.regions = vgic_v3_rdbase_registers; 808 iodev.regions = vgic_v3_rd_registers;
832 iodev.nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers); 809 iodev.nr_regions = ARRAY_SIZE(vgic_v3_rd_registers);
833 iodev.base_addr = 0; 810 iodev.base_addr = 0;
834 break; 811 break;
835 } 812 }
@@ -987,21 +964,11 @@ int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
987 int offset, u32 *val) 964 int offset, u32 *val)
988{ 965{
989 struct vgic_io_device rd_dev = { 966 struct vgic_io_device rd_dev = {
990 .regions = vgic_v3_rdbase_registers, 967 .regions = vgic_v3_rd_registers,
991 .nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers), 968 .nr_regions = ARRAY_SIZE(vgic_v3_rd_registers),
992 }; 969 };
993 970
994 struct vgic_io_device sgi_dev = { 971 return vgic_uaccess(vcpu, &rd_dev, is_write, offset, val);
995 .regions = vgic_v3_sgibase_registers,
996 .nr_regions = ARRAY_SIZE(vgic_v3_sgibase_registers),
997 };
998
999 /* SGI_base is the next 64K frame after RD_base */
1000 if (offset >= SZ_64K)
1001 return vgic_uaccess(vcpu, &sgi_dev, is_write, offset - SZ_64K,
1002 val);
1003 else
1004 return vgic_uaccess(vcpu, &rd_dev, is_write, offset, val);
1005} 972}
1006 973
1007int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write, 974int vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write,