Skip to content

Commit 1505bc7

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: selftests: Standardise layout of GIC frames
It would appear that all of the selftests are using the same exact layout for the GIC frames. Fold this back into the library implementation to avoid defining magic values all over the selftests. This is an extension of Colton's change, ripping out parameterization of from the library internals in addition to the public interfaces. Co-developed-by: Colton Lewis <coltonlewis@google.com> Signed-off-by: Colton Lewis <coltonlewis@google.com> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20240422200158.2606761-15-oliver.upton@linux.dev Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent d82689b commit 1505bc7

10 files changed

Lines changed: 62 additions & 85 deletions

File tree

tools/testing/selftests/kvm/aarch64/arch_timer.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
#include "timer_test.h"
1515
#include "vgic.h"
1616

17-
#define GICD_BASE_GPA 0x8000000ULL
18-
#define GICR_BASE_GPA 0x80A0000ULL
19-
2017
enum guest_stage {
2118
GUEST_STAGE_VTIMER_CVAL = 1,
2219
GUEST_STAGE_VTIMER_TVAL,
@@ -149,8 +146,7 @@ static void guest_code(void)
149146

150147
local_irq_disable();
151148

152-
gic_init(GIC_V3, test_args.nr_vcpus,
153-
(void *)GICD_BASE_GPA, (void *)GICR_BASE_GPA);
149+
gic_init(GIC_V3, test_args.nr_vcpus);
154150

155151
timer_set_ctl(VIRTUAL, CTL_IMASK);
156152
timer_set_ctl(PHYSICAL, CTL_IMASK);
@@ -209,7 +205,7 @@ struct kvm_vm *test_vm_create(void)
209205
vcpu_init_descriptor_tables(vcpus[i]);
210206

211207
test_init_timer_irq(vm);
212-
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
208+
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
213209
__TEST_REQUIRE(gic_fd >= 0, "Failed to create vgic-v3");
214210

215211
/* Make all the test's cmdline args visible to the guest */

tools/testing/selftests/kvm/aarch64/vgic_irq.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
#include "gic_v3.h"
2020
#include "vgic.h"
2121

22-
#define GICD_BASE_GPA 0x08000000ULL
23-
#define GICR_BASE_GPA 0x080A0000ULL
24-
2522
/*
2623
* Stores the user specified args; it's passed to the guest and to every test
2724
* function.
@@ -49,9 +46,6 @@ struct test_args {
4946
#define IRQ_DEFAULT_PRIO (LOWEST_PRIO - 1)
5047
#define IRQ_DEFAULT_PRIO_REG (IRQ_DEFAULT_PRIO << KVM_PRIO_SHIFT) /* 0xf0 */
5148

52-
static void *dist = (void *)GICD_BASE_GPA;
53-
static void *redist = (void *)GICR_BASE_GPA;
54-
5549
/*
5650
* The kvm_inject_* utilities are used by the guest to ask the host to inject
5751
* interrupts (e.g., using the KVM_IRQ_LINE ioctl).
@@ -478,7 +472,7 @@ static void guest_code(struct test_args *args)
478472
bool level_sensitive = args->level_sensitive;
479473
struct kvm_inject_desc *f, *inject_fns;
480474

481-
gic_init(GIC_V3, 1, dist, redist);
475+
gic_init(GIC_V3, 1);
482476

483477
for (i = 0; i < nr_irqs; i++)
484478
gic_irq_enable(i);
@@ -764,8 +758,7 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
764758
memcpy(addr_gva2hva(vm, args_gva), &args, sizeof(args));
765759
vcpu_args_set(vcpu, 1, args_gva);
766760

767-
gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
768-
GICD_BASE_GPA, GICR_BASE_GPA);
761+
gic_fd = vgic_v3_setup(vm, 1, nr_irqs);
769762
__TEST_REQUIRE(gic_fd >= 0, "Failed to create vgic-v3, skipping");
770763

771764
vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,

tools/testing/selftests/kvm/aarch64/vpmu_counter_access.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,6 @@ static void guest_code(uint64_t expected_pmcr_n)
404404
GUEST_DONE();
405405
}
406406

407-
#define GICD_BASE_GPA 0x8000000ULL
408-
#define GICR_BASE_GPA 0x80A0000ULL
409-
410407
/* Create a VM that has one vCPU with PMUv3 configured. */
411408
static void create_vpmu_vm(void *guest_code)
412409
{
@@ -438,8 +435,7 @@ static void create_vpmu_vm(void *guest_code)
438435
init.features[0] |= (1 << KVM_ARM_VCPU_PMU_V3);
439436
vpmu_vm.vcpu = aarch64_vcpu_add(vpmu_vm.vm, 0, &init, guest_code);
440437
vcpu_init_descriptor_tables(vpmu_vm.vcpu);
441-
vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64,
442-
GICD_BASE_GPA, GICR_BASE_GPA);
438+
vpmu_vm.gic_fd = vgic_v3_setup(vpmu_vm.vm, 1, 64);
443439
__TEST_REQUIRE(vpmu_vm.gic_fd >= 0,
444440
"Failed to create vgic-v3, skipping");
445441

tools/testing/selftests/kvm/dirty_log_perf_test.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
#ifdef __aarch64__
2323
#include "aarch64/vgic.h"
2424

25-
#define GICD_BASE_GPA 0x8000000ULL
26-
#define GICR_BASE_GPA 0x80A0000ULL
27-
2825
static int gic_fd;
2926

3027
static void arch_setup_vm(struct kvm_vm *vm, unsigned int nr_vcpus)
@@ -33,7 +30,7 @@ static void arch_setup_vm(struct kvm_vm *vm, unsigned int nr_vcpus)
3330
* The test can still run even if hardware does not support GICv3, as it
3431
* is only an optimization to reduce guest exits.
3532
*/
36-
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
33+
gic_fd = vgic_v3_setup(vm, nr_vcpus, 64);
3734
}
3835

3936
static void arch_cleanup_vm(struct kvm_vm *vm)

tools/testing/selftests/kvm/include/aarch64/gic.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@
66
#ifndef SELFTEST_KVM_GIC_H
77
#define SELFTEST_KVM_GIC_H
88

9+
#include <asm/kvm.h>
10+
911
enum gic_type {
1012
GIC_V3,
1113
GIC_TYPE_MAX,
1214
};
1315

16+
#define GICD_BASE_GPA 0x8000000ULL
17+
#define GICR_BASE_GPA (GICD_BASE_GPA + KVM_VGIC_V3_DIST_SIZE)
18+
19+
/* The GIC is identity-mapped into the guest at the time of setup. */
20+
#define GICD_BASE_GVA ((volatile void *)GICD_BASE_GPA)
21+
#define GICR_BASE_GVA ((volatile void *)GICR_BASE_GPA)
22+
1423
#define MIN_SGI 0
1524
#define MIN_PPI 16
1625
#define MIN_SPI 32
@@ -21,8 +30,7 @@ enum gic_type {
2130
#define INTID_IS_PPI(intid) (MIN_PPI <= (intid) && (intid) < MIN_SPI)
2231
#define INTID_IS_SPI(intid) (MIN_SPI <= (intid) && (intid) <= MAX_SPI)
2332

24-
void gic_init(enum gic_type type, unsigned int nr_cpus,
25-
void *dist_base, void *redist_base);
33+
void gic_init(enum gic_type type, unsigned int nr_cpus);
2634
void gic_irq_enable(unsigned int intid);
2735
void gic_irq_disable(unsigned int intid);
2836
unsigned int gic_get_and_ack_irq(void);

tools/testing/selftests/kvm/include/aarch64/vgic.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
((uint64_t)(flags) << 12) | \
1717
index)
1818

19-
int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
20-
uint64_t gicd_base_gpa, uint64_t gicr_base_gpa);
19+
int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs);
2120

2221
#define VGIC_MAX_RESERVED 1023
2322

tools/testing/selftests/kvm/lib/aarch64/gic.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
static const struct gic_common_ops *gic_common_ops;
1818
static struct spinlock gic_lock;
1919

20-
static void gic_cpu_init(unsigned int cpu, void *redist_base)
20+
static void gic_cpu_init(unsigned int cpu)
2121
{
22-
gic_common_ops->gic_cpu_init(cpu, redist_base);
22+
gic_common_ops->gic_cpu_init(cpu);
2323
}
2424

25-
static void
26-
gic_dist_init(enum gic_type type, unsigned int nr_cpus, void *dist_base)
25+
static void gic_dist_init(enum gic_type type, unsigned int nr_cpus)
2726
{
2827
const struct gic_common_ops *gic_ops = NULL;
2928

@@ -40,7 +39,7 @@ gic_dist_init(enum gic_type type, unsigned int nr_cpus, void *dist_base)
4039

4140
GUEST_ASSERT(gic_ops);
4241

43-
gic_ops->gic_init(nr_cpus, dist_base);
42+
gic_ops->gic_init(nr_cpus);
4443
gic_common_ops = gic_ops;
4544

4645
/* Make sure that the initialized data is visible to all the vCPUs */
@@ -49,18 +48,15 @@ gic_dist_init(enum gic_type type, unsigned int nr_cpus, void *dist_base)
4948
spin_unlock(&gic_lock);
5049
}
5150

52-
void gic_init(enum gic_type type, unsigned int nr_cpus,
53-
void *dist_base, void *redist_base)
51+
void gic_init(enum gic_type type, unsigned int nr_cpus)
5452
{
5553
uint32_t cpu = guest_get_vcpuid();
5654

5755
GUEST_ASSERT(type < GIC_TYPE_MAX);
58-
GUEST_ASSERT(dist_base);
59-
GUEST_ASSERT(redist_base);
6056
GUEST_ASSERT(nr_cpus);
6157

62-
gic_dist_init(type, nr_cpus, dist_base);
63-
gic_cpu_init(cpu, redist_base);
58+
gic_dist_init(type, nr_cpus);
59+
gic_cpu_init(cpu);
6460
}
6561

6662
void gic_irq_enable(unsigned int intid)

tools/testing/selftests/kvm/lib/aarch64/gic_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#define SELFTEST_KVM_GIC_PRIVATE_H
99

1010
struct gic_common_ops {
11-
void (*gic_init)(unsigned int nr_cpus, void *dist_base);
12-
void (*gic_cpu_init)(unsigned int cpu, void *redist_base);
11+
void (*gic_init)(unsigned int nr_cpus);
12+
void (*gic_cpu_init)(unsigned int cpu);
1313
void (*gic_irq_enable)(unsigned int intid);
1414
void (*gic_irq_disable)(unsigned int intid);
1515
uint64_t (*gic_read_iar)(void);

tools/testing/selftests/kvm/lib/aarch64/gic_v3.c

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#define ICC_PMR_DEF_PRIO 0xf0
2525

2626
struct gicv3_data {
27-
void *dist_base;
28-
void *redist_base[GICV3_MAX_CPUS];
2927
unsigned int nr_cpus;
3028
unsigned int nr_spis;
3129
};
@@ -46,17 +44,23 @@ static void gicv3_gicd_wait_for_rwp(void)
4644
{
4745
unsigned int count = 100000; /* 1s */
4846

49-
while (readl(gicv3_data.dist_base + GICD_CTLR) & GICD_CTLR_RWP) {
47+
while (readl(GICD_BASE_GVA + GICD_CTLR) & GICD_CTLR_RWP) {
5048
GUEST_ASSERT(count--);
5149
udelay(10);
5250
}
5351
}
5452

55-
static void gicv3_gicr_wait_for_rwp(void *redist_base)
53+
static inline volatile void *gicr_base_cpu(uint32_t cpu)
54+
{
55+
/* Align all the redistributors sequentially */
56+
return GICR_BASE_GVA + cpu * SZ_64K * 2;
57+
}
58+
59+
static void gicv3_gicr_wait_for_rwp(uint32_t cpu)
5660
{
5761
unsigned int count = 100000; /* 1s */
5862

59-
while (readl(redist_base + GICR_CTLR) & GICR_CTLR_RWP) {
63+
while (readl(gicr_base_cpu(cpu) + GICR_CTLR) & GICR_CTLR_RWP) {
6064
GUEST_ASSERT(count--);
6165
udelay(10);
6266
}
@@ -67,7 +71,7 @@ static void gicv3_wait_for_rwp(uint32_t cpu_or_dist)
6771
if (cpu_or_dist & DIST_BIT)
6872
gicv3_gicd_wait_for_rwp();
6973
else
70-
gicv3_gicr_wait_for_rwp(gicv3_data.redist_base[cpu_or_dist]);
74+
gicv3_gicr_wait_for_rwp(cpu_or_dist);
7175
}
7276

7377
static enum gicv3_intid_range get_intid_range(unsigned int intid)
@@ -127,15 +131,15 @@ static void gicv3_set_eoi_split(bool split)
127131

128132
uint32_t gicv3_reg_readl(uint32_t cpu_or_dist, uint64_t offset)
129133
{
130-
void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base
131-
: sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]);
134+
volatile void *base = cpu_or_dist & DIST_BIT ? GICD_BASE_GVA
135+
: sgi_base_from_redist(gicr_base_cpu(cpu_or_dist));
132136
return readl(base + offset);
133137
}
134138

135139
void gicv3_reg_writel(uint32_t cpu_or_dist, uint64_t offset, uint32_t reg_val)
136140
{
137-
void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base
138-
: sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]);
141+
volatile void *base = cpu_or_dist & DIST_BIT ? GICD_BASE_GVA
142+
: sgi_base_from_redist(gicr_base_cpu(cpu_or_dist));
139143
writel(reg_val, base + offset);
140144
}
141145

@@ -274,7 +278,7 @@ static bool gicv3_irq_get_pending(uint32_t intid)
274278
return gicv3_read_reg(intid, GICD_ISPENDR, 32, 1);
275279
}
276280

277-
static void gicv3_enable_redist(void *redist_base)
281+
static void gicv3_enable_redist(volatile void *redist_base)
278282
{
279283
uint32_t val = readl(redist_base + GICR_WAKER);
280284
unsigned int count = 100000; /* 1s */
@@ -289,21 +293,15 @@ static void gicv3_enable_redist(void *redist_base)
289293
}
290294
}
291295

292-
static inline void *gicr_base_cpu(void *redist_base, uint32_t cpu)
296+
static void gicv3_cpu_init(unsigned int cpu)
293297
{
294-
/* Align all the redistributors sequentially */
295-
return redist_base + cpu * SZ_64K * 2;
296-
}
297-
298-
static void gicv3_cpu_init(unsigned int cpu, void *redist_base)
299-
{
300-
void *sgi_base;
298+
volatile void *sgi_base;
301299
unsigned int i;
302-
void *redist_base_cpu;
300+
volatile void *redist_base_cpu;
303301

304302
GUEST_ASSERT(cpu < gicv3_data.nr_cpus);
305303

306-
redist_base_cpu = gicr_base_cpu(redist_base, cpu);
304+
redist_base_cpu = gicr_base_cpu(cpu);
307305
sgi_base = sgi_base_from_redist(redist_base_cpu);
308306

309307
gicv3_enable_redist(redist_base_cpu);
@@ -321,7 +319,7 @@ static void gicv3_cpu_init(unsigned int cpu, void *redist_base)
321319
writel(GICD_INT_DEF_PRI_X4,
322320
sgi_base + GICR_IPRIORITYR0 + i);
323321

324-
gicv3_gicr_wait_for_rwp(redist_base_cpu);
322+
gicv3_gicr_wait_for_rwp(cpu);
325323

326324
/* Enable the GIC system register (ICC_*) access */
327325
write_sysreg_s(read_sysreg_s(SYS_ICC_SRE_EL1) | ICC_SRE_EL1_SRE,
@@ -332,51 +330,47 @@ static void gicv3_cpu_init(unsigned int cpu, void *redist_base)
332330

333331
/* Enable non-secure Group-1 interrupts */
334332
write_sysreg_s(ICC_IGRPEN1_EL1_MASK, SYS_ICC_IGRPEN1_EL1);
335-
336-
gicv3_data.redist_base[cpu] = redist_base_cpu;
337333
}
338334

339335
static void gicv3_dist_init(void)
340336
{
341-
void *dist_base = gicv3_data.dist_base;
342337
unsigned int i;
343338

344339
/* Disable the distributor until we set things up */
345-
writel(0, dist_base + GICD_CTLR);
340+
writel(0, GICD_BASE_GVA + GICD_CTLR);
346341
gicv3_gicd_wait_for_rwp();
347342

348343
/*
349344
* Mark all the SPI interrupts as non-secure Group-1.
350345
* Also, deactivate and disable them.
351346
*/
352347
for (i = 32; i < gicv3_data.nr_spis; i += 32) {
353-
writel(~0, dist_base + GICD_IGROUPR + i / 8);
354-
writel(~0, dist_base + GICD_ICACTIVER + i / 8);
355-
writel(~0, dist_base + GICD_ICENABLER + i / 8);
348+
writel(~0, GICD_BASE_GVA + GICD_IGROUPR + i / 8);
349+
writel(~0, GICD_BASE_GVA + GICD_ICACTIVER + i / 8);
350+
writel(~0, GICD_BASE_GVA + GICD_ICENABLER + i / 8);
356351
}
357352

358353
/* Set a default priority for all the SPIs */
359354
for (i = 32; i < gicv3_data.nr_spis; i += 4)
360355
writel(GICD_INT_DEF_PRI_X4,
361-
dist_base + GICD_IPRIORITYR + i);
356+
GICD_BASE_GVA + GICD_IPRIORITYR + i);
362357

363358
/* Wait for the settings to sync-in */
364359
gicv3_gicd_wait_for_rwp();
365360

366361
/* Finally, enable the distributor globally with ARE */
367362
writel(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A |
368-
GICD_CTLR_ENABLE_G1, dist_base + GICD_CTLR);
363+
GICD_CTLR_ENABLE_G1, GICD_BASE_GVA + GICD_CTLR);
369364
gicv3_gicd_wait_for_rwp();
370365
}
371366

372-
static void gicv3_init(unsigned int nr_cpus, void *dist_base)
367+
static void gicv3_init(unsigned int nr_cpus)
373368
{
374369
GUEST_ASSERT(nr_cpus <= GICV3_MAX_CPUS);
375370

376371
gicv3_data.nr_cpus = nr_cpus;
377-
gicv3_data.dist_base = dist_base;
378372
gicv3_data.nr_spis = GICD_TYPER_SPIS(
379-
readl(gicv3_data.dist_base + GICD_TYPER));
373+
readl(GICD_BASE_GVA + GICD_TYPER));
380374
if (gicv3_data.nr_spis > 1020)
381375
gicv3_data.nr_spis = 1020;
382376

0 commit comments

Comments
 (0)