@@ -154,9 +154,6 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
154154
155155 va55 = va & BIT (55 );
156156
157- if (wi -> regime == TR_EL2 && va55 )
158- goto addrsz ;
159-
160157 wi -> s2 = wi -> regime == TR_EL10 && (hcr & (HCR_VM | HCR_DC ));
161158
162159 switch (wi -> regime ) {
@@ -179,6 +176,46 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
179176 BUG ();
180177 }
181178
179+ /* Someone was silly enough to encode TG0/TG1 differently */
180+ if (va55 && wi -> regime != TR_EL2 ) {
181+ wi -> txsz = FIELD_GET (TCR_T1SZ_MASK , tcr );
182+ tg = FIELD_GET (TCR_TG1_MASK , tcr );
183+
184+ switch (tg << TCR_TG1_SHIFT ) {
185+ case TCR_TG1_4K :
186+ wi -> pgshift = 12 ; break ;
187+ case TCR_TG1_16K :
188+ wi -> pgshift = 14 ; break ;
189+ case TCR_TG1_64K :
190+ default : /* IMPDEF: treat any other value as 64k */
191+ wi -> pgshift = 16 ; break ;
192+ }
193+ } else {
194+ wi -> txsz = FIELD_GET (TCR_T0SZ_MASK , tcr );
195+ tg = FIELD_GET (TCR_TG0_MASK , tcr );
196+
197+ switch (tg << TCR_TG0_SHIFT ) {
198+ case TCR_TG0_4K :
199+ wi -> pgshift = 12 ; break ;
200+ case TCR_TG0_16K :
201+ wi -> pgshift = 14 ; break ;
202+ case TCR_TG0_64K :
203+ default : /* IMPDEF: treat any other value as 64k */
204+ wi -> pgshift = 16 ; break ;
205+ }
206+ }
207+
208+ wi -> pa52bit = has_52bit_pa (vcpu , wi , tcr );
209+
210+ ia_bits = get_ia_size (wi );
211+
212+ /* AArch64.S1StartLevel() */
213+ stride = wi -> pgshift - 3 ;
214+ wi -> sl = 3 - (((ia_bits - 1 ) - wi -> pgshift ) / stride );
215+
216+ if (wi -> regime == TR_EL2 && va55 )
217+ goto addrsz ;
218+
182219 tbi = (wi -> regime == TR_EL2 ?
183220 FIELD_GET (TCR_EL2_TBI , tcr ) :
184221 (va55 ?
@@ -248,46 +285,15 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
248285 /* R_BVXDG */
249286 wi -> hpd |= (wi -> poe || wi -> e0poe );
250287
251- /* Someone was silly enough to encode TG0/TG1 differently */
252- if (va55 ) {
253- wi -> txsz = FIELD_GET (TCR_T1SZ_MASK , tcr );
254- tg = FIELD_GET (TCR_TG1_MASK , tcr );
255-
256- switch (tg << TCR_TG1_SHIFT ) {
257- case TCR_TG1_4K :
258- wi -> pgshift = 12 ; break ;
259- case TCR_TG1_16K :
260- wi -> pgshift = 14 ; break ;
261- case TCR_TG1_64K :
262- default : /* IMPDEF: treat any other value as 64k */
263- wi -> pgshift = 16 ; break ;
264- }
265- } else {
266- wi -> txsz = FIELD_GET (TCR_T0SZ_MASK , tcr );
267- tg = FIELD_GET (TCR_TG0_MASK , tcr );
268-
269- switch (tg << TCR_TG0_SHIFT ) {
270- case TCR_TG0_4K :
271- wi -> pgshift = 12 ; break ;
272- case TCR_TG0_16K :
273- wi -> pgshift = 14 ; break ;
274- case TCR_TG0_64K :
275- default : /* IMPDEF: treat any other value as 64k */
276- wi -> pgshift = 16 ; break ;
277- }
278- }
279-
280288 /* R_PLCGL, R_YXNYW */
281289 if (!kvm_has_feat_enum (vcpu -> kvm , ID_AA64MMFR2_EL1 , ST , 48 _47 )) {
282290 if (wi -> txsz > 39 )
283- goto transfault_l0 ;
291+ goto transfault ;
284292 } else {
285293 if (wi -> txsz > 48 || (BIT (wi -> pgshift ) == SZ_64K && wi -> txsz > 47 ))
286- goto transfault_l0 ;
294+ goto transfault ;
287295 }
288296
289- wi -> pa52bit = has_52bit_pa (vcpu , wi , tcr );
290-
291297 /* R_GTJBY, R_SXWGM */
292298 switch (BIT (wi -> pgshift )) {
293299 case SZ_4K :
@@ -300,28 +306,22 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
300306 }
301307
302308 if ((lva && wi -> txsz < 12 ) || (!lva && wi -> txsz < 16 ))
303- goto transfault_l0 ;
304-
305- ia_bits = get_ia_size (wi );
309+ goto transfault ;
306310
307311 /* R_YYVYV, I_THCZK */
308312 if ((!va55 && va > GENMASK (ia_bits - 1 , 0 )) ||
309313 (va55 && va < GENMASK (63 , ia_bits )))
310- goto transfault_l0 ;
314+ goto transfault ;
311315
312316 /* I_ZFSYQ */
313317 if (wi -> regime != TR_EL2 &&
314318 (tcr & (va55 ? TCR_EPD1_MASK : TCR_EPD0_MASK )))
315- goto transfault_l0 ;
319+ goto transfault ;
316320
317321 /* R_BNDVG and following statements */
318322 if (kvm_has_feat (vcpu -> kvm , ID_AA64MMFR2_EL1 , E0PD , IMP ) &&
319323 wi -> as_el0 && (tcr & (va55 ? TCR_E0PD1 : TCR_E0PD0 )))
320- goto transfault_l0 ;
321-
322- /* AArch64.S1StartLevel() */
323- stride = wi -> pgshift - 3 ;
324- wi -> sl = 3 - (((ia_bits - 1 ) - wi -> pgshift ) / stride );
324+ goto transfault ;
325325
326326 ps = (wi -> regime == TR_EL2 ?
327327 FIELD_GET (TCR_EL2_PS_MASK , tcr ) : FIELD_GET (TCR_IPS_MASK , tcr ));
@@ -351,12 +351,17 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
351351
352352 return 0 ;
353353
354- addrsz : /* Address Size Fault level 0 */
354+ addrsz :
355+ /*
356+ * Address Size Fault level 0 to indicate it comes from TTBR.
357+ * yes, this is an oddity.
358+ */
355359 fail_s1_walk (wr , ESR_ELx_FSC_ADDRSZ_L (0 ), false);
356360 return - EFAULT ;
357361
358- transfault_l0 : /* Translation Fault level 0 */
359- fail_s1_walk (wr , ESR_ELx_FSC_FAULT_L (0 ), false);
362+ transfault :
363+ /* Translation Fault on start level */
364+ fail_s1_walk (wr , ESR_ELx_FSC_FAULT_L (wi -> sl ), false);
360365 return - EFAULT ;
361366}
362367
0 commit comments