~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/s390/kvm/gaccess.c

Version: ~ [ linux-5.11 ] ~ [ linux-5.10.17 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.99 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.176 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.221 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.257 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.257 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp