@@ -2087,12 +2087,37 @@ static const struct sys_reg_desc cp15_64_regs[] = {
2087
2087
{ SYS_DESC (SYS_AARCH32_CNTP_CVAL ), access_arch_timer },
2088
2088
};
2089
2089
2090
+ static int check_sysreg_table (const struct sys_reg_desc * table , unsigned int n ,
2091
+ bool is_32 )
2092
+ {
2093
+ unsigned int i ;
2094
+
2095
+ for (i = 0 ; i < n ; i ++ ) {
2096
+ if (!is_32 && table [i ].reg && !table [i ].reset ) {
2097
+ kvm_err ("sys_reg table %p entry %d has lacks reset\n" ,
2098
+ table , i );
2099
+ return 1 ;
2100
+ }
2101
+
2102
+ if (i && cmp_sys_reg (& table [i - 1 ], & table [i ]) >= 0 ) {
2103
+ kvm_err ("sys_reg table %p out of order (%d)\n" , table , i - 1 );
2104
+ return 1 ;
2105
+ }
2106
+ }
2107
+
2108
+ return 0 ;
2109
+ }
2110
+
2090
2111
/* Target specific emulation tables */
2091
2112
static struct kvm_sys_reg_target_table * target_tables [KVM_ARM_NUM_TARGETS ];
2092
2113
2093
2114
void kvm_register_target_sys_reg_table (unsigned int target ,
2094
2115
struct kvm_sys_reg_target_table * table )
2095
2116
{
2117
+ if (check_sysreg_table (table -> table64 .table , table -> table64 .num , false) ||
2118
+ check_sysreg_table (table -> table32 .table , table -> table32 .num , true))
2119
+ return ;
2120
+
2096
2121
target_tables [target ] = table ;
2097
2122
}
2098
2123
@@ -2378,19 +2403,13 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
2378
2403
}
2379
2404
2380
2405
static void reset_sys_reg_descs (struct kvm_vcpu * vcpu ,
2381
- const struct sys_reg_desc * table , size_t num ,
2382
- unsigned long * bmap )
2406
+ const struct sys_reg_desc * table , size_t num )
2383
2407
{
2384
2408
unsigned long i ;
2385
2409
2386
2410
for (i = 0 ; i < num ; i ++ )
2387
- if (table [i ].reset ) {
2388
- int reg = table [i ].reg ;
2389
-
2411
+ if (table [i ].reset )
2390
2412
table [i ].reset (vcpu , & table [i ]);
2391
- if (reg > 0 && reg < NR_SYS_REGS )
2392
- set_bit (reg , bmap );
2393
- }
2394
2413
}
2395
2414
2396
2415
/**
@@ -2846,32 +2865,18 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
2846
2865
return write_demux_regids (uindices );
2847
2866
}
2848
2867
2849
- static int check_sysreg_table (const struct sys_reg_desc * table , unsigned int n )
2850
- {
2851
- unsigned int i ;
2852
-
2853
- for (i = 1 ; i < n ; i ++ ) {
2854
- if (cmp_sys_reg (& table [i - 1 ], & table [i ]) >= 0 ) {
2855
- kvm_err ("sys_reg table %p out of order (%d)\n" , table , i - 1 );
2856
- return 1 ;
2857
- }
2858
- }
2859
-
2860
- return 0 ;
2861
- }
2862
-
2863
2868
void kvm_sys_reg_table_init (void )
2864
2869
{
2865
2870
unsigned int i ;
2866
2871
struct sys_reg_desc clidr ;
2867
2872
2868
2873
/* Make sure tables are unique and in order. */
2869
- BUG_ON (check_sysreg_table (sys_reg_descs , ARRAY_SIZE (sys_reg_descs )));
2870
- BUG_ON (check_sysreg_table (cp14_regs , ARRAY_SIZE (cp14_regs )));
2871
- BUG_ON (check_sysreg_table (cp14_64_regs , ARRAY_SIZE (cp14_64_regs )));
2872
- BUG_ON (check_sysreg_table (cp15_regs , ARRAY_SIZE (cp15_regs )));
2873
- BUG_ON (check_sysreg_table (cp15_64_regs , ARRAY_SIZE (cp15_64_regs )));
2874
- BUG_ON (check_sysreg_table (invariant_sys_regs , ARRAY_SIZE (invariant_sys_regs )));
2874
+ BUG_ON (check_sysreg_table (sys_reg_descs , ARRAY_SIZE (sys_reg_descs ), false ));
2875
+ BUG_ON (check_sysreg_table (cp14_regs , ARRAY_SIZE (cp14_regs ), true ));
2876
+ BUG_ON (check_sysreg_table (cp14_64_regs , ARRAY_SIZE (cp14_64_regs ), true ));
2877
+ BUG_ON (check_sysreg_table (cp15_regs , ARRAY_SIZE (cp15_regs ), true ));
2878
+ BUG_ON (check_sysreg_table (cp15_64_regs , ARRAY_SIZE (cp15_64_regs ), true ));
2879
+ BUG_ON (check_sysreg_table (invariant_sys_regs , ARRAY_SIZE (invariant_sys_regs ), false ));
2875
2880
2876
2881
/* We abuse the reset function to overwrite the table itself. */
2877
2882
for (i = 0 ; i < ARRAY_SIZE (invariant_sys_regs ); i ++ )
@@ -2907,17 +2912,10 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
2907
2912
{
2908
2913
size_t num ;
2909
2914
const struct sys_reg_desc * table ;
2910
- DECLARE_BITMAP (bmap , NR_SYS_REGS ) = { 0 , };
2911
2915
2912
2916
/* Generic chip reset first (so target could override). */
2913
- reset_sys_reg_descs (vcpu , sys_reg_descs , ARRAY_SIZE (sys_reg_descs ), bmap );
2917
+ reset_sys_reg_descs (vcpu , sys_reg_descs , ARRAY_SIZE (sys_reg_descs ));
2914
2918
2915
2919
table = get_target_table (vcpu -> arch .target , true, & num );
2916
- reset_sys_reg_descs (vcpu , table , num , bmap );
2917
-
2918
- for (num = 1 ; num < NR_SYS_REGS ; num ++ ) {
2919
- if (WARN (!test_bit (num , bmap ),
2920
- "Didn't reset __vcpu_sys_reg(%zi)\n" , num ))
2921
- break ;
2922
- }
2920
+ reset_sys_reg_descs (vcpu , table , num );
2923
2921
}
0 commit comments