linux/arch/s390/kvm/gaccess.c
<<
>>
Prefs
   1/*
   2 * guest access functions
   3 *
   4 * Copyright IBM Corp. 2014
   5 *
   6 */
   7
   8#include <linux/vmalloc.h>
   9#include <linux/err.h>
  10#include <asm/pgtable.h>
  11#include "kvm-s390.h"
  12#include "gaccess.h"
  13#include <asm/switch_to.h>
  14
  15union asce {
  16        unsigned long val;
  17        struct {
  18                unsigned long origin : 52; /* Region- or Segment-Table Origin */
  19                unsigned long    : 2;
  20                unsigned long g  : 1; /* Subspace Group Control */
  21                unsigned long p  : 1; /* Private Space Control */
  22                unsigned long s  : 1; /* Storage-Alteration-Event Control */
  23                unsigned long x  : 1; /* Space-Switch-Event Control */
  24                unsigned long r  : 1; /* Real-Space Control */
  25                unsigned long    : 1;
  26                unsigned long dt : 2; /* Designation-Type Control */
  27                unsigned long tl : 2; /* Region- or Segment-Table Length */
  28        };
  29};
  30
  31enum {
  32        ASCE_TYPE_SEGMENT = 0,
  33        ASCE_TYPE_REGION3 = 1,
  34        ASCE_TYPE_REGION2 = 2,
  35        ASCE_TYPE_REGION1 = 3
  36};
  37
  38union region1_table_entry {
  39        unsigned long val;
  40        struct {
  41                unsigned long rto: 52;/* Region-Table Origin */
  42                unsigned long    : 2;
  43                unsigned long p  : 1; /* DAT-Protection Bit */
  44                unsigned long    : 1;
  45                unsigned long tf : 2; /* Region-Second-Table Offset */
  46                unsigned long i  : 1; /* Region-Invalid Bit */
  47                unsigned long    : 1;
  48                unsigned long tt : 2; /* Table-Type Bits */
  49                unsigned long tl : 2; /* Region-Second-Table Length */
  50        };
  51};
  52
  53union region2_table_entry {
  54        unsigned long val;
  55        struct {
  56                unsigned long rto: 52;/* Region-Table Origin */
  57                unsigned long    : 2;
  58                unsigned long p  : 1; /* DAT-Protection Bit */
  59                unsigned long    : 1;
  60                unsigned long tf : 2; /* Region-Third-Table Offset */
  61                unsigned long i  : 1; /* Region-Invalid Bit */
  62                unsigned long    : 1;
  63                unsigned long tt : 2; /* Table-Type Bits */
  64                unsigned long tl : 2; /* Region-Third-Table Length */
  65        };
  66};
  67
  68struct region3_table_entry_fc0 {
  69        unsigned long sto: 52;/* Segment-Table Origin */
  70        unsigned long    : 1;
  71        unsigned long fc : 1; /* Format-Control */
  72        unsigned long p  : 1; /* DAT-Protection Bit */
  73        unsigned long    : 1;
  74        unsigned long tf : 2; /* Segment-Table Offset */
  75        unsigned long i  : 1; /* Region-Invalid Bit */
  76        unsigned long cr : 1; /* Common-Region Bit */
  77        unsigned long tt : 2; /* Table-Type Bits */
  78        unsigned long tl : 2; /* Segment-Table Length */
  79};
  80
  81struct region3_table_entry_fc1 {
  82        unsigned long rfaa : 33; /* Region-Frame Absolute Address */
  83        unsigned long    : 14;
  84        unsigned long av : 1; /* ACCF-Validity Control */
  85        unsigned long acc: 4; /* Access-Control Bits */
  86        unsigned long f  : 1; /* Fetch-Protection Bit */
  87        unsigned long fc : 1; /* Format-Control */
  88        unsigned long p  : 1; /* DAT-Protection Bit */
  89        unsigned long co : 1; /* Change-Recording Override */
  90        unsigned long    : 2;
  91        unsigned long i  : 1; /* Region-Invalid Bit */
  92        unsigned long cr : 1; /* Common-Region Bit */
  93        unsigned long tt : 2; /* Table-Type Bits */
  94        unsigned long    : 2;
  95};
  96
  97union region3_table_entry {
  98        unsigned long val;
  99        struct region3_table_entry_fc0 fc0;
 100        struct region3_table_entry_fc1 fc1;
 101        struct {
 102                unsigned long    : 53;
 103                unsigned long fc : 1; /* Format-Control */
 104                unsigned long    : 4;
 105                unsigned long i  : 1; /* Region-Invalid Bit */
 106                unsigned long cr : 1; /* Common-Region Bit */
 107                unsigned long tt : 2; /* Table-Type Bits */
 108                unsigned long    : 2;
 109        };
 110};
 111
 112struct segment_entry_fc0 {
 113        unsigned long pto: 53;/* Page-Table Origin */
 114        unsigned long fc : 1; /* Format-Control */
 115        unsigned long p  : 1; /* DAT-Protection Bit */
 116        unsigned long    : 3;
 117        unsigned long i  : 1; /* Segment-Invalid Bit */
 118        unsigned long cs : 1; /* Common-Segment Bit */
 119        unsigned long tt : 2; /* Table-Type Bits */
 120        unsigned long    : 2;
 121};
 122
 123struct segment_entry_fc1 {
 124        unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
 125        unsigned long    : 3;
 126        unsigned long av : 1; /* ACCF-Validity Control */
 127        unsigned long acc: 4; /* Access-Control Bits */
 128        unsigned long f  : 1; /* Fetch-Protection Bit */
 129        unsigned long fc : 1; /* Format-Control */
 130        unsigned long p  : 1; /* DAT-Protection Bit */
 131        unsigned long co : 1; /* Change-Recording Override */
 132        unsigned long    : 2;
 133        unsigned long i  : 1; /* Segment-Invalid Bit */
 134        unsigned long cs : 1; /* Common-Segment Bit */
 135        unsigned long tt : 2; /* Table-Type Bits */
 136        unsigned long    : 2;
 137};
 138
 139union segment_table_entry {
 140        unsigned long val;
 141        struct segment_entry_fc0 fc0;
 142        struct segment_entry_fc1 fc1;
 143        struct {
 144                unsigned long    : 53;
 145                unsigned long fc : 1; /* Format-Control */
 146                unsigned long    : 4;
 147                unsigned long i  : 1; /* Segment-Invalid Bit */
 148                unsigned long cs : 1; /* Common-Segment Bit */
 149                unsigned long tt : 2; /* Table-Type Bits */
 150                unsigned long    : 2;
 151        };
 152};
 153
 154enum {
 155        TABLE_TYPE_SEGMENT = 0,
 156        TABLE_TYPE_REGION3 = 1,
 157        TABLE_TYPE_REGION2 = 2,
 158        TABLE_TYPE_REGION1 = 3
 159};
 160
 161union page_table_entry {
 162        unsigned long val;
 163        struct {
 164                unsigned long pfra : 52; /* Page-Frame Real Address */
 165                unsigned long z  : 1; /* Zero Bit */
 166                unsigned long i  : 1; /* Page-Invalid Bit */
 167                unsigned long p  : 1; /* DAT-Protection Bit */
 168                unsigned long co : 1; /* Change-Recording Override */
 169                unsigned long    : 8;
 170        };
 171};
 172
 173/*
 174 * vaddress union in order to easily decode a virtual address into its
 175 * region first index, region second index etc. parts.
 176 */
 177union vaddress {
 178        unsigned long addr;
 179        struct {
 180                unsigned long rfx : 11;
 181                unsigned long rsx : 11;
 182                unsigned long rtx : 11;
 183                unsigned long sx  : 11;
 184                unsigned long px  : 8;
 185                unsigned long bx  : 12;
 186        };
 187        struct {
 188                unsigned long rfx01 : 2;
 189                unsigned long       : 9;
 190                unsigned long rsx01 : 2;
 191                unsigned long       : 9;
 192                unsigned long rtx01 : 2;
 193                unsigned long       : 9;
 194                unsigned long sx01  : 2;
 195                unsigned long       : 29;
 196        };
 197};
 198
 199/*
 200 * raddress union which will contain the result (real or absolute address)
 201 * after a page table walk. The rfaa, sfaa and pfra members are used to
 202 * simply assign them the value of a region, segment or page table entry.
 203 */
 204union raddress {
 205        unsigned long addr;
 206        unsigned long rfaa : 33; /* Region-Frame Absolute Address */
 207        unsigned long sfaa : 44; /* Segment-Frame Absolute Address */
 208        unsigned long pfra : 52; /* Page-Frame Real Address */
 209};
 210
 211union alet {
 212        u32 val;
 213        struct {
 214                u32 reserved : 7;
 215                u32 p        : 1;
 216                u32 alesn    : 8;
 217                u32 alen     : 16;
 218        };
 219};
 220
 221union ald {
 222        u32 val;
 223        struct {
 224                u32     : 1;
 225                u32 alo : 24;
 226                u32 all : 7;
 227        };
 228};
 229
 230struct ale {
 231        unsigned long i      : 1; /* ALEN-Invalid Bit */
 232        unsigned long        : 5;
 233        unsigned long fo     : 1; /* Fetch-Only Bit */
 234        unsigned long p      : 1; /* Private Bit */
 235        unsigned long alesn  : 8; /* Access-List-Entry Sequence Number */
 236        unsigned long aleax  : 16; /* Access-List-Entry Authorization Index */
 237        unsigned long        : 32;
 238        unsigned long        : 1;
 239        unsigned long asteo  : 25; /* ASN-Second-Table-Entry Origin */
 240        unsigned long        : 6;
 241        unsigned long astesn : 32; /* ASTE Sequence Number */
 242} __packed;
 243
 244struct aste {
 245        unsigned long i      : 1; /* ASX-Invalid Bit */
 246        unsigned long ato    : 29; /* Authority-Table Origin */
 247        unsigned long        : 1;
 248        unsigned long b      : 1; /* Base-Space Bit */
 249        unsigned long ax     : 16; /* Authorization Index */
 250        unsigned long atl    : 12; /* Authority-Table Length */
 251        unsigned long        : 2;
 252        unsigned long ca     : 1; /* Controlled-ASN Bit */
 253        unsigned long ra     : 1; /* Reusable-ASN Bit */
 254        unsigned long asce   : 64; /* Address-Space-Control Element */
 255        unsigned long ald    : 32;
 256        unsigned long astesn : 32;
 257        /* .. more fields there */
 258} __packed;
 259
 260int ipte_lock_held(struct kvm_vcpu *vcpu)
 261{
 262        union ipte_control *ic = &vcpu->kvm->arch.sca->ipte_control;
 263
 264        if (vcpu->arch.sie_block->eca & 1)
 265                return ic->kh != 0;
 266        return vcpu->kvm->arch.ipte_lock_count != 0;
 267}
 268
 269static void ipte_lock_simple(struct kvm_vcpu *vcpu)
 270{
 271        union ipte_control old, new, *ic;
 272
 273        mutex_lock(&vcpu->kvm->arch.ipte_mutex);
 274        vcpu->kvm->arch.ipte_lock_count++;
 275        if (vcpu->kvm->arch.ipte_lock_count > 1)
 276                goto out;
 277        ic = &vcpu->kvm->arch.sca->ipte_control;
 278        do {
 279                old = READ_ONCE(*ic);
 280                while (old.k) {
 281                        cond_resched();
 282                        old = READ_ONCE(*ic);
 283                }
 284                new = old;
 285                new.k = 1;
 286        } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
 287out:
 288        mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
 289}
 290
 291static void ipte_unlock_simple(struct kvm_vcpu *vcpu)
 292{
 293        union ipte_control old, new, *ic;
 294
 295        mutex_lock(&vcpu->kvm->arch.ipte_mutex);
 296        vcpu->kvm->arch.ipte_lock_count--;
 297        if (vcpu->kvm->arch.ipte_lock_count)
 298                goto out;
 299        ic = &vcpu->kvm->arch.sca->ipte_control;
 300        do {
 301                old = READ_ONCE(*ic);
 302                new = old;
 303                new.k = 0;
 304        } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
 305        wake_up(&vcpu->kvm->arch.ipte_wq);
 306out:
 307        mutex_unlock(&vcpu->kvm->arch.ipte_mutex);
 308}
 309
 310static void ipte_lock_siif(struct kvm_vcpu *vcpu)
 311{
 312        union ipte_control old, new, *ic;
 313
 314        ic = &vcpu->kvm->arch.sca->ipte_control;
 315        do {
 316                old = READ_ONCE(*ic);
 317                while (old.kg) {
 318                        cond_resched();
 319                        old = READ_ONCE(*ic);
 320                }
 321                new = old;
 322                new.k = 1;
 323                new.kh++;
 324        } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
 325}
 326
 327static void ipte_unlock_siif(struct kvm_vcpu *vcpu)
 328{
 329        union ipte_control old, new, *ic;
 330
 331        ic = &vcpu->kvm->arch.sca->ipte_control;
 332        do {
 333                old = READ_ONCE(*ic);
 334                new = old;
 335                new.kh--;
 336                if (!new.kh)
 337                        new.k = 0;
 338        } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
 339        if (!new.kh)
 340                wake_up(&vcpu->kvm->arch.ipte_wq);
 341}
 342
 343void ipte_lock(struct kvm_vcpu *vcpu)
 344{
 345        if (vcpu->arch.sie_block->eca & 1)
 346                ipte_lock_siif(vcpu);
 347        else
 348                ipte_lock_simple(vcpu);
 349}
 350
 351void ipte_unlock(struct kvm_vcpu *vcpu)
 352{
 353        if (vcpu->arch.sie_block->eca & 1)
 354                ipte_unlock_siif(vcpu);
 355        else
 356                ipte_unlock_simple(vcpu);
 357}
 358
 359static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, ar_t ar,
 360                          int write)
 361{
 362        union alet alet;
 363        struct ale ale;
 364        struct aste aste;
 365        unsigned long ald_addr, authority_table_addr;
 366        union ald ald;
 367        int eax, rc;
 368        u8 authority_table;
 369
 370        if (ar >= NUM_ACRS)
 371                return -EINVAL;
 372
 373        save_access_regs(vcpu->run->s.regs.acrs);
 374        alet.val = vcpu->run->s.regs.acrs[ar];
 375
 376        if (ar == 0 || alet.val == 0) {
 377                asce->val = vcpu->arch.sie_block->gcr[1];
 378                return 0;
 379        } else if (alet.val == 1) {
 380                asce->val = vcpu->arch.sie_block->gcr[7];
 381                return 0;
 382        }
 383
 384        if (alet.reserved)
 385                return PGM_ALET_SPECIFICATION;
 386
 387        if (alet.p)
 388                ald_addr = vcpu->arch.sie_block->gcr[5];
 389        else
 390                ald_addr = vcpu->arch.sie_block->gcr[2];
 391        ald_addr &= 0x7fffffc0;
 392
 393        rc = read_guest_real(vcpu, ald_addr + 16, &ald.val, sizeof(union ald));
 394        if (rc)
 395                return rc;
 396
 397        if (alet.alen / 8 > ald.all)
 398                return PGM_ALEN_TRANSLATION;
 399
 400        if (0x7fffffff - ald.alo * 128 < alet.alen * 16)
 401                return PGM_ADDRESSING;
 402
 403        rc = read_guest_real(vcpu, ald.alo * 128 + alet.alen * 16, &ale,
 404                             sizeof(struct ale));
 405        if (rc)
 406                return rc;
 407
 408        if (ale.i == 1)
 409                return PGM_ALEN_TRANSLATION;
 410        if (ale.alesn != alet.alesn)
 411                return PGM_ALE_SEQUENCE;
 412
 413        rc = read_guest_real(vcpu, ale.asteo * 64, &aste, sizeof(struct aste));
 414        if (rc)
 415                return rc;
 416
 417        if (aste.i)
 418                return PGM_ASTE_VALIDITY;
 419        if (aste.astesn != ale.astesn)
 420                return PGM_ASTE_SEQUENCE;
 421
 422        if (ale.p == 1) {
 423                eax = (vcpu->arch.sie_block->gcr[8] >> 16) & 0xffff;
 424                if (ale.aleax != eax) {
 425                        if (eax / 16 > aste.atl)
 426                                return PGM_EXTENDED_AUTHORITY;
 427
 428                        authority_table_addr = aste.ato * 4 + eax / 4;
 429
 430                        rc = read_guest_real(vcpu, authority_table_addr,
 431                                             &authority_table,
 432                                             sizeof(u8));
 433                        if (rc)
 434                                return rc;
 435
 436                        if ((authority_table & (0x40 >> ((eax & 3) * 2))) == 0)
 437                                return PGM_EXTENDED_AUTHORITY;
 438                }
 439        }
 440
 441        if (ale.fo == 1 && write)
 442                return PGM_PROTECTION;
 443
 444        asce->val = aste.asce;
 445        return 0;
 446}
 447
 448struct trans_exc_code_bits {
 449        unsigned long addr : 52; /* Translation-exception Address */
 450        unsigned long fsi  : 2;  /* Access Exception Fetch/Store Indication */
 451        unsigned long      : 6;
 452        unsigned long b60  : 1;
 453        unsigned long b61  : 1;
 454        unsigned long as   : 2;  /* ASCE Identifier */
 455};
 456
 457enum {
 458        FSI_UNKNOWN = 0, /* Unknown wether fetch or store */
 459        FSI_STORE   = 1, /* Exception was due to store operation */
 460        FSI_FETCH   = 2  /* Exception was due to fetch operation */
 461};
 462
 463static int get_vcpu_asce(struct kvm_vcpu *vcpu, union asce *asce,
 464                         ar_t ar, int write)
 465{
 466        int rc;
 467        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 468        struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
 469        struct trans_exc_code_bits *tec_bits;
 470
 471        memset(pgm, 0, sizeof(*pgm));
 472        tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
 473        tec_bits->fsi = write ? FSI_STORE : FSI_FETCH;
 474        tec_bits->as = psw_bits(*psw).as;
 475
 476        if (!psw_bits(*psw).t) {
 477                asce->val = 0;
 478                asce->r = 1;
 479                return 0;
 480        }
 481
 482        switch (psw_bits(vcpu->arch.sie_block->gpsw).as) {
 483        case PSW_AS_PRIMARY:
 484                asce->val = vcpu->arch.sie_block->gcr[1];
 485                return 0;
 486        case PSW_AS_SECONDARY:
 487                asce->val = vcpu->arch.sie_block->gcr[7];
 488                return 0;
 489        case PSW_AS_HOME:
 490                asce->val = vcpu->arch.sie_block->gcr[13];
 491                return 0;
 492        case PSW_AS_ACCREG:
 493                rc = ar_translation(vcpu, asce, ar, write);
 494                switch (rc) {
 495                case PGM_ALEN_TRANSLATION:
 496                case PGM_ALE_SEQUENCE:
 497                case PGM_ASTE_VALIDITY:
 498                case PGM_ASTE_SEQUENCE:
 499                case PGM_EXTENDED_AUTHORITY:
 500                        vcpu->arch.pgm.exc_access_id = ar;
 501                        break;
 502                case PGM_PROTECTION:
 503                        tec_bits->b60 = 1;
 504                        tec_bits->b61 = 1;
 505                        break;
 506                }
 507                if (rc > 0)
 508                        pgm->code = rc;
 509                return rc;
 510        }
 511        return 0;
 512}
 513
 514static int deref_table(struct kvm *kvm, unsigned long gpa, unsigned long *val)
 515{
 516        return kvm_read_guest(kvm, gpa, val, sizeof(*val));
 517}
 518
 519/**
 520 * guest_translate - translate a guest virtual into a guest absolute address
 521 * @vcpu: virtual cpu
 522 * @gva: guest virtual address
 523 * @gpa: points to where guest physical (absolute) address should be stored
 524 * @asce: effective asce
 525 * @write: indicates if access is a write access
 526 *
 527 * Translate a guest virtual address into a guest absolute address by means
 528 * of dynamic address translation as specified by the architecture.
 529 * If the resulting absolute address is not available in the configuration
 530 * an addressing exception is indicated and @gpa will not be changed.
 531 *
 532 * Returns: - zero on success; @gpa contains the resulting absolute address
 533 *          - a negative value if guest access failed due to e.g. broken
 534 *            guest mapping
 535 *          - a positve value if an access exception happened. In this case
 536 *            the returned value is the program interruption code as defined
 537 *            by the architecture
 538 */
 539static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
 540                                     unsigned long *gpa, const union asce asce,
 541                                     int write)
 542{
 543        union vaddress vaddr = {.addr = gva};
 544        union raddress raddr = {.addr = gva};
 545        union page_table_entry pte;
 546        int dat_protection = 0;
 547        union ctlreg0 ctlreg0;
 548        unsigned long ptr;
 549        int edat1, edat2;
 550
 551        ctlreg0.val = vcpu->arch.sie_block->gcr[0];
 552        edat1 = ctlreg0.edat && test_kvm_facility(vcpu->kvm, 8);
 553        edat2 = edat1 && test_kvm_facility(vcpu->kvm, 78);
 554        if (asce.r)
 555                goto real_address;
 556        ptr = asce.origin * 4096;
 557        switch (asce.dt) {
 558        case ASCE_TYPE_REGION1:
 559                if (vaddr.rfx01 > asce.tl)
 560                        return PGM_REGION_FIRST_TRANS;
 561                ptr += vaddr.rfx * 8;
 562                break;
 563        case ASCE_TYPE_REGION2:
 564                if (vaddr.rfx)
 565                        return PGM_ASCE_TYPE;
 566                if (vaddr.rsx01 > asce.tl)
 567                        return PGM_REGION_SECOND_TRANS;
 568                ptr += vaddr.rsx * 8;
 569                break;
 570        case ASCE_TYPE_REGION3:
 571                if (vaddr.rfx || vaddr.rsx)
 572                        return PGM_ASCE_TYPE;
 573                if (vaddr.rtx01 > asce.tl)
 574                        return PGM_REGION_THIRD_TRANS;
 575                ptr += vaddr.rtx * 8;
 576                break;
 577        case ASCE_TYPE_SEGMENT:
 578                if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
 579                        return PGM_ASCE_TYPE;
 580                if (vaddr.sx01 > asce.tl)
 581                        return PGM_SEGMENT_TRANSLATION;
 582                ptr += vaddr.sx * 8;
 583                break;
 584        }
 585        switch (asce.dt) {
 586        case ASCE_TYPE_REGION1: {
 587                union region1_table_entry rfte;
 588
 589                if (kvm_is_error_gpa(vcpu->kvm, ptr))
 590                        return PGM_ADDRESSING;
 591                if (deref_table(vcpu->kvm, ptr, &rfte.val))
 592                        return -EFAULT;
 593                if (rfte.i)
 594                        return PGM_REGION_FIRST_TRANS;
 595                if (rfte.tt != TABLE_TYPE_REGION1)
 596                        return PGM_TRANSLATION_SPEC;
 597                if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
 598                        return PGM_REGION_SECOND_TRANS;
 599                if (edat1)
 600                        dat_protection |= rfte.p;
 601                ptr = rfte.rto * 4096 + vaddr.rsx * 8;
 602        }
 603                /* fallthrough */
 604        case ASCE_TYPE_REGION2: {
 605                union region2_table_entry rste;
 606
 607                if (kvm_is_error_gpa(vcpu->kvm, ptr))
 608                        return PGM_ADDRESSING;
 609                if (deref_table(vcpu->kvm, ptr, &rste.val))
 610                        return -EFAULT;
 611                if (rste.i)
 612                        return PGM_REGION_SECOND_TRANS;
 613                if (rste.tt != TABLE_TYPE_REGION2)
 614                        return PGM_TRANSLATION_SPEC;
 615                if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
 616                        return PGM_REGION_THIRD_TRANS;
 617                if (edat1)
 618                        dat_protection |= rste.p;
 619                ptr = rste.rto * 4096 + vaddr.rtx * 8;
 620        }
 621                /* fallthrough */
 622        case ASCE_TYPE_REGION3: {
 623                union region3_table_entry rtte;
 624
 625                if (kvm_is_error_gpa(vcpu->kvm, ptr))
 626                        return PGM_ADDRESSING;
 627                if (deref_table(vcpu->kvm, ptr, &rtte.val))
 628                        return -EFAULT;
 629                if (rtte.i)
 630                        return PGM_REGION_THIRD_TRANS;
 631                if (rtte.tt != TABLE_TYPE_REGION3)
 632                        return PGM_TRANSLATION_SPEC;
 633                if (rtte.cr && asce.p && edat2)
 634                        return PGM_TRANSLATION_SPEC;
 635                if (rtte.fc && edat2) {
 636                        dat_protection |= rtte.fc1.p;
 637                        raddr.rfaa = rtte.fc1.rfaa;
 638                        goto absolute_address;
 639                }
 640                if (vaddr.sx01 < rtte.fc0.tf)
 641                        return PGM_SEGMENT_TRANSLATION;
 642                if (vaddr.sx01 > rtte.fc0.tl)
 643                        return PGM_SEGMENT_TRANSLATION;
 644                if (edat1)
 645                        dat_protection |= rtte.fc0.p;
 646                ptr = rtte.fc0.sto * 4096 + vaddr.sx * 8;
 647        }
 648                /* fallthrough */
 649        case ASCE_TYPE_SEGMENT: {
 650                union segment_table_entry ste;
 651
 652                if (kvm_is_error_gpa(vcpu->kvm, ptr))
 653                        return PGM_ADDRESSING;
 654                if (deref_table(vcpu->kvm, ptr, &ste.val))
 655                        return -EFAULT;
 656                if (ste.i)
 657                        return PGM_SEGMENT_TRANSLATION;
 658                if (ste.tt != TABLE_TYPE_SEGMENT)
 659                        return PGM_TRANSLATION_SPEC;
 660                if (ste.cs && asce.p)
 661                        return PGM_TRANSLATION_SPEC;
 662                if (ste.fc && edat1) {
 663                        dat_protection |= ste.fc1.p;
 664                        raddr.sfaa = ste.fc1.sfaa;
 665                        goto absolute_address;
 666                }
 667                dat_protection |= ste.fc0.p;
 668                ptr = ste.fc0.pto * 2048 + vaddr.px * 8;
 669        }
 670        }
 671        if (kvm_is_error_gpa(vcpu->kvm, ptr))
 672                return PGM_ADDRESSING;
 673        if (deref_table(vcpu->kvm, ptr, &pte.val))
 674                return -EFAULT;
 675        if (pte.i)
 676                return PGM_PAGE_TRANSLATION;
 677        if (pte.z)
 678                return PGM_TRANSLATION_SPEC;
 679        if (pte.co && !edat1)
 680                return PGM_TRANSLATION_SPEC;
 681        dat_protection |= pte.p;
 682        raddr.pfra = pte.pfra;
 683real_address:
 684        raddr.addr = kvm_s390_real_to_abs(vcpu, raddr.addr);
 685absolute_address:
 686        if (write && dat_protection)
 687                return PGM_PROTECTION;
 688        if (kvm_is_error_gpa(vcpu->kvm, raddr.addr))
 689                return PGM_ADDRESSING;
 690        *gpa = raddr.addr;
 691        return 0;
 692}
 693
 694static inline int is_low_address(unsigned long ga)
 695{
 696        /* Check for address ranges 0..511 and 4096..4607 */
 697        return (ga & ~0x11fful) == 0;
 698}
 699
 700static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
 701                                          const union asce asce)
 702{
 703        union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};
 704        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 705
 706        if (!ctlreg0.lap)
 707                return 0;
 708        if (psw_bits(*psw).t && asce.p)
 709                return 0;
 710        return 1;
 711}
 712
 713static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga,
 714                            unsigned long *pages, unsigned long nr_pages,
 715                            const union asce asce, int write)
 716{
 717        struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
 718        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 719        struct trans_exc_code_bits *tec_bits;
 720        int lap_enabled, rc;
 721
 722        tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
 723        lap_enabled = low_address_protection_enabled(vcpu, asce);
 724        while (nr_pages) {
 725                ga = kvm_s390_logical_to_effective(vcpu, ga);
 726                tec_bits->addr = ga >> PAGE_SHIFT;
 727                if (write && lap_enabled && is_low_address(ga)) {
 728                        pgm->code = PGM_PROTECTION;
 729                        return pgm->code;
 730                }
 731                ga &= PAGE_MASK;
 732                if (psw_bits(*psw).t) {
 733                        rc = guest_translate(vcpu, ga, pages, asce, write);
 734                        if (rc < 0)
 735                                return rc;
 736                        if (rc == PGM_PROTECTION)
 737                                tec_bits->b61 = 1;
 738                        if (rc)
 739                                pgm->code = rc;
 740                } else {
 741                        *pages = kvm_s390_real_to_abs(vcpu, ga);
 742                        if (kvm_is_error_gpa(vcpu->kvm, *pages))
 743                                pgm->code = PGM_ADDRESSING;
 744                }
 745                if (pgm->code)
 746                        return pgm->code;
 747                ga += PAGE_SIZE;
 748                pages++;
 749                nr_pages--;
 750        }
 751        return 0;
 752}
 753
 754int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
 755                 unsigned long len, int write)
 756{
 757        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 758        unsigned long _len, nr_pages, gpa, idx;
 759        unsigned long pages_array[2];
 760        unsigned long *pages;
 761        int need_ipte_lock;
 762        union asce asce;
 763        int rc;
 764
 765        if (!len)
 766                return 0;
 767        rc = get_vcpu_asce(vcpu, &asce, ar, write);
 768        if (rc)
 769                return rc;
 770        nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
 771        pages = pages_array;
 772        if (nr_pages > ARRAY_SIZE(pages_array))
 773                pages = vmalloc(nr_pages * sizeof(unsigned long));
 774        if (!pages)
 775                return -ENOMEM;
 776        need_ipte_lock = psw_bits(*psw).t && !asce.r;
 777        if (need_ipte_lock)
 778                ipte_lock(vcpu);
 779        rc = guest_page_range(vcpu, ga, pages, nr_pages, asce, write);
 780        for (idx = 0; idx < nr_pages && !rc; idx++) {
 781                gpa = *(pages + idx) + (ga & ~PAGE_MASK);
 782                _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
 783                if (write)
 784                        rc = kvm_write_guest(vcpu->kvm, gpa, data, _len);
 785                else
 786                        rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
 787                len -= _len;
 788                ga += _len;
 789                data += _len;
 790        }
 791        if (need_ipte_lock)
 792                ipte_unlock(vcpu);
 793        if (nr_pages > ARRAY_SIZE(pages_array))
 794                vfree(pages);
 795        return rc;
 796}
 797
 798int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
 799                      void *data, unsigned long len, int write)
 800{
 801        unsigned long _len, gpa;
 802        int rc = 0;
 803
 804        while (len && !rc) {
 805                gpa = kvm_s390_real_to_abs(vcpu, gra);
 806                _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
 807                if (write)
 808                        rc = write_guest_abs(vcpu, gpa, data, _len);
 809                else
 810                        rc = read_guest_abs(vcpu, gpa, data, _len);
 811                len -= _len;
 812                gra += _len;
 813                data += _len;
 814        }
 815        return rc;
 816}
 817
 818/**
 819 * guest_translate_address - translate guest logical into guest absolute address
 820 *
 821 * Parameter semantics are the same as the ones from guest_translate.
 822 * The memory contents at the guest address are not changed.
 823 *
 824 * Note: The IPTE lock is not taken during this function, so the caller
 825 * has to take care of this.
 826 */
 827int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
 828                            unsigned long *gpa, int write)
 829{
 830        struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
 831        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 832        struct trans_exc_code_bits *tec;
 833        union asce asce;
 834        int rc;
 835
 836        gva = kvm_s390_logical_to_effective(vcpu, gva);
 837        tec = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
 838        rc = get_vcpu_asce(vcpu, &asce, ar, write);
 839        tec->addr = gva >> PAGE_SHIFT;
 840        if (rc)
 841                return rc;
 842        if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) {
 843                if (write) {
 844                        rc = pgm->code = PGM_PROTECTION;
 845                        return rc;
 846                }
 847        }
 848
 849        if (psw_bits(*psw).t && !asce.r) {      /* Use DAT? */
 850                rc = guest_translate(vcpu, gva, gpa, asce, write);
 851                if (rc > 0) {
 852                        if (rc == PGM_PROTECTION)
 853                                tec->b61 = 1;
 854                        pgm->code = rc;
 855                }
 856        } else {
 857                rc = 0;
 858                *gpa = kvm_s390_real_to_abs(vcpu, gva);
 859                if (kvm_is_error_gpa(vcpu->kvm, *gpa))
 860                        rc = pgm->code = PGM_ADDRESSING;
 861        }
 862
 863        return rc;
 864}
 865
 866/**
 867 * check_gva_range - test a range of guest virtual addresses for accessibility
 868 */
 869int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
 870                    unsigned long length, int is_write)
 871{
 872        unsigned long gpa;
 873        unsigned long currlen;
 874        int rc = 0;
 875
 876        ipte_lock(vcpu);
 877        while (length > 0 && !rc) {
 878                currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
 879                rc = guest_translate_address(vcpu, gva, ar, &gpa, is_write);
 880                gva += currlen;
 881                length -= currlen;
 882        }
 883        ipte_unlock(vcpu);
 884
 885        return rc;
 886}
 887
 888/**
 889 * kvm_s390_check_low_addr_prot_real - check for low-address protection
 890 * @gra: Guest real address
 891 *
 892 * Checks whether an address is subject to low-address protection and set
 893 * up vcpu->arch.pgm accordingly if necessary.
 894 *
 895 * Return: 0 if no protection exception, or PGM_PROTECTION if protected.
 896 */
 897int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra)
 898{
 899        struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
 900        psw_t *psw = &vcpu->arch.sie_block->gpsw;
 901        struct trans_exc_code_bits *tec_bits;
 902        union ctlreg0 ctlreg0 = {.val = vcpu->arch.sie_block->gcr[0]};
 903
 904        if (!ctlreg0.lap || !is_low_address(gra))
 905                return 0;
 906
 907        memset(pgm, 0, sizeof(*pgm));
 908        tec_bits = (struct trans_exc_code_bits *)&pgm->trans_exc_code;
 909        tec_bits->fsi = FSI_STORE;
 910        tec_bits->as = psw_bits(*psw).as;
 911        tec_bits->addr = gra >> PAGE_SHIFT;
 912        pgm->code = PGM_PROTECTION;
 913
 914        return pgm->code;
 915}
 916