@@ -40,9 +40,11 @@ struct s1_walk_result {
40
40
u8 APTable ;
41
41
bool UXNTable ;
42
42
bool PXNTable ;
43
+ bool uov ;
43
44
bool ur ;
44
45
bool uw ;
45
46
bool ux ;
47
+ bool pov ;
46
48
bool pr ;
47
49
bool pw ;
48
50
bool px ;
@@ -881,6 +883,9 @@ static void compute_s1_direct_permissions(struct kvm_vcpu *vcpu,
881
883
/* XN maps to UXN */
882
884
wr -> px = !(wr -> desc & PTE_UXN );
883
885
}
886
+
887
+ wr -> pov = wi -> poe ;
888
+ wr -> uov = wi -> e0poe ;
884
889
}
885
890
886
891
static void compute_s1_hierarchical_permissions (struct kvm_vcpu * vcpu ,
@@ -1016,13 +1021,58 @@ static void compute_s1_indirect_permissions(struct kvm_vcpu *vcpu,
1016
1021
else
1017
1022
set_unpriv_perms (wr , false, false, false);
1018
1023
1024
+ wr -> pov = wi -> poe && !(pp & BIT (3 ));
1025
+ wr -> uov = wi -> e0poe && !(up & BIT (3 ));
1026
+
1019
1027
/* R_VFPJF */
1020
1028
if (wr -> px && wr -> uw ) {
1021
1029
set_priv_perms (wr , false, false, false);
1022
1030
set_unpriv_perms (wr , false, false, false);
1023
1031
}
1024
1032
}
1025
1033
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
+
1026
1076
static void compute_s1_permissions (struct kvm_vcpu * vcpu ,
1027
1077
struct s1_walk_info * wi ,
1028
1078
struct s1_walk_result * wr )
@@ -1037,6 +1087,9 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
1037
1087
if (!wi -> hpd )
1038
1088
compute_s1_hierarchical_permissions (vcpu , wi , wr );
1039
1089
1090
+ if (wi -> poe || wi -> e0poe )
1091
+ compute_s1_overlay_permissions (vcpu , wi , wr );
1092
+
1040
1093
pan = wi -> pan && (wr -> ur || wr -> uw ||
1041
1094
(pan3_enabled (vcpu , wi -> regime ) && wr -> ux ));
1042
1095
wr -> pw &= !pan ;
0 commit comments