@@ -98,21 +98,26 @@ static enum trans_regime compute_translation_regime(struct kvm_vcpu *vcpu, u32 o
9898 }
9999}
100100
101+ static u64 effective_tcr2 (struct kvm_vcpu * vcpu , enum trans_regime regime )
102+ {
103+ if (regime == TR_EL10 ) {
104+ if (vcpu_has_nv (vcpu ) &&
105+ !(__vcpu_sys_reg (vcpu , HCRX_EL2 ) & HCRX_EL2_TCR2En ))
106+ return 0 ;
107+
108+ return __vcpu_sys_reg (vcpu , TCR2_EL1 );
109+ }
110+
111+ return vcpu_read_sys_reg (vcpu , TCR2_EL2 );
112+ }
113+
101114static bool s1pie_enabled (struct kvm_vcpu * vcpu , enum trans_regime regime )
102115{
103116 if (!kvm_has_s1pie (vcpu -> kvm ))
104117 return false;
105118
106- switch (regime ) {
107- case TR_EL2 :
108- case TR_EL20 :
109- return vcpu_read_sys_reg (vcpu , TCR2_EL2 ) & TCR2_EL2_PIE ;
110- case TR_EL10 :
111- return (__vcpu_sys_reg (vcpu , HCRX_EL2 ) & HCRX_EL2_TCR2En ) &&
112- (__vcpu_sys_reg (vcpu , TCR2_EL1 ) & TCR2_EL1_PIE );
113- default :
114- BUG ();
115- }
119+ /* Abuse TCR2_EL1_PIE and use it for EL2 as well */
120+ return effective_tcr2 (vcpu , regime ) & TCR2_EL1_PIE ;
116121}
117122
118123static void compute_s1poe (struct kvm_vcpu * vcpu , struct s1_walk_info * wi )
@@ -124,23 +129,11 @@ static void compute_s1poe(struct kvm_vcpu *vcpu, struct s1_walk_info *wi)
124129 return ;
125130 }
126131
127- switch (wi -> regime ) {
128- case TR_EL2 :
129- case TR_EL20 :
130- val = vcpu_read_sys_reg (vcpu , TCR2_EL2 );
131- wi -> poe = val & TCR2_EL2_POE ;
132- wi -> e0poe = (wi -> regime == TR_EL20 ) && (val & TCR2_EL2_E0POE );
133- break ;
134- case TR_EL10 :
135- if (__vcpu_sys_reg (vcpu , HCRX_EL2 ) & HCRX_EL2_TCR2En ) {
136- wi -> poe = wi -> e0poe = false;
137- return ;
138- }
132+ val = effective_tcr2 (vcpu , wi -> regime );
139133
140- val = __vcpu_sys_reg (vcpu , TCR2_EL1 );
141- wi -> poe = val & TCR2_EL1_POE ;
142- wi -> e0poe = val & TCR2_EL1_E0POE ;
143- }
134+ /* Abuse TCR2_EL1_* for EL2 */
135+ wi -> poe = val & TCR2_EL1_POE ;
136+ wi -> e0poe = (wi -> regime != TR_EL2 ) && (val & TCR2_EL1_E0POE );
144137}
145138
146139static int setup_s1_walk (struct kvm_vcpu * vcpu , struct s1_walk_info * wi ,
@@ -150,11 +143,16 @@ static int setup_s1_walk(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
150143 unsigned int stride , x ;
151144 bool va55 , tbi , lva ;
152145
153- hcr = __vcpu_sys_reg (vcpu , HCR_EL2 );
154-
155146 va55 = va & BIT (55 );
156147
157- wi -> s2 = wi -> regime == TR_EL10 && (hcr & (HCR_VM | HCR_DC ));
148+ if (vcpu_has_nv (vcpu )) {
149+ hcr = __vcpu_sys_reg (vcpu , HCR_EL2 );
150+ wi -> s2 = wi -> regime == TR_EL10 && (hcr & (HCR_VM | HCR_DC ));
151+ } else {
152+ WARN_ON_ONCE (wi -> regime != TR_EL10 );
153+ wi -> s2 = false;
154+ hcr = 0 ;
155+ }
158156
159157 switch (wi -> regime ) {
160158 case TR_EL10 :
@@ -851,7 +849,7 @@ static u64 compute_par_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
851849 par = SYS_PAR_EL1_NSE ;
852850 par |= wr -> pa & SYS_PAR_EL1_PA ;
853851
854- if (wi -> regime == TR_EL10 &&
852+ if (wi -> regime == TR_EL10 && vcpu_has_nv ( vcpu ) &&
855853 (__vcpu_sys_reg (vcpu , HCR_EL2 ) & HCR_DC )) {
856854 par |= FIELD_PREP (SYS_PAR_EL1_ATTR ,
857855 MEMATTR (WbRaWa , WbRaWa ));
0 commit comments