@@ -39,7 +39,13 @@ static bool illegal_handler_invoked;
39
39
#define SBI_PMU_TEST_SNAPSHOT BIT(2)
40
40
#define SBI_PMU_TEST_OVERFLOW BIT(3)
41
41
42
- static int disabled_tests ;
42
+ #define SBI_PMU_OVERFLOW_IRQNUM_DEFAULT 5
43
+ struct test_args {
44
+ int disabled_tests ;
45
+ int overflow_irqnum ;
46
+ };
47
+
48
+ static struct test_args targs ;
43
49
44
50
unsigned long pmu_csr_read_num (int csr_num )
45
51
{
@@ -118,8 +124,8 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
118
124
119
125
ret = sbi_ecall (SBI_EXT_PMU , SBI_EXT_PMU_COUNTER_STOP , counter , 1 , stop_flags ,
120
126
0 , 0 , 0 );
121
- __GUEST_ASSERT (ret .error == 0 , "Unable to stop counter %ld error %ld\n" ,
122
- counter , ret .error );
127
+ __GUEST_ASSERT (ret .error == 0 || ret . error == SBI_ERR_ALREADY_STOPPED ,
128
+ "Unable to stop counter %ld error %ld\n" , counter , ret .error );
123
129
}
124
130
125
131
static void guest_illegal_exception_handler (struct ex_regs * regs )
@@ -137,7 +143,6 @@ static void guest_irq_handler(struct ex_regs *regs)
137
143
unsigned int irq_num = regs -> cause & ~CAUSE_IRQ_FLAG ;
138
144
struct riscv_pmu_snapshot_data * snapshot_data = snapshot_gva ;
139
145
unsigned long overflown_mask ;
140
- unsigned long counter_val = 0 ;
141
146
142
147
/* Validate that we are in the correct irq handler */
143
148
GUEST_ASSERT_EQ (irq_num , IRQ_PMU_OVF );
@@ -151,10 +156,6 @@ static void guest_irq_handler(struct ex_regs *regs)
151
156
GUEST_ASSERT (overflown_mask & 0x01 );
152
157
153
158
WRITE_ONCE (vcpu_shared_irq_count , vcpu_shared_irq_count + 1 );
154
-
155
- counter_val = READ_ONCE (snapshot_data -> ctr_values [0 ]);
156
- /* Now start the counter to mimick the real driver behavior */
157
- start_counter (counter_in_use , SBI_PMU_START_FLAG_SET_INIT_VALUE , counter_val );
158
159
}
159
160
160
161
static unsigned long get_counter_index (unsigned long cbase , unsigned long cmask ,
@@ -479,7 +480,7 @@ static void test_pmu_events_snaphost(void)
479
480
480
481
static void test_pmu_events_overflow (void )
481
482
{
482
- int num_counters = 0 ;
483
+ int num_counters = 0 , i = 0 ;
483
484
484
485
/* Verify presence of SBI PMU and minimum requrired SBI version */
485
486
verify_sbi_requirement_assert ();
@@ -496,11 +497,15 @@ static void test_pmu_events_overflow(void)
496
497
* Qemu supports overflow for cycle/instruction.
497
498
* This test may fail on any platform that do not support overflow for these two events.
498
499
*/
499
- test_pmu_event_overflow (SBI_PMU_HW_CPU_CYCLES );
500
- GUEST_ASSERT_EQ (vcpu_shared_irq_count , 1 );
500
+ for (i = 0 ; i < targs .overflow_irqnum ; i ++ )
501
+ test_pmu_event_overflow (SBI_PMU_HW_CPU_CYCLES );
502
+ GUEST_ASSERT_EQ (vcpu_shared_irq_count , targs .overflow_irqnum );
503
+
504
+ vcpu_shared_irq_count = 0 ;
501
505
502
- test_pmu_event_overflow (SBI_PMU_HW_INSTRUCTIONS );
503
- GUEST_ASSERT_EQ (vcpu_shared_irq_count , 2 );
506
+ for (i = 0 ; i < targs .overflow_irqnum ; i ++ )
507
+ test_pmu_event_overflow (SBI_PMU_HW_INSTRUCTIONS );
508
+ GUEST_ASSERT_EQ (vcpu_shared_irq_count , targs .overflow_irqnum );
504
509
505
510
GUEST_DONE ();
506
511
}
@@ -609,7 +614,11 @@ static void test_vm_events_overflow(void *guest_code)
609
614
vcpu_init_vector_tables (vcpu );
610
615
/* Initialize guest timer frequency. */
611
616
timer_freq = vcpu_get_reg (vcpu , RISCV_TIMER_REG (frequency ));
617
+
618
+ /* Export the shared variables to the guest */
612
619
sync_global_to_guest (vm , timer_freq );
620
+ sync_global_to_guest (vm , vcpu_shared_irq_count );
621
+ sync_global_to_guest (vm , targs );
613
622
614
623
run_vcpu (vcpu );
615
624
@@ -618,35 +627,54 @@ static void test_vm_events_overflow(void *guest_code)
618
627
619
628
static void test_print_help (char * name )
620
629
{
621
- pr_info ("Usage: %s [-h] [-d <test name>]\n" , name );
622
- pr_info ("\t-d: Test to disable. Available tests are 'basic', 'events', 'snapshot', 'overflow'\n" );
630
+ pr_info ("Usage: %s [-h] [-t <test name>] [-n <number of LCOFI interrupt for overflow test>]\n" ,
631
+ name );
632
+ pr_info ("\t-t: Test to run (default all). Available tests are 'basic', 'events', 'snapshot', 'overflow'\n" );
633
+ pr_info ("\t-n: Number of LCOFI interrupt to trigger for each event in overflow test (default: %d)\n" ,
634
+ SBI_PMU_OVERFLOW_IRQNUM_DEFAULT );
623
635
pr_info ("\t-h: print this help screen\n" );
624
636
}
625
637
626
638
static bool parse_args (int argc , char * argv [])
627
639
{
628
640
int opt ;
641
+ int temp_disabled_tests = SBI_PMU_TEST_BASIC | SBI_PMU_TEST_EVENTS | SBI_PMU_TEST_SNAPSHOT |
642
+ SBI_PMU_TEST_OVERFLOW ;
643
+ int overflow_interrupts = 0 ;
629
644
630
- while ((opt = getopt (argc , argv , "hd :" )) != -1 ) {
645
+ while ((opt = getopt (argc , argv , "ht:n :" )) != -1 ) {
631
646
switch (opt ) {
632
- case 'd ' :
647
+ case 't ' :
633
648
if (!strncmp ("basic" , optarg , 5 ))
634
- disabled_tests |= SBI_PMU_TEST_BASIC ;
649
+ temp_disabled_tests &= ~ SBI_PMU_TEST_BASIC ;
635
650
else if (!strncmp ("events" , optarg , 6 ))
636
- disabled_tests |= SBI_PMU_TEST_EVENTS ;
651
+ temp_disabled_tests &= ~ SBI_PMU_TEST_EVENTS ;
637
652
else if (!strncmp ("snapshot" , optarg , 8 ))
638
- disabled_tests |= SBI_PMU_TEST_SNAPSHOT ;
653
+ temp_disabled_tests &= ~ SBI_PMU_TEST_SNAPSHOT ;
639
654
else if (!strncmp ("overflow" , optarg , 8 ))
640
- disabled_tests |= SBI_PMU_TEST_OVERFLOW ;
655
+ temp_disabled_tests &= ~ SBI_PMU_TEST_OVERFLOW ;
641
656
else
642
657
goto done ;
658
+ targs .disabled_tests = temp_disabled_tests ;
659
+ break ;
660
+ case 'n' :
661
+ overflow_interrupts = atoi_positive ("Number of LCOFI" , optarg );
643
662
break ;
644
663
case 'h' :
645
664
default :
646
665
goto done ;
647
666
}
648
667
}
649
668
669
+ if (overflow_interrupts > 0 ) {
670
+ if (targs .disabled_tests & SBI_PMU_TEST_OVERFLOW ) {
671
+ pr_info ("-n option is only available for overflow test\n" );
672
+ goto done ;
673
+ } else {
674
+ targs .overflow_irqnum = overflow_interrupts ;
675
+ }
676
+ }
677
+
650
678
return true;
651
679
done :
652
680
test_print_help (argv [0 ]);
@@ -655,25 +683,28 @@ static bool parse_args(int argc, char *argv[])
655
683
656
684
int main (int argc , char * argv [])
657
685
{
686
+ targs .disabled_tests = 0 ;
687
+ targs .overflow_irqnum = SBI_PMU_OVERFLOW_IRQNUM_DEFAULT ;
688
+
658
689
if (!parse_args (argc , argv ))
659
690
exit (KSFT_SKIP );
660
691
661
- if (!(disabled_tests & SBI_PMU_TEST_BASIC )) {
692
+ if (!(targs . disabled_tests & SBI_PMU_TEST_BASIC )) {
662
693
test_vm_basic_test (test_pmu_basic_sanity );
663
694
pr_info ("SBI PMU basic test : PASS\n" );
664
695
}
665
696
666
- if (!(disabled_tests & SBI_PMU_TEST_EVENTS )) {
697
+ if (!(targs . disabled_tests & SBI_PMU_TEST_EVENTS )) {
667
698
test_vm_events_test (test_pmu_events );
668
699
pr_info ("SBI PMU event verification test : PASS\n" );
669
700
}
670
701
671
- if (!(disabled_tests & SBI_PMU_TEST_SNAPSHOT )) {
702
+ if (!(targs . disabled_tests & SBI_PMU_TEST_SNAPSHOT )) {
672
703
test_vm_events_snapshot_test (test_pmu_events_snaphost );
673
704
pr_info ("SBI PMU event verification with snapshot test : PASS\n" );
674
705
}
675
706
676
- if (!(disabled_tests & SBI_PMU_TEST_OVERFLOW )) {
707
+ if (!(targs . disabled_tests & SBI_PMU_TEST_OVERFLOW )) {
677
708
test_vm_events_overflow (test_pmu_events_overflow );
678
709
pr_info ("SBI PMU event verification with overflow test : PASS\n" );
679
710
}
0 commit comments