Skip to content

Commit fad4cf9

Browse files
Sebastian OttMarc Zyngier
authored andcommitted
KVM: arm64: selftests: Determine effective counter width in arch_timer_edge_cases
arch_timer_edge_cases uses ~0 as the maximum counter value, however there's no architectural guarantee that this is valid. Figure out the effective counter width based on the effective frequency like it's done by the kernel. This also serves as a workaround for AC03_CPU_14 that led to the following assertion failure on ampere-one machines: ==== Test Assertion Failure ==== arm64/arch_timer_edge_cases.c:169: timer_condition == istatus pid=11236 tid=11236 errno=4 - Interrupted system call 1 0x0000000000404ce7: test_run at arch_timer_edge_cases.c:938 2 0x0000000000401ebb: main at arch_timer_edge_cases.c:1053 3 0x0000ffff9fa8625b: ?? ??:0 4 0x0000ffff9fa8633b: ?? ??:0 5 0x0000000000401fef: _start at ??:? 0x1 != 0x0 (timer_condition != istatus) Note that the following subtest only worked since the counter initialized with CVAL_MAX would instantly overflow (which is no longer the case): test_set_cnt_after_cval_no_irq(timer, 0, DEF_CNT, CVAL_MAX, sm); To fix this we could swap CVAL_MAX for 0 here but since that is already done by test_move_counters_behind_timers() let's remove that subtest. Link: https://lore.kernel.org/kvmarm/[email protected] Link: https://amperecomputing.com/assets/AmpereOne_Developer_ER_v0_80_20240823_28945022f4.pdf Signed-off-by: Sebastian Ott <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 05ce38d commit fad4cf9

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,17 @@
2222
#include "gic.h"
2323
#include "vgic.h"
2424

25-
static const uint64_t CVAL_MAX = ~0ULL;
25+
/* Depends on counter width. */
26+
static uint64_t CVAL_MAX;
2627
/* tval is a signed 32-bit int. */
2728
static const int32_t TVAL_MAX = INT32_MAX;
2829
static const int32_t TVAL_MIN = INT32_MIN;
2930

3031
/* After how much time we say there is no IRQ. */
3132
static const uint32_t TIMEOUT_NO_IRQ_US = 50000;
3233

33-
/* A nice counter value to use as the starting one for most tests. */
34-
static const uint64_t DEF_CNT = (CVAL_MAX / 2);
34+
/* Counter value to use as the starting one for most tests. Set to CVAL_MAX/2 */
35+
static uint64_t DEF_CNT;
3536

3637
/* Number of runs. */
3738
static const uint32_t NR_TEST_ITERS_DEF = 5;
@@ -732,12 +733,6 @@ static void test_move_counters_ahead_of_timers(enum arch_timer timer)
732733
test_set_cnt_after_tval(timer, 0, tval, (uint64_t) tval + 1,
733734
wm);
734735
}
735-
736-
for (i = 0; i < ARRAY_SIZE(sleep_method); i++) {
737-
sleep_method_t sm = sleep_method[i];
738-
739-
test_set_cnt_after_cval_no_irq(timer, 0, DEF_CNT, CVAL_MAX, sm);
740-
}
741736
}
742737

743738
/*
@@ -975,6 +970,8 @@ static void test_vm_create(struct kvm_vm **vm, struct kvm_vcpu **vcpu,
975970
test_init_timer_irq(*vm, *vcpu);
976971
vgic_v3_setup(*vm, 1, 64);
977972
sync_global_to_guest(*vm, test_args);
973+
sync_global_to_guest(*vm, CVAL_MAX);
974+
sync_global_to_guest(*vm, DEF_CNT);
978975
}
979976

980977
static void test_print_help(char *name)
@@ -1035,6 +1032,17 @@ static bool parse_args(int argc, char *argv[])
10351032
return false;
10361033
}
10371034

1035+
static void set_counter_defaults(void)
1036+
{
1037+
const uint64_t MIN_ROLLOVER_SECS = 40ULL * 365 * 24 * 3600;
1038+
uint64_t freq = read_sysreg(CNTFRQ_EL0);
1039+
uint64_t width = ilog2(MIN_ROLLOVER_SECS * freq);
1040+
1041+
width = clamp(width, 56, 64);
1042+
CVAL_MAX = GENMASK_ULL(width - 1, 0);
1043+
DEF_CNT = CVAL_MAX / 2;
1044+
}
1045+
10381046
int main(int argc, char *argv[])
10391047
{
10401048
struct kvm_vcpu *vcpu;
@@ -1047,6 +1055,7 @@ int main(int argc, char *argv[])
10471055
exit(KSFT_SKIP);
10481056

10491057
sched_getaffinity(0, sizeof(default_cpuset), &default_cpuset);
1058+
set_counter_defaults();
10501059

10511060
if (test_args.test_virtual) {
10521061
test_vm_create(&vm, &vcpu, VIRTUAL);

0 commit comments

Comments
 (0)