Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * guest access functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright IBM Corp. 2014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/mm_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <asm/gmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include "kvm-s390.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "gaccess.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <asm/switch_to.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) union asce {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 		unsigned long origin : 52; /* Region- or Segment-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 		unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 		unsigned long g  : 1; /* Subspace Group Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 		unsigned long p  : 1; /* Private Space Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 		unsigned long s  : 1; /* Storage-Alteration-Event Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 		unsigned long x  : 1; /* Space-Switch-Event Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 		unsigned long r  : 1; /* Real-Space Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 		unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 		unsigned long dt : 2; /* Designation-Type Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 		unsigned long tl : 2; /* Region- or Segment-Table Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	ASCE_TYPE_SEGMENT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	ASCE_TYPE_REGION3 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	ASCE_TYPE_REGION2 = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	ASCE_TYPE_REGION1 = 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) union region1_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 		unsigned long rto: 52;/* Region-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 		unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 		unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		unsigned long tf : 2; /* Region-Second-Table Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 		unsigned long i  : 1; /* Region-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 		unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 		unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 		unsigned long tl : 2; /* Region-Second-Table Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) union region2_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 		unsigned long rto: 52;/* Region-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 		unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 		unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		unsigned long tf : 2; /* Region-Third-Table Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 		unsigned long i  : 1; /* Region-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 		unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		unsigned long tl : 2; /* Region-Third-Table Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) struct region3_table_entry_fc0 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	unsigned long sto: 52;/* Segment-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	unsigned long	 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	unsigned long tf : 2; /* Segment-Table Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	unsigned long i  : 1; /* Region-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	unsigned long cr : 1; /* Common-Region Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	unsigned long tl : 2; /* Segment-Table Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) struct region3_table_entry_fc1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	unsigned long rfaa : 33; /* Region-Frame Absolute Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	unsigned long	 : 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	unsigned long av : 1; /* ACCF-Validity Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	unsigned long acc: 4; /* Access-Control Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	unsigned long f  : 1; /* Fetch-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	unsigned long iep: 1; /* Instruction-Execution-Protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	unsigned long i  : 1; /* Region-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	unsigned long cr : 1; /* Common-Region Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) union region3_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	struct region3_table_entry_fc0 fc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	struct region3_table_entry_fc1 fc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		unsigned long	 : 53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		unsigned long	 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		unsigned long i  : 1; /* Region-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		unsigned long cr : 1; /* Common-Region Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) struct segment_entry_fc0 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	unsigned long pto: 53;/* Page-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	unsigned long	 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	unsigned long i  : 1; /* Segment-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	unsigned long cs : 1; /* Common-Segment Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) struct segment_entry_fc1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	unsigned long	 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	unsigned long av : 1; /* ACCF-Validity Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	unsigned long acc: 4; /* Access-Control Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	unsigned long f  : 1; /* Fetch-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	unsigned long iep: 1; /* Instruction-Execution-Protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	unsigned long i  : 1; /* Segment-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	unsigned long cs : 1; /* Common-Segment Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) union segment_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	struct segment_entry_fc0 fc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	struct segment_entry_fc1 fc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		unsigned long	 : 53;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		unsigned long fc : 1; /* Format-Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		unsigned long	 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		unsigned long i  : 1; /* Segment-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		unsigned long cs : 1; /* Common-Segment Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		unsigned long tt : 2; /* Table-Type Bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		unsigned long	 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	TABLE_TYPE_SEGMENT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	TABLE_TYPE_REGION3 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	TABLE_TYPE_REGION2 = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	TABLE_TYPE_REGION1 = 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) union page_table_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		unsigned long pfra : 52; /* Page-Frame Real Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		unsigned long z  : 1; /* Zero Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		unsigned long i  : 1; /* Page-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		unsigned long p  : 1; /* DAT-Protection Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		unsigned long iep: 1; /* Instruction-Execution-Protection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		unsigned long	 : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * vaddress union in order to easily decode a virtual address into its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  * region first index, region second index etc. parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) union vaddress {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		unsigned long rfx : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		unsigned long rsx : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		unsigned long rtx : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		unsigned long sx  : 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		unsigned long px  : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		unsigned long bx  : 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		unsigned long rfx01 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		unsigned long	    : 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		unsigned long rsx01 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		unsigned long	    : 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		unsigned long rtx01 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		unsigned long	    : 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		unsigned long sx01  : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		unsigned long	    : 29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  * raddress union which will contain the result (real or absolute address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  * after a page table walk. The rfaa, sfaa and pfra members are used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  * simply assign them the value of a region, segment or page table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) union raddress {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	unsigned long rfaa : 33; /* Region-Frame Absolute Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	unsigned long pfra : 52; /* Page-Frame Real Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) union alet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		u32 reserved : 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		u32 p        : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		u32 alesn    : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		u32 alen     : 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) union ald {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		u32     : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		u32 alo : 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		u32 all : 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) struct ale {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	unsigned long i      : 1; /* ALEN-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	unsigned long        : 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	unsigned long fo     : 1; /* Fetch-Only Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	unsigned long p      : 1; /* Private Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	unsigned long alesn  : 8; /* Access-List-Entry Sequence Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	unsigned long aleax  : 16; /* Access-List-Entry Authorization Index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	unsigned long        : 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	unsigned long        : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	unsigned long asteo  : 25; /* ASN-Second-Table-Entry Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	unsigned long        : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	unsigned long astesn : 32; /* ASTE Sequence Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) struct aste {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	unsigned long i      : 1; /* ASX-Invalid Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	unsigned long ato    : 29; /* Authority-Table Origin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	unsigned long        : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	unsigned long b      : 1; /* Base-Space Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	unsigned long ax     : 16; /* Authorization Index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	unsigned long atl    : 12; /* Authority-Table Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	unsigned long        : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	unsigned long ca     : 1; /* Controlled-ASN Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	unsigned long ra     : 1; /* Reusable-ASN Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	unsigned long asce   : 64; /* Address-Space-Control Element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	unsigned long ald    : 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	unsigned long astesn : 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	/* .. more fields there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) int ipte_lock_held(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	if (vcpu->arch.sie_block->eca & ECA_SII) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		read_lock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		rc = kvm_s390_get_ipte_control(vcpu->kvm)->kh != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	return vcpu->kvm->arch.ipte_lock_count != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) static void ipte_lock_simple(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	union ipte_control old, new, *ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	mutex_lock(&vcpu->kvm->arch.ipte_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	vcpu->kvm->arch.ipte_lock_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	if (vcpu->kvm->arch.ipte_lock_count > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	read_lock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	ic = kvm_s390_get_ipte_control(vcpu->kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		old = READ_ONCE(*ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		if (old.k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		new = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		new.k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) static void ipte_unlock_simple(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	union ipte_control old, new, *ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	mutex_lock(&vcpu->kvm->arch.ipte_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	vcpu->kvm->arch.ipte_lock_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (vcpu->kvm->arch.ipte_lock_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	read_lock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	ic = kvm_s390_get_ipte_control(vcpu->kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		old = READ_ONCE(*ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		new = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		new.k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	wake_up(&vcpu->kvm->arch.ipte_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) static void ipte_lock_siif(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	union ipte_control old, new, *ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	read_lock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	ic = kvm_s390_get_ipte_control(vcpu->kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		old = READ_ONCE(*ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		if (old.kg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		new = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		new.k = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		new.kh++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	union ipte_control old, new, *ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	read_lock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	ic = kvm_s390_get_ipte_control(vcpu->kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		old = READ_ONCE(*ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		new = old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		new.kh--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		if (!new.kh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			new.k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	} while (cmpxchg(&ic->val, old.val, new.val) != old.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	read_unlock(&vcpu->kvm->arch.sca_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	if (!new.kh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		wake_up(&vcpu->kvm->arch.ipte_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) void ipte_lock(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (vcpu->arch.sie_block->eca & ECA_SII)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		ipte_lock_siif(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		ipte_lock_simple(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) void ipte_unlock(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	if (vcpu->arch.sie_block->eca & ECA_SII)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		ipte_unlock_siif(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		ipte_unlock_simple(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, u8 ar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			  enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	union alet alet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	struct ale ale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	struct aste aste;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	unsigned long ald_addr, authority_table_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	union ald ald;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	int eax, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	u8 authority_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (ar >= NUM_ACRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	save_access_regs(vcpu->run->s.regs.acrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	alet.val = vcpu->run->s.regs.acrs[ar];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	if (ar == 0 || alet.val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		asce->val = vcpu->arch.sie_block->gcr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	} else if (alet.val == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		asce->val = vcpu->arch.sie_block->gcr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if (alet.reserved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		return PGM_ALET_SPECIFICATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	if (alet.p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		ald_addr = vcpu->arch.sie_block->gcr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		ald_addr = vcpu->arch.sie_block->gcr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	ald_addr &= 0x7fffffc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	rc = read_guest_real(vcpu, ald_addr + 16, &ald.val, sizeof(union ald));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	if (alet.alen / 8 > ald.all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		return PGM_ALEN_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	if (0x7fffffff - ald.alo * 128 < alet.alen * 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	rc = read_guest_real(vcpu, ald.alo * 128 + alet.alen * 16, &ale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			     sizeof(struct ale));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	if (ale.i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		return PGM_ALEN_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	if (ale.alesn != alet.alesn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		return PGM_ALE_SEQUENCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	rc = read_guest_real(vcpu, ale.asteo * 64, &aste, sizeof(struct aste));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	if (aste.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		return PGM_ASTE_VALIDITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	if (aste.astesn != ale.astesn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		return PGM_ASTE_SEQUENCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	if (ale.p == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		eax = (vcpu->arch.sie_block->gcr[8] >> 16) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		if (ale.aleax != eax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 			if (eax / 16 > aste.atl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 				return PGM_EXTENDED_AUTHORITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			authority_table_addr = aste.ato * 4 + eax / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			rc = read_guest_real(vcpu, authority_table_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 					     &authority_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 					     sizeof(u8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			if ((authority_table & (0x40 >> ((eax & 3) * 2))) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 				return PGM_EXTENDED_AUTHORITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	if (ale.fo == 1 && mode == GACC_STORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		return PGM_PROTECTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	asce->val = aste.asce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) struct trans_exc_code_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	unsigned long addr : 52; /* Translation-exception Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	unsigned long fsi  : 2;  /* Access Exception Fetch/Store Indication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	unsigned long	   : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	unsigned long b56  : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	unsigned long	   : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	unsigned long b60  : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	unsigned long b61  : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	unsigned long as   : 2;  /* ASCE Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	FSI_UNKNOWN = 0, /* Unknown wether fetch or store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	FSI_STORE   = 1, /* Exception was due to store operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	FSI_FETCH   = 2  /* Exception was due to fetch operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) enum prot_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	PROT_TYPE_LA   = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	PROT_TYPE_KEYC = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	PROT_TYPE_ALC  = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	PROT_TYPE_DAT  = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	PROT_TYPE_IEP  = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) static int trans_exc(struct kvm_vcpu *vcpu, int code, unsigned long gva,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		     u8 ar, enum gacc_mode mode, enum prot_type prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	struct trans_exc_code_bits *tec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	memset(pgm, 0, sizeof(*pgm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	pgm->code = code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	case PGM_PROTECTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		switch (prot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		case PROT_TYPE_IEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			tec->b61 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		case PROT_TYPE_LA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 			tec->b56 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		case PROT_TYPE_KEYC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			tec->b60 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		case PROT_TYPE_ALC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 			tec->b60 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		case PROT_TYPE_DAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			tec->b61 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	case PGM_ASCE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	case PGM_PAGE_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	case PGM_REGION_FIRST_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	case PGM_REGION_SECOND_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	case PGM_REGION_THIRD_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	case PGM_SEGMENT_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		 * op_access_id only applies to MOVE_PAGE -> set bit 61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		 * exc_access_id has to be set to 0 for some instructions. Both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		 * cases have to be handled by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		tec->addr = gva >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		tec->fsi = mode == GACC_STORE ? FSI_STORE : FSI_FETCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		tec->as = psw_bits(vcpu->arch.sie_block->gpsw).as;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	case PGM_ALEN_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	case PGM_ALE_SEQUENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	case PGM_ASTE_VALIDITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	case PGM_ASTE_SEQUENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	case PGM_EXTENDED_AUTHORITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		 * We can always store exc_access_id, as it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		 * undefined for non-ar cases. It is undefined for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		 * most DAT protection exceptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		pgm->exc_access_id = ar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	return code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			 unsigned long ga, u8 ar, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	struct psw_bits psw = psw_bits(vcpu->arch.sie_block->gpsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	if (!psw.dat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		asce->val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		asce->r = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	if ((mode == GACC_IFETCH) && (psw.as != PSW_BITS_AS_HOME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		psw.as = PSW_BITS_AS_PRIMARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	switch (psw.as) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	case PSW_BITS_AS_PRIMARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		asce->val = vcpu->arch.sie_block->gcr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	case PSW_BITS_AS_SECONDARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		asce->val = vcpu->arch.sie_block->gcr[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	case PSW_BITS_AS_HOME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		asce->val = vcpu->arch.sie_block->gcr[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	case PSW_BITS_AS_ACCREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		rc = ar_translation(vcpu, asce, ar, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		if (rc > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 			return trans_exc(vcpu, rc, ga, ar, mode, PROT_TYPE_ALC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	return kvm_read_guest(kvm, gpa, val, sizeof(*val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  * guest_translate - translate a guest virtual into a guest absolute address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  * @vcpu: virtual cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)  * @gva: guest virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)  * @gpa: points to where guest physical (absolute) address should be stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)  * @asce: effective asce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)  * @mode: indicates the access mode to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)  * @prot: returns the type for protection exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)  * Translate a guest virtual address into a guest absolute address by means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  * of dynamic address translation as specified by the architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  * If the resulting absolute address is not available in the configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  * an addressing exception is indicated and @gpa will not be changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  * Returns: - zero on success; @gpa contains the resulting absolute address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)  *	    - a negative value if guest access failed due to e.g. broken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)  *	      guest mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610)  *	    - a positve value if an access exception happened. In this case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611)  *	      the returned value is the program interruption code as defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612)  *	      by the architecture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 				     unsigned long *gpa, const union asce asce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 				     enum gacc_mode mode, enum prot_type *prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	union vaddress vaddr = {.addr = gva};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	union raddress raddr = {.addr = gva};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	union page_table_entry pte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	int dat_protection = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	int iep_protection = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	union ctlreg0 ctlreg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	unsigned long ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	int edat1, edat2, iep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	ctlreg0.val = vcpu->arch.sie_block->gcr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	if (asce.r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		goto real_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ptr = asce.origin * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	switch (asce.dt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	case ASCE_TYPE_REGION1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		if (vaddr.rfx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			return PGM_REGION_FIRST_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		ptr += vaddr.rfx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	case ASCE_TYPE_REGION2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		if (vaddr.rfx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		if (vaddr.rsx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		ptr += vaddr.rsx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	case ASCE_TYPE_REGION3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		if (vaddr.rfx || vaddr.rsx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		if (vaddr.rtx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		ptr += vaddr.rtx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	case ASCE_TYPE_SEGMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		if (vaddr.sx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		ptr += vaddr.sx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	switch (asce.dt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	case ASCE_TYPE_REGION1:	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		union region1_table_entry rfte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		if (kvm_is_error_gpa(vcpu->kvm, ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		if (deref_table(vcpu->kvm, ptr, &rfte.val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		if (rfte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			return PGM_REGION_FIRST_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		if (rfte.tt != TABLE_TYPE_REGION1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		if (edat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			dat_protection |= rfte.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		ptr = rfte.rto * PAGE_SIZE + vaddr.rsx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	case ASCE_TYPE_REGION2: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		union region2_table_entry rste;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		if (kvm_is_error_gpa(vcpu->kvm, ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 			return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		if (deref_table(vcpu->kvm, ptr, &rste.val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		if (rste.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		if (rste.tt != TABLE_TYPE_REGION2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		if (edat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			dat_protection |= rste.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		ptr = rste.rto * PAGE_SIZE + vaddr.rtx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	case ASCE_TYPE_REGION3: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		union region3_table_entry rtte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		if (kvm_is_error_gpa(vcpu->kvm, ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		if (deref_table(vcpu->kvm, ptr, &rtte.val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		if (rtte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		if (rtte.tt != TABLE_TYPE_REGION3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		if (rtte.cr && asce.p && edat2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		if (rtte.fc && edat2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			dat_protection |= rtte.fc1.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			iep_protection = rtte.fc1.iep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			raddr.rfaa = rtte.fc1.rfaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			goto absolute_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		if (vaddr.sx01 < rtte.fc0.tf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		if (vaddr.sx01 > rtte.fc0.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		if (edat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			dat_protection |= rtte.fc0.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		ptr = rtte.fc0.sto * PAGE_SIZE + vaddr.sx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	case ASCE_TYPE_SEGMENT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		union segment_table_entry ste;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		if (kvm_is_error_gpa(vcpu->kvm, ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		if (deref_table(vcpu->kvm, ptr, &ste.val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		if (ste.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		if (ste.tt != TABLE_TYPE_SEGMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		if (ste.cs && asce.p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		if (ste.fc && edat1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			dat_protection |= ste.fc1.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			iep_protection = ste.fc1.iep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			raddr.sfaa = ste.fc1.sfaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			goto absolute_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		dat_protection |= ste.fc0.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		ptr = ste.fc0.pto * (PAGE_SIZE / 2) + vaddr.px * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (kvm_is_error_gpa(vcpu->kvm, ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (deref_table(vcpu->kvm, ptr, &pte.val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	if (pte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		return PGM_PAGE_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if (pte.z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	dat_protection |= pte.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	iep_protection = pte.iep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	raddr.pfra = pte.pfra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) real_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) absolute_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	if (mode == GACC_STORE && dat_protection) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		*prot = PROT_TYPE_DAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		return PGM_PROTECTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	if (mode == GACC_IFETCH && iep_protection && iep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		*prot = PROT_TYPE_IEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		return PGM_PROTECTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	if (kvm_is_error_gpa(vcpu->kvm, raddr.addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		return PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	*gpa = raddr.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) static inline int is_low_address(unsigned long ga)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	/* Check for address ranges 0..511 and 4096..4607 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	return (ga & ~0x11fful) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 					  const union asce asce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	psw_t *psw = &vcpu->arch.sie_block->gpsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (!ctlreg0.lap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	if (psw_bits(*psw).dat && asce.p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			    unsigned long *pages, unsigned long nr_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			    const union asce asce, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	psw_t *psw = &vcpu->arch.sie_block->gpsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	int lap_enabled, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	enum prot_type prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	lap_enabled = low_address_protection_enabled(vcpu, asce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	while (nr_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		ga = kvm_s390_logical_to_effective(vcpu, ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 					 PROT_TYPE_LA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		ga &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (psw_bits(*psw).dat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			rc = guest_translate(vcpu, ga, pages, asce, mode, &prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 				return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			*pages = kvm_s390_real_to_abs(vcpu, ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			if (kvm_is_error_gpa(vcpu->kvm, *pages))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 				rc = PGM_ADDRESSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			return trans_exc(vcpu, rc, ga, ar, mode, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		ga += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		pages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		nr_pages--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		 unsigned long len, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	psw_t *psw = &vcpu->arch.sie_block->gpsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	unsigned long _len, nr_pages, gpa, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	unsigned long pages_array[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	unsigned long *pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	int need_ipte_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	union asce asce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	ga = kvm_s390_logical_to_effective(vcpu, ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	rc = get_vcpu_asce(vcpu, &asce, ga, ar, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	pages = pages_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	if (nr_pages > ARRAY_SIZE(pages_array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		pages = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (!pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	need_ipte_lock = psw_bits(*psw).dat && !asce.r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (need_ipte_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		ipte_lock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	rc = guest_page_range(vcpu, ga, ar, pages, nr_pages, asce, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	for (idx = 0; idx < nr_pages && !rc; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		gpa = *(pages + idx) + (ga & ~PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		if (mode == GACC_STORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			rc = kvm_write_guest(vcpu->kvm, gpa, data, _len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		len -= _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		ga += _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		data += _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (need_ipte_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		ipte_unlock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if (nr_pages > ARRAY_SIZE(pages_array))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		vfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		      void *data, unsigned long len, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	unsigned long _len, gpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	while (len && !rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		gpa = kvm_s390_real_to_abs(vcpu, gra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		if (mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			rc = write_guest_abs(vcpu, gpa, data, _len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			rc = read_guest_abs(vcpu, gpa, data, _len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		len -= _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		gra += _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		data += _len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896)  * guest_translate_address - translate guest logical into guest absolute address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898)  * Parameter semantics are the same as the ones from guest_translate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)  * The memory contents at the guest address are not changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901)  * Note: The IPTE lock is not taken during this function, so the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)  * has to take care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 			    unsigned long *gpa, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	psw_t *psw = &vcpu->arch.sie_block->gpsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	enum prot_type prot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	union asce asce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	gva = kvm_s390_logical_to_effective(vcpu, gva);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		if (mode == GACC_STORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			return trans_exc(vcpu, PGM_PROTECTION, gva, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 					 mode, PROT_TYPE_LA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (psw_bits(*psw).dat && !asce.r) {	/* Use DAT? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		rc = guest_translate(vcpu, gva, gpa, asce, mode, &prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		if (rc > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			return trans_exc(vcpu, rc, gva, 0, mode, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		*gpa = kvm_s390_real_to_abs(vcpu, gva);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		if (kvm_is_error_gpa(vcpu->kvm, *gpa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			return trans_exc(vcpu, rc, gva, PGM_ADDRESSING, mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936)  * check_gva_range - test a range of guest virtual addresses for accessibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		    unsigned long length, enum gacc_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	unsigned long gpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	unsigned long currlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	ipte_lock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	while (length > 0 && !rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		rc = guest_translate_address(vcpu, gva, ar, &gpa, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		gva += currlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		length -= currlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	ipte_unlock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958)  * kvm_s390_check_low_addr_prot_real - check for low-address protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959)  * @gra: Guest real address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961)  * Checks whether an address is subject to low-address protection and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962)  * up vcpu->arch.pgm accordingly if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)  * Return: 0 if no protection exception, or PGM_PROTECTION if protected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (!ctlreg0.lap || !is_low_address(gra))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	return trans_exc(vcpu, PGM_PROTECTION, gra, 0, GACC_STORE, PROT_TYPE_LA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976)  * kvm_s390_shadow_tables - walk the guest page table and create shadow tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)  * @sg: pointer to the shadow guest address space structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978)  * @saddr: faulting address in the shadow gmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979)  * @pgt: pointer to the beginning of the page table for the given address if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980)  *	 successful (return value 0), or to the first invalid DAT entry in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981)  *	 case of exceptions (return value > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982)  * @fake: pgt references contiguous guest memory block, not a pgtable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 				  unsigned long *pgt, int *dat_protection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 				  int *fake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	struct gmap *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	union asce asce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	union vaddress vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	unsigned long ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	*fake = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	*dat_protection = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	parent = sg->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	vaddr.addr = saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	asce.val = sg->orig_asce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	ptr = asce.origin * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (asce.r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		*fake = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		asce.dt = ASCE_TYPE_REGION1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	switch (asce.dt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	case ASCE_TYPE_REGION1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		if (vaddr.rfx01 > asce.tl && !*fake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			return PGM_REGION_FIRST_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	case ASCE_TYPE_REGION2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		if (vaddr.rfx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		if (vaddr.rsx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	case ASCE_TYPE_REGION3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		if (vaddr.rfx || vaddr.rsx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		if (vaddr.rtx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	case ASCE_TYPE_SEGMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			return PGM_ASCE_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		if (vaddr.sx01 > asce.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	switch (asce.dt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	case ASCE_TYPE_REGION1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		union region1_table_entry rfte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		if (*fake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 			ptr += vaddr.rfx * _REGION1_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			rfte.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			goto shadow_r2t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		*pgt = ptr + vaddr.rfx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		rc = gmap_read_table(parent, ptr + vaddr.rfx * 8, &rfte.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (rfte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			return PGM_REGION_FIRST_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		if (rfte.tt != TABLE_TYPE_REGION1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		if (sg->edat_level >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			*dat_protection |= rfte.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		ptr = rfte.rto * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) shadow_r2t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	case ASCE_TYPE_REGION2: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		union region2_table_entry rste;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		if (*fake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			ptr += vaddr.rsx * _REGION2_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			rste.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			goto shadow_r3t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		*pgt = ptr + vaddr.rsx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		rc = gmap_read_table(parent, ptr + vaddr.rsx * 8, &rste.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		if (rste.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			return PGM_REGION_SECOND_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		if (rste.tt != TABLE_TYPE_REGION2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		if (sg->edat_level >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			*dat_protection |= rste.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		ptr = rste.rto * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) shadow_r3t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		rste.p |= *dat_protection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	case ASCE_TYPE_REGION3: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		union region3_table_entry rtte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		if (*fake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			ptr += vaddr.rtx * _REGION3_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			rtte.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			goto shadow_sgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		*pgt = ptr + vaddr.rtx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		rc = gmap_read_table(parent, ptr + vaddr.rtx * 8, &rtte.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		if (rtte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 			return PGM_REGION_THIRD_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		if (rtte.tt != TABLE_TYPE_REGION3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		if (rtte.cr && asce.p && sg->edat_level >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		if (rtte.fc && sg->edat_level >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 			*dat_protection |= rtte.fc0.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 			*fake = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 			ptr = rtte.fc1.rfaa * _REGION3_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 			rtte.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			goto shadow_sgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		if (vaddr.sx01 < rtte.fc0.tf || vaddr.sx01 > rtte.fc0.tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		if (sg->edat_level >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			*dat_protection |= rtte.fc0.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		ptr = rtte.fc0.sto * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) shadow_sgt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		rtte.fc0.p |= *dat_protection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	case ASCE_TYPE_SEGMENT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		union segment_table_entry ste;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		if (*fake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 			ptr += vaddr.sx * _SEGMENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			ste.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			goto shadow_pgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		*pgt = ptr + vaddr.sx * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		rc = gmap_read_table(parent, ptr + vaddr.sx * 8, &ste.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		if (ste.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 			return PGM_SEGMENT_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		if (ste.tt != TABLE_TYPE_SEGMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		if (ste.cs && asce.p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			return PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		*dat_protection |= ste.fc0.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		if (ste.fc && sg->edat_level >= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			*fake = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 			ptr = ste.fc1.sfaa * _SEGMENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 			ste.val = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			goto shadow_pgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		ptr = ste.fc0.pto * (PAGE_SIZE / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) shadow_pgt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		ste.fc0.p |= *dat_protection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		rc = gmap_shadow_pgt(sg, saddr, ste.val, *fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	/* Return the parent address of the page table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	*pgt = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)  * kvm_s390_shadow_fault - handle fault on a shadow page table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)  * @vcpu: virtual cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)  * @sg: pointer to the shadow guest address space structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)  * @saddr: faulting address in the shadow gmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)  * @datptr: will contain the address of the faulting DAT table entry, or of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)  *	    the valid leaf, plus some flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)  * Returns: - 0 if the shadow fault was successfully resolved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)  *	    - > 0 (pgm exception code) on exceptions while faulting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)  *	    - -EAGAIN if the caller can retry immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  *	    - -EFAULT when accessing invalid guest addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)  *	    - -ENOMEM if out of memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			  unsigned long saddr, unsigned long *datptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	union vaddress vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	union page_table_entry pte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	unsigned long pgt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	int dat_protection, fake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	mmap_read_lock(sg->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	 * We don't want any guest-2 tables to change - so the parent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	 * tables/pointers we read stay valid - unshadowing is however
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	 * always possible - only guest_table_lock protects us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	ipte_lock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection, &fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		rc = kvm_s390_shadow_tables(sg, saddr, &pgt, &dat_protection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 					    &fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	vaddr.addr = saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	if (fake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		pte.val = pgt + vaddr.px * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		goto shadow_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	switch (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	case PGM_SEGMENT_TRANSLATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	case PGM_REGION_THIRD_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	case PGM_REGION_SECOND_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	case PGM_REGION_FIRST_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		pgt |= PEI_NOT_PTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		pgt += vaddr.px * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		rc = gmap_read_table(sg->parent, pgt, &pte.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (datptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		*datptr = pgt | dat_protection * PEI_DAT_PROT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (!rc && pte.i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		rc = PGM_PAGE_TRANSLATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	if (!rc && pte.z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		rc = PGM_TRANSLATION_SPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) shadow_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	pte.p |= dat_protection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		rc = gmap_shadow_page(sg, saddr, __pte(pte.val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	ipte_unlock(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	mmap_read_unlock(sg->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }