#include "timer_test.h"
 #include "vgic.h"
 
-#define GICD_BASE_GPA                  0x8000000ULL
-#define GICR_BASE_GPA                  0x80A0000ULL
-
 enum guest_stage {
        GUEST_STAGE_VTIMER_CVAL = 1,
        GUEST_STAGE_VTIMER_TVAL,
 
        local_irq_disable();
 
-       gic_init(GIC_V3, test_args.nr_vcpus,
-               (void *)GICD_BASE_GPA, (void *)GICR_BASE_GPA);
+       gic_init(GIC_V3, test_args.nr_vcpus);
 
        timer_set_ctl(VIRTUAL, CTL_IMASK);
        timer_set_ctl(PHYSICAL, CTL_IMASK);
                vcpu_init_descriptor_tables(vcpus[i]);
 
        test_init_timer_irq(vm);
-       gic_fd = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+       gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
        __TEST_REQUIRE(gic_fd >= 0, "Failed to create vgic-v3");
 
        /* Make all the test's cmdline args visible to the guest */
 
 #include "gic_v3.h"
 #include "vgic.h"
 
-#define GICD_BASE_GPA          0x08000000ULL
-#define GICR_BASE_GPA          0x080A0000ULL
-
 /*
  * Stores the user specified args; it's passed to the guest and to every test
  * function.
 #define IRQ_DEFAULT_PRIO       (LOWEST_PRIO - 1)
 #define IRQ_DEFAULT_PRIO_REG   (IRQ_DEFAULT_PRIO << KVM_PRIO_SHIFT) /* 0xf0 */
 
-static void *dist = (void *)GICD_BASE_GPA;
-static void *redist = (void *)GICR_BASE_GPA;
-
 /*
  * The kvm_inject_* utilities are used by the guest to ask the host to inject
  * interrupts (e.g., using the KVM_IRQ_LINE ioctl).
        bool level_sensitive = args->level_sensitive;
        struct kvm_inject_desc *f, *inject_fns;
 
-       gic_init(GIC_V3, 1, dist, redist);
+       gic_init(GIC_V3, 1);
 
        for (i = 0; i < nr_irqs; i++)
                gic_irq_enable(i);
        memcpy(addr_gva2hva(vm, args_gva), &args, sizeof(args));
        vcpu_args_set(vcpu, 1, args_gva);
 
-       gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
-                       GICD_BASE_GPA, GICR_BASE_GPA);
+       gic_fd = vgic_v3_setup(vm, 1, nr_irqs);
        __TEST_REQUIRE(gic_fd >= 0, "Failed to create vgic-v3, skipping");
 
        vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
 
        GUEST_DONE();
 }
 
-#define GICD_BASE_GPA  0x8000000ULL
-#define GICR_BASE_GPA  0x80A0000ULL
-
 /* Create a VM that has one vCPU with PMUv3 configured. */
 static void create_vpmu_vm(void *guest_code)
 {
        init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
        vpmu_vm.vcpu = aarch64_vcpu_add(vpmu_vm.vm, 0, &init, guest_code);
        vcpu_init_descriptor_tables(vpmu_vm.vcpu);
-       vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64,
-                                       GICD_BASE_GPA, GICR_BASE_GPA);
+       vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64);
        __TEST_REQUIRE(vpmu_vm.gic_fd >= 0,
                       "Failed to create vgic-v3, skipping");
 
 
 #ifdef __aarch64__
 #include "aarch64/vgic.h"
 
-#define GICD_BASE_GPA                  0x8000000ULL
-#define GICR_BASE_GPA                  0x80A0000ULL
-
 static int gic_fd;
 
 static void arch_setup_vm(struct kvm_vm *vm, unsigned int nr_vcpus)
         * The test can still run even if hardware does not support GICv3, as it
         * is only an optimization to reduce guest exits.
         */
-       gic_fd = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+       gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
 }
 
 static void arch_cleanup_vm(struct kvm_vm *vm)
 
 #ifndef SELFTEST_KVM_GIC_H
 #define SELFTEST_KVM_GIC_H
 
+#include <asm/kvm.h>
+
 enum gic_type {
        GIC_V3,
        GIC_TYPE_MAX,
 };
 
+#define GICD_BASE_GPA          0x8000000ULL
+#define GICR_BASE_GPA          (GICD_BASE_GPA + KVM_VGIC_V3_DIST_SIZE)
+
+/* The GIC is identity-mapped into the guest at the time of setup. */
+#define GICD_BASE_GVA          ((volatile void *)GICD_BASE_GPA)
+#define GICR_BASE_GVA          ((volatile void *)GICR_BASE_GPA)
+
 #define MIN_SGI                        0
 #define MIN_PPI                        16
 #define MIN_SPI                        32
 #define INTID_IS_PPI(intid)    (MIN_PPI <= (intid) && (intid) < MIN_SPI)
 #define INTID_IS_SPI(intid)    (MIN_SPI <= (intid) && (intid) <= MAX_SPI)
 
-void gic_init(enum gic_type type, unsigned int nr_cpus,
-               void *dist_base, void *redist_base);
+void gic_init(enum gic_type type, unsigned int nr_cpus);
 void gic_irq_enable(unsigned int intid);
 void gic_irq_disable(unsigned int intid);
 unsigned int gic_get_and_ack_irq(void);
 
        ((uint64_t)(flags) << 12) | \
        index)
 
-int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
-               uint64_t gicd_base_gpa, uint64_t gicr_base_gpa);
+int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs);
 
 #define VGIC_MAX_RESERVED      1023
 
 
 static const struct gic_common_ops *gic_common_ops;
 static struct spinlock gic_lock;
 
-static void gic_cpu_init(unsigned int cpu, void *redist_base)
+static void gic_cpu_init(unsigned int cpu)
 {
-       gic_common_ops->gic_cpu_init(cpu, redist_base);
+       gic_common_ops->gic_cpu_init(cpu);
 }
 
-static void
-gic_dist_init(enum gic_type type, unsigned int nr_cpus, void *dist_base)
+static void gic_dist_init(enum gic_type type, unsigned int nr_cpus)
 {
        const struct gic_common_ops *gic_ops = NULL;
 
 
        GUEST_ASSERT(gic_ops);
 
-       gic_ops->gic_init(nr_cpus, dist_base);
+       gic_ops->gic_init(nr_cpus);
        gic_common_ops = gic_ops;
 
        /* Make sure that the initialized data is visible to all the vCPUs */
        spin_unlock(&gic_lock);
 }
 
-void gic_init(enum gic_type type, unsigned int nr_cpus,
-               void *dist_base, void *redist_base)
+void gic_init(enum gic_type type, unsigned int nr_cpus)
 {
        uint32_t cpu = guest_get_vcpuid();
 
        GUEST_ASSERT(type < GIC_TYPE_MAX);
-       GUEST_ASSERT(dist_base);
-       GUEST_ASSERT(redist_base);
        GUEST_ASSERT(nr_cpus);
 
-       gic_dist_init(type, nr_cpus, dist_base);
-       gic_cpu_init(cpu, redist_base);
+       gic_dist_init(type, nr_cpus);
+       gic_cpu_init(cpu);
 }
 
 void gic_irq_enable(unsigned int intid)
 
 #define SELFTEST_KVM_GIC_PRIVATE_H
 
 struct gic_common_ops {
-       void (*gic_init)(unsigned int nr_cpus, void *dist_base);
-       void (*gic_cpu_init)(unsigned int cpu, void *redist_base);
+       void (*gic_init)(unsigned int nr_cpus);
+       void (*gic_cpu_init)(unsigned int cpu);
        void (*gic_irq_enable)(unsigned int intid);
        void (*gic_irq_disable)(unsigned int intid);
        uint64_t (*gic_read_iar)(void);
 
 #define ICC_PMR_DEF_PRIO               0xf0
 
 struct gicv3_data {
-       void *dist_base;
-       void *redist_base[GICV3_MAX_CPUS];
        unsigned int nr_cpus;
        unsigned int nr_spis;
 };
 {
        unsigned int count = 100000; /* 1s */
 
-       while (readl(gicv3_data.dist_base + GICD_CTLR) & GICD_CTLR_RWP) {
+       while (readl(GICD_BASE_GVA + GICD_CTLR) & GICD_CTLR_RWP) {
                GUEST_ASSERT(count--);
                udelay(10);
        }
 }
 
-static void gicv3_gicr_wait_for_rwp(void *redist_base)
+static inline volatile void *gicr_base_cpu(uint32_t cpu)
+{
+       /* Align all the redistributors sequentially */
+       return GICR_BASE_GVA + cpu * SZ_64K * 2;
+}
+
+static void gicv3_gicr_wait_for_rwp(uint32_t cpu)
 {
        unsigned int count = 100000; /* 1s */
 
-       while (readl(redist_base + GICR_CTLR) & GICR_CTLR_RWP) {
+       while (readl(gicr_base_cpu(cpu) + GICR_CTLR) & GICR_CTLR_RWP) {
                GUEST_ASSERT(count--);
                udelay(10);
        }
        if (cpu_or_dist & DIST_BIT)
                gicv3_gicd_wait_for_rwp();
        else
-               gicv3_gicr_wait_for_rwp(gicv3_data.redist_base[cpu_or_dist]);
+               gicv3_gicr_wait_for_rwp(cpu_or_dist);
 }
 
 static enum gicv3_intid_range get_intid_range(unsigned int intid)
 
 uint32_t gicv3_reg_readl(uint32_t cpu_or_dist, uint64_t offset)
 {
-       void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base
-               : sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]);
+       volatile void *base = cpu_or_dist & DIST_BIT ? GICD_BASE_GVA
+                       : sgi_base_from_redist(gicr_base_cpu(cpu_or_dist));
        return readl(base + offset);
 }
 
 void gicv3_reg_writel(uint32_t cpu_or_dist, uint64_t offset, uint32_t reg_val)
 {
-       void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base
-               : sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]);
+       volatile void *base = cpu_or_dist & DIST_BIT ? GICD_BASE_GVA
+                       : sgi_base_from_redist(gicr_base_cpu(cpu_or_dist));
        writel(reg_val, base + offset);
 }
 
        return gicv3_read_reg(intid, GICD_ISPENDR, 32, 1);
 }
 
-static void gicv3_enable_redist(void *redist_base)
+static void gicv3_enable_redist(volatile void *redist_base)
 {
        uint32_t val = readl(redist_base + GICR_WAKER);
        unsigned int count = 100000; /* 1s */
        }
 }
 
-static inline void *gicr_base_cpu(void *redist_base, uint32_t cpu)
+static void gicv3_cpu_init(unsigned int cpu)
 {
-       /* Align all the redistributors sequentially */
-       return redist_base + cpu * SZ_64K * 2;
-}
-
-static void gicv3_cpu_init(unsigned int cpu, void *redist_base)
-{
-       void *sgi_base;
+       volatile void *sgi_base;
        unsigned int i;
-       void *redist_base_cpu;
+       volatile void *redist_base_cpu;
 
        GUEST_ASSERT(cpu < gicv3_data.nr_cpus);
 
-       redist_base_cpu = gicr_base_cpu(redist_base, cpu);
+       redist_base_cpu = gicr_base_cpu(cpu);
        sgi_base = sgi_base_from_redist(redist_base_cpu);
 
        gicv3_enable_redist(redist_base_cpu);
                writel(GICD_INT_DEF_PRI_X4,
                                sgi_base + GICR_IPRIORITYR0 + i);
 
-       gicv3_gicr_wait_for_rwp(redist_base_cpu);
+       gicv3_gicr_wait_for_rwp(cpu);
 
        /* Enable the GIC system register (ICC_*) access */
        write_sysreg_s(read_sysreg_s(SYS_ICC_SRE_EL1) | ICC_SRE_EL1_SRE,
 
        /* Enable non-secure Group-1 interrupts */
        write_sysreg_s(ICC_IGRPEN1_EL1_MASK, SYS_ICC_IGRPEN1_EL1);
-
-       gicv3_data.redist_base[cpu] = redist_base_cpu;
 }
 
 static void gicv3_dist_init(void)
 {
-       void *dist_base = gicv3_data.dist_base;
        unsigned int i;
 
        /* Disable the distributor until we set things up */
-       writel(0, dist_base + GICD_CTLR);
+       writel(0, GICD_BASE_GVA + GICD_CTLR);
        gicv3_gicd_wait_for_rwp();
 
        /*
         * Also, deactivate and disable them.
         */
        for (i = 32; i < gicv3_data.nr_spis; i += 32) {
-               writel(~0, dist_base + GICD_IGROUPR + i / 8);
-               writel(~0, dist_base + GICD_ICACTIVER + i / 8);
-               writel(~0, dist_base + GICD_ICENABLER + i / 8);
+               writel(~0, GICD_BASE_GVA + GICD_IGROUPR + i / 8);
+               writel(~0, GICD_BASE_GVA + GICD_ICACTIVER + i / 8);
+               writel(~0, GICD_BASE_GVA + GICD_ICENABLER + i / 8);
        }
 
        /* Set a default priority for all the SPIs */
        for (i = 32; i < gicv3_data.nr_spis; i += 4)
                writel(GICD_INT_DEF_PRI_X4,
-                               dist_base + GICD_IPRIORITYR + i);
+                               GICD_BASE_GVA + GICD_IPRIORITYR + i);
 
        /* Wait for the settings to sync-in */
        gicv3_gicd_wait_for_rwp();
 
        /* Finally, enable the distributor globally with ARE */
        writel(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A |
-                       GICD_CTLR_ENABLE_G1, dist_base + GICD_CTLR);
+                       GICD_CTLR_ENABLE_G1, GICD_BASE_GVA + GICD_CTLR);
        gicv3_gicd_wait_for_rwp();
 }
 
-static void gicv3_init(unsigned int nr_cpus, void *dist_base)
+static void gicv3_init(unsigned int nr_cpus)
 {
        GUEST_ASSERT(nr_cpus <= GICV3_MAX_CPUS);
 
        gicv3_data.nr_cpus = nr_cpus;
-       gicv3_data.dist_base = dist_base;
        gicv3_data.nr_spis = GICD_TYPER_SPIS(
-                               readl(gicv3_data.dist_base + GICD_TYPER));
+                               readl(GICD_BASE_GVA + GICD_TYPER));
        if (gicv3_data.nr_spis > 1020)
                gicv3_data.nr_spis = 1020;
 
 
  * Input args:
  *     vm - KVM VM
  *     nr_vcpus - Number of vCPUs supported by this VM
- *     gicd_base_gpa - Guest Physical Address of the Distributor region
- *     gicr_base_gpa - Guest Physical Address of the Redistributor region
  *
  * Output args: None
  *
  * redistributor regions of the guest. Since it depends on the number of
  * vCPUs for the VM, it must be called after all the vCPUs have been created.
  */
-int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
-               uint64_t gicd_base_gpa, uint64_t gicr_base_gpa)
+int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs)
 {
        int gic_fd;
-       uint64_t redist_attr;
+       uint64_t attr;
        struct list_head *iter;
        unsigned int nr_gic_pages, nr_vcpus_created = 0;
 
        kvm_device_attr_set(gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                            KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);
 
+       attr = GICD_BASE_GPA;
        kvm_device_attr_set(gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
-                           KVM_VGIC_V3_ADDR_TYPE_DIST, &gicd_base_gpa);
+                           KVM_VGIC_V3_ADDR_TYPE_DIST, &attr);
        nr_gic_pages = vm_calc_num_guest_pages(vm->mode, KVM_VGIC_V3_DIST_SIZE);
-       virt_map(vm, gicd_base_gpa, gicd_base_gpa,  nr_gic_pages);
+       virt_map(vm, GICD_BASE_GPA, GICD_BASE_GPA, nr_gic_pages);
 
        /* Redistributor setup */
-       redist_attr = REDIST_REGION_ATTR_ADDR(nr_vcpus, gicr_base_gpa, 0, 0);
+       attr = REDIST_REGION_ATTR_ADDR(nr_vcpus, GICR_BASE_GPA, 0, 0);
        kvm_device_attr_set(gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
-                           KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &redist_attr);
+                           KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &attr);
        nr_gic_pages = vm_calc_num_guest_pages(vm->mode,
                                                KVM_VGIC_V3_REDIST_SIZE * nr_vcpus);
-       virt_map(vm, gicr_base_gpa, gicr_base_gpa,  nr_gic_pages);
+       virt_map(vm, GICR_BASE_GPA, GICR_BASE_GPA, nr_gic_pages);
 
        kvm_device_attr_set(gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                            KVM_DEV_ARM_VGIC_CTRL_INIT, NULL);