root/arch/powerpc/kvm/book3s_32_mmu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_debug_ip
  2. sr_vsid
  3. sr_valid
  4. sr_ks
  5. sr_kp
  6. find_sr
  7. kvmppc_mmu_book3s_32_ea_to_vp
  8. kvmppc_mmu_book3s_32_reset_msr
  9. kvmppc_mmu_book3s_32_get_pteg
  10. kvmppc_mmu_book3s_32_get_ptem
  11. kvmppc_mmu_book3s_32_xlate_bat
  12. kvmppc_mmu_book3s_32_xlate_pte
  13. kvmppc_mmu_book3s_32_xlate
  14. kvmppc_mmu_book3s_32_mfsrin
  15. kvmppc_mmu_book3s_32_mtsrin
  16. kvmppc_mmu_book3s_32_tlbie
  17. kvmppc_mmu_book3s_32_esid_to_vsid
  18. kvmppc_mmu_book3s_32_is_dcbz32
  19. kvmppc_mmu_book3s_32_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  * Copyright SUSE Linux Products GmbH 2009
   5  *
   6  * Authors: Alexander Graf <agraf@suse.de>
   7  */
   8 
   9 #include <linux/types.h>
  10 #include <linux/string.h>
  11 #include <linux/kvm.h>
  12 #include <linux/kvm_host.h>
  13 #include <linux/highmem.h>
  14 
  15 #include <asm/kvm_ppc.h>
  16 #include <asm/kvm_book3s.h>
  17 
  18 /* #define DEBUG_MMU */
  19 /* #define DEBUG_MMU_PTE */
  20 /* #define DEBUG_MMU_PTE_IP 0xfff14c40 */
  21 
  22 #ifdef DEBUG_MMU
  23 #define dprintk(X...) printk(KERN_INFO X)
  24 #else
  25 #define dprintk(X...) do { } while(0)
  26 #endif
  27 
  28 #ifdef DEBUG_MMU_PTE
  29 #define dprintk_pte(X...) printk(KERN_INFO X)
  30 #else
  31 #define dprintk_pte(X...) do { } while(0)
  32 #endif
  33 
  34 #define PTEG_FLAG_ACCESSED      0x00000100
  35 #define PTEG_FLAG_DIRTY         0x00000080
  36 #ifndef SID_SHIFT
  37 #define SID_SHIFT               28
  38 #endif
  39 
  40 static inline bool check_debug_ip(struct kvm_vcpu *vcpu)
  41 {
  42 #ifdef DEBUG_MMU_PTE_IP
  43         return vcpu->arch.regs.nip == DEBUG_MMU_PTE_IP;
  44 #else
  45         return true;
  46 #endif
  47 }
  48 
  49 static inline u32 sr_vsid(u32 sr_raw)
  50 {
  51         return sr_raw & 0x0fffffff;
  52 }
  53 
  54 static inline bool sr_valid(u32 sr_raw)
  55 {
  56         return (sr_raw & 0x80000000) ? false : true;
  57 }
  58 
  59 static inline bool sr_ks(u32 sr_raw)
  60 {
  61         return (sr_raw & 0x40000000) ? true: false;
  62 }
  63 
  64 static inline bool sr_kp(u32 sr_raw)
  65 {
  66         return (sr_raw & 0x20000000) ? true: false;
  67 }
  68 
  69 static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
  70                                           struct kvmppc_pte *pte, bool data,
  71                                           bool iswrite);
  72 static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
  73                                              u64 *vsid);
  74 
  75 static u32 find_sr(struct kvm_vcpu *vcpu, gva_t eaddr)
  76 {
  77         return kvmppc_get_sr(vcpu, (eaddr >> 28) & 0xf);
  78 }
  79 
  80 static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
  81                                          bool data)
  82 {
  83         u64 vsid;
  84         struct kvmppc_pte pte;
  85 
  86         if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data, false))
  87                 return pte.vpage;
  88 
  89         kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid);
  90         return (((u64)eaddr >> 12) & 0xffff) | (vsid << 16);
  91 }
  92 
  93 static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
  94 {
  95         kvmppc_set_msr(vcpu, 0);
  96 }
  97 
  98 static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvm_vcpu *vcpu,
  99                                       u32 sre, gva_t eaddr,
 100                                       bool primary)
 101 {
 102         struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
 103         u32 page, hash, pteg, htabmask;
 104         hva_t r;
 105 
 106         page = (eaddr & 0x0FFFFFFF) >> 12;
 107         htabmask = ((vcpu_book3s->sdr1 & 0x1FF) << 16) | 0xFFC0;
 108 
 109         hash = ((sr_vsid(sre) ^ page) << 6);
 110         if (!primary)
 111                 hash = ~hash;
 112         hash &= htabmask;
 113 
 114         pteg = (vcpu_book3s->sdr1 & 0xffff0000) | hash;
 115 
 116         dprintk("MMU: pc=0x%lx eaddr=0x%lx sdr1=0x%llx pteg=0x%x vsid=0x%x\n",
 117                 kvmppc_get_pc(vcpu), eaddr, vcpu_book3s->sdr1, pteg,
 118                 sr_vsid(sre));
 119 
 120         r = gfn_to_hva(vcpu->kvm, pteg >> PAGE_SHIFT);
 121         if (kvm_is_error_hva(r))
 122                 return r;
 123         return r | (pteg & ~PAGE_MASK);
 124 }
 125 
 126 static u32 kvmppc_mmu_book3s_32_get_ptem(u32 sre, gva_t eaddr, bool primary)
 127 {
 128         return ((eaddr & 0x0fffffff) >> 22) | (sr_vsid(sre) << 7) |
 129                (primary ? 0 : 0x40) | 0x80000000;
 130 }
 131 
 132 static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr,
 133                                           struct kvmppc_pte *pte, bool data,
 134                                           bool iswrite)
 135 {
 136         struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
 137         struct kvmppc_bat *bat;
 138         int i;
 139 
 140         for (i = 0; i < 8; i++) {
 141                 if (data)
 142                         bat = &vcpu_book3s->dbat[i];
 143                 else
 144                         bat = &vcpu_book3s->ibat[i];
 145 
 146                 if (kvmppc_get_msr(vcpu) & MSR_PR) {
 147                         if (!bat->vp)
 148                                 continue;
 149                 } else {
 150                         if (!bat->vs)
 151                                 continue;
 152                 }
 153 
 154                 if (check_debug_ip(vcpu))
 155                 {
 156                         dprintk_pte("%cBAT %02d: 0x%lx - 0x%x (0x%x)\n",
 157                                     data ? 'd' : 'i', i, eaddr, bat->bepi,
 158                                     bat->bepi_mask);
 159                 }
 160                 if ((eaddr & bat->bepi_mask) == bat->bepi) {
 161                         u64 vsid;
 162                         kvmppc_mmu_book3s_32_esid_to_vsid(vcpu,
 163                                 eaddr >> SID_SHIFT, &vsid);
 164                         vsid <<= 16;
 165                         pte->vpage = (((u64)eaddr >> 12) & 0xffff) | vsid;
 166 
 167                         pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask);
 168                         pte->may_read = bat->pp;
 169                         pte->may_write = bat->pp > 1;
 170                         pte->may_execute = true;
 171                         if (!pte->may_read) {
 172                                 printk(KERN_INFO "BAT is not readable!\n");
 173                                 continue;
 174                         }
 175                         if (iswrite && !pte->may_write) {
 176                                 dprintk_pte("BAT is read-only!\n");
 177                                 continue;
 178                         }
 179 
 180                         return 0;
 181                 }
 182         }
 183 
 184         return -ENOENT;
 185 }
 186 
 187 static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
 188                                      struct kvmppc_pte *pte, bool data,
 189                                      bool iswrite, bool primary)
 190 {
 191         u32 sre;
 192         hva_t ptegp;
 193         u32 pteg[16];
 194         u32 pte0, pte1;
 195         u32 ptem = 0;
 196         int i;
 197         int found = 0;
 198 
 199         sre = find_sr(vcpu, eaddr);
 200 
 201         dprintk_pte("SR 0x%lx: vsid=0x%x, raw=0x%x\n", eaddr >> 28,
 202                     sr_vsid(sre), sre);
 203 
 204         pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
 205 
 206         ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu, sre, eaddr, primary);
 207         if (kvm_is_error_hva(ptegp)) {
 208                 printk(KERN_INFO "KVM: Invalid PTEG!\n");
 209                 goto no_page_found;
 210         }
 211 
 212         ptem = kvmppc_mmu_book3s_32_get_ptem(sre, eaddr, primary);
 213 
 214         if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) {
 215                 printk_ratelimited(KERN_ERR
 216                         "KVM: Can't copy data from 0x%lx!\n", ptegp);
 217                 goto no_page_found;
 218         }
 219 
 220         for (i=0; i<16; i+=2) {
 221                 pte0 = be32_to_cpu(pteg[i]);
 222                 pte1 = be32_to_cpu(pteg[i + 1]);
 223                 if (ptem == pte0) {
 224                         u8 pp;
 225 
 226                         pte->raddr = (pte1 & ~(0xFFFULL)) | (eaddr & 0xFFF);
 227                         pp = pte1 & 3;
 228 
 229                         if ((sr_kp(sre) &&  (kvmppc_get_msr(vcpu) & MSR_PR)) ||
 230                             (sr_ks(sre) && !(kvmppc_get_msr(vcpu) & MSR_PR)))
 231                                 pp |= 4;
 232 
 233                         pte->may_write = false;
 234                         pte->may_read = false;
 235                         pte->may_execute = true;
 236                         switch (pp) {
 237                                 case 0:
 238                                 case 1:
 239                                 case 2:
 240                                 case 6:
 241                                         pte->may_write = true;
 242                                         /* fall through */
 243                                 case 3:
 244                                 case 5:
 245                                 case 7:
 246                                         pte->may_read = true;
 247                                         break;
 248                         }
 249 
 250                         dprintk_pte("MMU: Found PTE -> %x %x - %x\n",
 251                                     pte0, pte1, pp);
 252                         found = 1;
 253                         break;
 254                 }
 255         }
 256 
 257         /* Update PTE C and A bits, so the guest's swapper knows we used the
 258            page */
 259         if (found) {
 260                 u32 pte_r = pte1;
 261                 char __user *addr = (char __user *) (ptegp + (i+1) * sizeof(u32));
 262 
 263                 /*
 264                  * Use single-byte writes to update the HPTE, to
 265                  * conform to what real hardware does.
 266                  */
 267                 if (pte->may_read && !(pte_r & PTEG_FLAG_ACCESSED)) {
 268                         pte_r |= PTEG_FLAG_ACCESSED;
 269                         put_user(pte_r >> 8, addr + 2);
 270                 }
 271                 if (iswrite && pte->may_write && !(pte_r & PTEG_FLAG_DIRTY)) {
 272                         pte_r |= PTEG_FLAG_DIRTY;
 273                         put_user(pte_r, addr + 3);
 274                 }
 275                 if (!pte->may_read || (iswrite && !pte->may_write))
 276                         return -EPERM;
 277                 return 0;
 278         }
 279 
 280 no_page_found:
 281 
 282         if (check_debug_ip(vcpu)) {
 283                 dprintk_pte("KVM MMU: No PTE found (sdr1=0x%llx ptegp=0x%lx)\n",
 284                             to_book3s(vcpu)->sdr1, ptegp);
 285                 for (i=0; i<16; i+=2) {
 286                         dprintk_pte("   %02d: 0x%x - 0x%x (0x%x)\n",
 287                                     i, be32_to_cpu(pteg[i]),
 288                                     be32_to_cpu(pteg[i+1]), ptem);
 289                 }
 290         }
 291 
 292         return -ENOENT;
 293 }
 294 
 295 static int kvmppc_mmu_book3s_32_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
 296                                       struct kvmppc_pte *pte, bool data,
 297                                       bool iswrite)
 298 {
 299         int r;
 300         ulong mp_ea = vcpu->arch.magic_page_ea;
 301 
 302         pte->eaddr = eaddr;
 303         pte->page_size = MMU_PAGE_4K;
 304 
 305         /* Magic page override */
 306         if (unlikely(mp_ea) &&
 307             unlikely((eaddr & ~0xfffULL) == (mp_ea & ~0xfffULL)) &&
 308             !(kvmppc_get_msr(vcpu) & MSR_PR)) {
 309                 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
 310                 pte->raddr = vcpu->arch.magic_page_pa | (pte->raddr & 0xfff);
 311                 pte->raddr &= KVM_PAM;
 312                 pte->may_execute = true;
 313                 pte->may_read = true;
 314                 pte->may_write = true;
 315 
 316                 return 0;
 317         }
 318 
 319         r = kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, pte, data, iswrite);
 320         if (r < 0)
 321                 r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte,
 322                                                    data, iswrite, true);
 323         if (r == -ENOENT)
 324                 r = kvmppc_mmu_book3s_32_xlate_pte(vcpu, eaddr, pte,
 325                                                    data, iswrite, false);
 326 
 327         return r;
 328 }
 329 
 330 
 331 static u32 kvmppc_mmu_book3s_32_mfsrin(struct kvm_vcpu *vcpu, u32 srnum)
 332 {
 333         return kvmppc_get_sr(vcpu, srnum);
 334 }
 335 
 336 static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum,
 337                                         ulong value)
 338 {
 339         kvmppc_set_sr(vcpu, srnum, value);
 340         kvmppc_mmu_map_segment(vcpu, srnum << SID_SHIFT);
 341 }
 342 
 343 static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large)
 344 {
 345         int i;
 346         struct kvm_vcpu *v;
 347 
 348         /* flush this VA on all cpus */
 349         kvm_for_each_vcpu(i, v, vcpu->kvm)
 350                 kvmppc_mmu_pte_flush(v, ea, 0x0FFFF000);
 351 }
 352 
 353 static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, ulong esid,
 354                                              u64 *vsid)
 355 {
 356         ulong ea = esid << SID_SHIFT;
 357         u32 sr;
 358         u64 gvsid = esid;
 359         u64 msr = kvmppc_get_msr(vcpu);
 360 
 361         if (msr & (MSR_DR|MSR_IR)) {
 362                 sr = find_sr(vcpu, ea);
 363                 if (sr_valid(sr))
 364                         gvsid = sr_vsid(sr);
 365         }
 366 
 367         /* In case we only have one of MSR_IR or MSR_DR set, let's put
 368            that in the real-mode context (and hope RM doesn't access
 369            high memory) */
 370         switch (msr & (MSR_DR|MSR_IR)) {
 371         case 0:
 372                 *vsid = VSID_REAL | esid;
 373                 break;
 374         case MSR_IR:
 375                 *vsid = VSID_REAL_IR | gvsid;
 376                 break;
 377         case MSR_DR:
 378                 *vsid = VSID_REAL_DR | gvsid;
 379                 break;
 380         case MSR_DR|MSR_IR:
 381                 if (sr_valid(sr))
 382                         *vsid = sr_vsid(sr);
 383                 else
 384                         *vsid = VSID_BAT | gvsid;
 385                 break;
 386         default:
 387                 BUG();
 388         }
 389 
 390         if (msr & MSR_PR)
 391                 *vsid |= VSID_PR;
 392 
 393         return 0;
 394 }
 395 
 396 static bool kvmppc_mmu_book3s_32_is_dcbz32(struct kvm_vcpu *vcpu)
 397 {
 398         return true;
 399 }
 400 
 401 
 402 void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu)
 403 {
 404         struct kvmppc_mmu *mmu = &vcpu->arch.mmu;
 405 
 406         mmu->mtsrin = kvmppc_mmu_book3s_32_mtsrin;
 407         mmu->mfsrin = kvmppc_mmu_book3s_32_mfsrin;
 408         mmu->xlate = kvmppc_mmu_book3s_32_xlate;
 409         mmu->reset_msr = kvmppc_mmu_book3s_32_reset_msr;
 410         mmu->tlbie = kvmppc_mmu_book3s_32_tlbie;
 411         mmu->esid_to_vsid = kvmppc_mmu_book3s_32_esid_to_vsid;
 412         mmu->ea_to_vp = kvmppc_mmu_book3s_32_ea_to_vp;
 413         mmu->is_dcbz32 = kvmppc_mmu_book3s_32_is_dcbz32;
 414 
 415         mmu->slbmte = NULL;
 416         mmu->slbmfee = NULL;
 417         mmu->slbmfev = NULL;
 418         mmu->slbfee = NULL;
 419         mmu->slbie = NULL;
 420         mmu->slbia = NULL;
 421 }

/* [<][>][^][v][top][bottom][index][help] */