Skip to content

Commit c44df5f

Browse files
Ricardo KollerMarc Zyngier
authored andcommitted
KVM: arm64: selftests: Add some tests for GICv2 in vgic_init
Add some GICv2 tests: general KVM device tests and DIST/CPUIF overlap tests. Do this by making test_vcpus_then_vgic and test_vgic_then_vcpus in vgic_init GIC version agnostic. Signed-off-by: Ricardo Koller <[email protected]> Reviewed-by: Eric Auger <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 46fb941 commit c44df5f

File tree

1 file changed

+79
-32
lines changed

1 file changed

+79
-32
lines changed

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

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -79,74 +79,120 @@ static void vm_gic_destroy(struct vm_gic *v)
7979
kvm_vm_free(v->vm);
8080
}
8181

82+
struct vgic_region_attr {
83+
uint64_t attr;
84+
uint64_t size;
85+
uint64_t alignment;
86+
};
87+
88+
struct vgic_region_attr gic_v3_dist_region = {
89+
.attr = KVM_VGIC_V3_ADDR_TYPE_DIST,
90+
.size = 0x10000,
91+
.alignment = 0x10000,
92+
};
93+
94+
struct vgic_region_attr gic_v3_redist_region = {
95+
.attr = KVM_VGIC_V3_ADDR_TYPE_REDIST,
96+
.size = NR_VCPUS * 0x20000,
97+
.alignment = 0x10000,
98+
};
99+
100+
struct vgic_region_attr gic_v2_dist_region = {
101+
.attr = KVM_VGIC_V2_ADDR_TYPE_DIST,
102+
.size = 0x1000,
103+
.alignment = 0x1000,
104+
};
105+
106+
struct vgic_region_attr gic_v2_cpu_region = {
107+
.attr = KVM_VGIC_V2_ADDR_TYPE_CPU,
108+
.size = 0x2000,
109+
.alignment = 0x1000,
110+
};
111+
82112
/**
83-
* Helper routine that performs KVM device tests in general and
84-
* especially ARM_VGIC_V3 ones. Eventually the ARM_VGIC_V3
85-
* device gets created, a legacy RDIST region is set at @0x0
86-
* and a DIST region is set @0x60000
113+
* Helper routine that performs KVM device tests in general. Eventually the
114+
* ARM_VGIC (GICv2 or GICv3) device gets created with an overlapping
115+
* DIST/REDIST (or DIST/CPUIF for GICv2). Assumption is 4 vcpus are going to be
116+
* used hence the overlap. In the case of GICv3, A RDIST region is set at @0x0
117+
* and a DIST region is set @0x70000. The GICv2 case sets a CPUIF @0x0 and a
118+
* DIST region @0x1000.
87119
*/
88-
static void subtest_v3_dist_rdist(struct vm_gic *v)
120+
static void subtest_dist_rdist(struct vm_gic *v)
89121
{
90122
int ret;
91123
uint64_t addr;
124+
struct vgic_region_attr rdist; /* CPU interface in GICv2*/
125+
struct vgic_region_attr dist;
126+
127+
rdist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_redist_region
128+
: gic_v2_cpu_region;
129+
dist = VGIC_DEV_IS_V3(v->gic_dev_type) ? gic_v3_dist_region
130+
: gic_v2_dist_region;
92131

93132
/* Check existing group/attributes */
94133
kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
95-
KVM_VGIC_V3_ADDR_TYPE_DIST);
134+
dist.attr);
96135

97136
kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
98-
KVM_VGIC_V3_ADDR_TYPE_REDIST);
137+
rdist.attr);
99138

100139
/* check non existing attribute */
101-
ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, 0);
140+
ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, -1);
102141
TEST_ASSERT(ret && errno == ENXIO, "attribute not supported");
103142

104143
/* misaligned DIST and REDIST address settings */
105-
addr = 0x1000;
144+
addr = dist.alignment / 0x10;
106145
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
107-
KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
108-
TEST_ASSERT(ret && errno == EINVAL, "GICv3 dist base not 64kB aligned");
146+
dist.attr, &addr, true);
147+
TEST_ASSERT(ret && errno == EINVAL, "GIC dist base not aligned");
109148

149+
addr = rdist.alignment / 0x10;
110150
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
111-
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
112-
TEST_ASSERT(ret && errno == EINVAL, "GICv3 redist base not 64kB aligned");
151+
rdist.attr, &addr, true);
152+
TEST_ASSERT(ret && errno == EINVAL, "GIC redist/cpu base not aligned");
113153

114154
/* out of range address */
115155
if (max_ipa_bits) {
116156
addr = 1ULL << max_ipa_bits;
117157
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
118-
KVM_VGIC_V3_ADDR_TYPE_DIST, &addr, true);
158+
dist.attr, &addr, true);
119159
TEST_ASSERT(ret && errno == E2BIG, "dist address beyond IPA limit");
120160

121161
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
122-
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
162+
rdist.attr, &addr, true);
123163
TEST_ASSERT(ret && errno == E2BIG, "redist address beyond IPA limit");
124164
}
125165

126166
/* set REDIST base address @0x0*/
127167
addr = 0x00000;
128168
kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
129-
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
169+
rdist.attr, &addr, true);
130170

131171
/* Attempt to create a second legacy redistributor region */
132172
addr = 0xE0000;
133173
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
134-
KVM_VGIC_V3_ADDR_TYPE_REDIST, &addr, true);
135-
TEST_ASSERT(ret && errno == EEXIST, "GICv3 redist base set again");
174+
rdist.attr, &addr, true);
175+
TEST_ASSERT(ret && errno == EEXIST, "GIC redist base set again");
136176

137-
/* Attempt to mix legacy and new redistributor regions */
138-
addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 0, 0);
139-
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
140-
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION, &addr, true);
141-
TEST_ASSERT(ret && errno == EINVAL, "attempt to mix GICv3 REDIST and REDIST_REGION");
177+
ret = _kvm_device_check_attr(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
178+
KVM_VGIC_V3_ADDR_TYPE_REDIST);
179+
if (!ret) {
180+
/* Attempt to mix legacy and new redistributor regions */
181+
addr = REDIST_REGION_ATTR_ADDR(NR_VCPUS, 0x100000, 0, 0);
182+
ret = _kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
183+
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
184+
&addr, true);
185+
TEST_ASSERT(ret && errno == EINVAL,
186+
"attempt to mix GICv3 REDIST and REDIST_REGION");
187+
}
142188

143189
/*
144190
* Set overlapping DIST / REDIST, cannot be detected here. Will be detected
145191
* on first vcpu run instead.
146192
*/
147-
addr = 3 * 2 * 0x10000;
148-
kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST,
149-
&addr, true);
193+
addr = rdist.size - rdist.alignment;
194+
kvm_device_access(v->gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
195+
dist.attr, &addr, true);
150196
}
151197

152198
/* Test the new REDIST region API */
@@ -254,14 +300,14 @@ static void subtest_v3_redist_regions(struct vm_gic *v)
254300
* VGIC KVM device is created and initialized before the secondary CPUs
255301
* get created
256302
*/
257-
static void test_v3_vgic_then_vcpus(uint32_t gic_dev_type)
303+
static void test_vgic_then_vcpus(uint32_t gic_dev_type)
258304
{
259305
struct vm_gic v;
260306
int ret, i;
261307

262308
v = vm_gic_create_with_vcpus(gic_dev_type, 1);
263309

264-
subtest_v3_dist_rdist(&v);
310+
subtest_dist_rdist(&v);
265311

266312
/* Add the rest of the VCPUs */
267313
for (i = 1; i < NR_VCPUS; ++i)
@@ -274,14 +320,14 @@ static void test_v3_vgic_then_vcpus(uint32_t gic_dev_type)
274320
}
275321

276322
/* All the VCPUs are created before the VGIC KVM device gets initialized */
277-
static void test_v3_vcpus_then_vgic(uint32_t gic_dev_type)
323+
static void test_vcpus_then_vgic(uint32_t gic_dev_type)
278324
{
279325
struct vm_gic v;
280326
int ret;
281327

282328
v = vm_gic_create_with_vcpus(gic_dev_type, NR_VCPUS);
283329

284-
subtest_v3_dist_rdist(&v);
330+
subtest_dist_rdist(&v);
285331

286332
ret = run_vcpu(v.vm, 3);
287333
TEST_ASSERT(ret == -EINVAL, "dist/rdist overlap detected on 1st vcpu run");
@@ -550,9 +596,10 @@ int test_kvm_device(uint32_t gic_dev_type)
550596

551597
void run_tests(uint32_t gic_dev_type)
552598
{
599+
test_vcpus_then_vgic(gic_dev_type);
600+
test_vgic_then_vcpus(gic_dev_type);
601+
553602
if (VGIC_DEV_IS_V3(gic_dev_type)) {
554-
test_v3_vcpus_then_vgic(gic_dev_type);
555-
test_v3_vgic_then_vcpus(gic_dev_type);
556603
test_v3_new_redist_regions();
557604
test_v3_typer_accesses();
558605
test_v3_last_bit_redist_regions();

0 commit comments

Comments
 (0)