@@ -40,9 +40,11 @@ struct s1_walk_result {
4040 u8 APTable ;
4141 bool UXNTable ;
4242 bool PXNTable ;
43+ bool uov ;
4344 bool ur ;
4445 bool uw ;
4546 bool ux ;
47+ bool pov ;
4648 bool pr ;
4749 bool pw ;
4850 bool px ;
@@ -881,6 +883,9 @@ static void compute_s1_direct_permissions(struct kvm_vcpu *vcpu,
881883 /* XN maps to UXN */
882884 wr -> px = !(wr -> desc & PTE_UXN );
883885 }
886+
887+ wr -> pov = wi -> poe ;
888+ wr -> uov = wi -> e0poe ;
884889}
885890
886891static void compute_s1_hierarchical_permissions (struct kvm_vcpu * vcpu ,
@@ -1016,13 +1021,58 @@ static void compute_s1_indirect_permissions(struct kvm_vcpu *vcpu,
10161021 else
10171022 set_unpriv_perms (wr , false, false, false);
10181023
1024+ wr -> pov = wi -> poe && !(pp & BIT (3 ));
1025+ wr -> uov = wi -> e0poe && !(up & BIT (3 ));
1026+
10191027 /* R_VFPJF */
10201028 if (wr -> px && wr -> uw ) {
10211029 set_priv_perms (wr , false, false, false);
10221030 set_unpriv_perms (wr , false, false, false);
10231031 }
10241032}
10251033
1034+ static void compute_s1_overlay_permissions (struct kvm_vcpu * vcpu ,
1035+ struct s1_walk_info * wi ,
1036+ struct s1_walk_result * wr )
1037+ {
1038+ u8 idx , pov_perms , uov_perms ;
1039+
1040+ idx = FIELD_GET (PTE_PO_IDX_MASK , wr -> desc );
1041+
1042+ switch (wi -> regime ) {
1043+ case TR_EL10 :
1044+ pov_perms = perm_idx (vcpu , POR_EL1 , idx );
1045+ uov_perms = perm_idx (vcpu , POR_EL0 , idx );
1046+ break ;
1047+ case TR_EL20 :
1048+ pov_perms = perm_idx (vcpu , POR_EL2 , idx );
1049+ uov_perms = perm_idx (vcpu , POR_EL0 , idx );
1050+ break ;
1051+ case TR_EL2 :
1052+ pov_perms = perm_idx (vcpu , POR_EL2 , idx );
1053+ uov_perms = 0 ;
1054+ break ;
1055+ }
1056+
1057+ if (pov_perms & ~POE_RXW )
1058+ pov_perms = POE_NONE ;
1059+
1060+ if (wi -> poe && wr -> pov ) {
1061+ wr -> pr &= pov_perms & POE_R ;
1062+ wr -> px &= pov_perms & POE_X ;
1063+ wr -> pw &= pov_perms & POE_W ;
1064+ }
1065+
1066+ if (uov_perms & ~POE_RXW )
1067+ uov_perms = POE_NONE ;
1068+
1069+ if (wi -> e0poe && wr -> uov ) {
1070+ wr -> ur &= uov_perms & POE_R ;
1071+ wr -> ux &= uov_perms & POE_X ;
1072+ wr -> uw &= uov_perms & POE_W ;
1073+ }
1074+ }
1075+
10261076static void compute_s1_permissions (struct kvm_vcpu * vcpu ,
10271077 struct s1_walk_info * wi ,
10281078 struct s1_walk_result * wr )
@@ -1037,6 +1087,9 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
10371087 if (!wi -> hpd )
10381088 compute_s1_hierarchical_permissions (vcpu , wi , wr );
10391089
1090+ if (wi -> poe || wi -> e0poe )
1091+ compute_s1_overlay_permissions (vcpu , wi , wr );
1092+
10401093 pan = wi -> pan && (wr -> ur || wr -> uw ||
10411094 (pan3_enabled (vcpu , wi -> regime ) && wr -> ux ));
10421095 wr -> pw &= !pan ;
0 commit comments