linux/arch/powerpc/kvm/booke_emulate.c
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or modify
   3 * it under the terms of the GNU General Public License, version 2, as
   4 * published by the Free Software Foundation.
   5 *
   6 * This program is distributed in the hope that it will be useful,
   7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   9 * GNU General Public License for more details.
  10 *
  11 * You should have received a copy of the GNU General Public License
  12 * along with this program; if not, write to the Free Software
  13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  14 *
  15 * Copyright IBM Corp. 2008
  16 * Copyright 2011 Freescale Semiconductor, Inc.
  17 *
  18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  19 */
  20
  21#include <linux/kvm_host.h>
  22#include <asm/disassemble.h>
  23
  24#include "booke.h"
  25
  26#define OP_19_XOP_RFI     50
  27#define OP_19_XOP_RFCI    51
  28
  29#define OP_31_XOP_MFMSR   83
  30#define OP_31_XOP_WRTEE   131
  31#define OP_31_XOP_MTMSR   146
  32#define OP_31_XOP_WRTEEI  163
  33
  34static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
  35{
  36        vcpu->arch.pc = vcpu->arch.shared->srr0;
  37        kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
  38}
  39
  40static void kvmppc_emul_rfci(struct kvm_vcpu *vcpu)
  41{
  42        vcpu->arch.pc = vcpu->arch.csrr0;
  43        kvmppc_set_msr(vcpu, vcpu->arch.csrr1);
  44}
  45
  46int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
  47                            unsigned int inst, int *advance)
  48{
  49        int emulated = EMULATE_DONE;
  50        int rs = get_rs(inst);
  51        int rt = get_rt(inst);
  52
  53        switch (get_op(inst)) {
  54        case 19:
  55                switch (get_xop(inst)) {
  56                case OP_19_XOP_RFI:
  57                        kvmppc_emul_rfi(vcpu);
  58                        kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
  59                        *advance = 0;
  60                        break;
  61
  62                case OP_19_XOP_RFCI:
  63                        kvmppc_emul_rfci(vcpu);
  64                        kvmppc_set_exit_type(vcpu, EMULATED_RFCI_EXITS);
  65                        *advance = 0;
  66                        break;
  67
  68                default:
  69                        emulated = EMULATE_FAIL;
  70                        break;
  71                }
  72                break;
  73
  74        case 31:
  75                switch (get_xop(inst)) {
  76
  77                case OP_31_XOP_MFMSR:
  78                        kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
  79                        kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
  80                        break;
  81
  82                case OP_31_XOP_MTMSR:
  83                        kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
  84                        kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
  85                        break;
  86
  87                case OP_31_XOP_WRTEE:
  88                        vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
  89                                        | (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
  90                        kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
  91                        break;
  92
  93                case OP_31_XOP_WRTEEI:
  94                        vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
  95                                                         | (inst & MSR_EE);
  96                        kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
  97                        break;
  98
  99                default:
 100                        emulated = EMULATE_FAIL;
 101                }
 102
 103                break;
 104
 105        default:
 106                emulated = EMULATE_FAIL;
 107        }
 108
 109        return emulated;
 110}
 111
 112/*
 113 * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode).
 114 * Their backing store is in real registers, and these functions
 115 * will return the wrong result if called for them in another context
 116 * (such as debugging).
 117 */
 118int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
 119{
 120        int emulated = EMULATE_DONE;
 121
 122        switch (sprn) {
 123        case SPRN_DEAR:
 124                vcpu->arch.shared->dar = spr_val;
 125                break;
 126        case SPRN_ESR:
 127                vcpu->arch.shared->esr = spr_val;
 128                break;
 129        case SPRN_CSRR0:
 130                vcpu->arch.csrr0 = spr_val;
 131                break;
 132        case SPRN_CSRR1:
 133                vcpu->arch.csrr1 = spr_val;
 134                break;
 135        case SPRN_DBCR0:
 136                vcpu->arch.dbg_reg.dbcr0 = spr_val;
 137                break;
 138        case SPRN_DBCR1:
 139                vcpu->arch.dbg_reg.dbcr1 = spr_val;
 140                break;
 141        case SPRN_DBSR:
 142                vcpu->arch.dbsr &= ~spr_val;
 143                break;
 144        case SPRN_TSR:
 145                kvmppc_clr_tsr_bits(vcpu, spr_val);
 146                break;
 147        case SPRN_TCR:
 148                /*
 149                 * WRC is a 2-bit field that is supposed to preserve its
 150                 * value once written to non-zero.
 151                 */
 152                if (vcpu->arch.tcr & TCR_WRC_MASK) {
 153                        spr_val &= ~TCR_WRC_MASK;
 154                        spr_val |= vcpu->arch.tcr & TCR_WRC_MASK;
 155                }
 156                kvmppc_set_tcr(vcpu, spr_val);
 157                break;
 158
 159        case SPRN_DECAR:
 160                vcpu->arch.decar = spr_val;
 161                break;
 162        /*
 163         * Note: SPRG4-7 are user-readable.
 164         * These values are loaded into the real SPRGs when resuming the
 165         * guest (PR-mode only).
 166         */
 167        case SPRN_SPRG4:
 168                vcpu->arch.shared->sprg4 = spr_val;
 169                break;
 170        case SPRN_SPRG5:
 171                vcpu->arch.shared->sprg5 = spr_val;
 172                break;
 173        case SPRN_SPRG6:
 174                vcpu->arch.shared->sprg6 = spr_val;
 175                break;
 176        case SPRN_SPRG7:
 177                vcpu->arch.shared->sprg7 = spr_val;
 178                break;
 179
 180        case SPRN_IVPR:
 181                vcpu->arch.ivpr = spr_val;
 182#ifdef CONFIG_KVM_BOOKE_HV
 183                mtspr(SPRN_GIVPR, spr_val);
 184#endif
 185                break;
 186        case SPRN_IVOR0:
 187                vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
 188                break;
 189        case SPRN_IVOR1:
 190                vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = spr_val;
 191                break;
 192        case SPRN_IVOR2:
 193                vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
 194#ifdef CONFIG_KVM_BOOKE_HV
 195                mtspr(SPRN_GIVOR2, spr_val);
 196#endif
 197                break;
 198        case SPRN_IVOR3:
 199                vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
 200                break;
 201        case SPRN_IVOR4:
 202                vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = spr_val;
 203                break;
 204        case SPRN_IVOR5:
 205                vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = spr_val;
 206                break;
 207        case SPRN_IVOR6:
 208                vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = spr_val;
 209                break;
 210        case SPRN_IVOR7:
 211                vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = spr_val;
 212                break;
 213        case SPRN_IVOR8:
 214                vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
 215#ifdef CONFIG_KVM_BOOKE_HV
 216                mtspr(SPRN_GIVOR8, spr_val);
 217#endif
 218                break;
 219        case SPRN_IVOR9:
 220                vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
 221                break;
 222        case SPRN_IVOR10:
 223                vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = spr_val;
 224                break;
 225        case SPRN_IVOR11:
 226                vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = spr_val;
 227                break;
 228        case SPRN_IVOR12:
 229                vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = spr_val;
 230                break;
 231        case SPRN_IVOR13:
 232                vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = spr_val;
 233                break;
 234        case SPRN_IVOR14:
 235                vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = spr_val;
 236                break;
 237        case SPRN_IVOR15:
 238                vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = spr_val;
 239                break;
 240        case SPRN_MCSR:
 241                vcpu->arch.mcsr &= ~spr_val;
 242                break;
 243#if defined(CONFIG_64BIT)
 244        case SPRN_EPCR:
 245                kvmppc_set_epcr(vcpu, spr_val);
 246#ifdef CONFIG_KVM_BOOKE_HV
 247                mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr);
 248#endif
 249                break;
 250#endif
 251        default:
 252                emulated = EMULATE_FAIL;
 253        }
 254
 255        return emulated;
 256}
 257
 258int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
 259{
 260        int emulated = EMULATE_DONE;
 261
 262        switch (sprn) {
 263        case SPRN_IVPR:
 264                *spr_val = vcpu->arch.ivpr;
 265                break;
 266        case SPRN_DEAR:
 267                *spr_val = vcpu->arch.shared->dar;
 268                break;
 269        case SPRN_ESR:
 270                *spr_val = vcpu->arch.shared->esr;
 271                break;
 272        case SPRN_EPR:
 273                *spr_val = vcpu->arch.epr;
 274                break;
 275        case SPRN_CSRR0:
 276                *spr_val = vcpu->arch.csrr0;
 277                break;
 278        case SPRN_CSRR1:
 279                *spr_val = vcpu->arch.csrr1;
 280                break;
 281        case SPRN_DBCR0:
 282                *spr_val = vcpu->arch.dbg_reg.dbcr0;
 283                break;
 284        case SPRN_DBCR1:
 285                *spr_val = vcpu->arch.dbg_reg.dbcr1;
 286                break;
 287        case SPRN_DBSR:
 288                *spr_val = vcpu->arch.dbsr;
 289                break;
 290        case SPRN_TSR:
 291                *spr_val = vcpu->arch.tsr;
 292                break;
 293        case SPRN_TCR:
 294                *spr_val = vcpu->arch.tcr;
 295                break;
 296
 297        case SPRN_IVOR0:
 298                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
 299                break;
 300        case SPRN_IVOR1:
 301                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
 302                break;
 303        case SPRN_IVOR2:
 304                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
 305                break;
 306        case SPRN_IVOR3:
 307                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
 308                break;
 309        case SPRN_IVOR4:
 310                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
 311                break;
 312        case SPRN_IVOR5:
 313                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
 314                break;
 315        case SPRN_IVOR6:
 316                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
 317                break;
 318        case SPRN_IVOR7:
 319                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
 320                break;
 321        case SPRN_IVOR8:
 322                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
 323                break;
 324        case SPRN_IVOR9:
 325                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
 326                break;
 327        case SPRN_IVOR10:
 328                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
 329                break;
 330        case SPRN_IVOR11:
 331                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
 332                break;
 333        case SPRN_IVOR12:
 334                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
 335                break;
 336        case SPRN_IVOR13:
 337                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
 338                break;
 339        case SPRN_IVOR14:
 340                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
 341                break;
 342        case SPRN_IVOR15:
 343                *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
 344                break;
 345        case SPRN_MCSR:
 346                *spr_val = vcpu->arch.mcsr;
 347                break;
 348#if defined(CONFIG_64BIT)
 349        case SPRN_EPCR:
 350                *spr_val = vcpu->arch.epcr;
 351                break;
 352#endif
 353
 354        default:
 355                emulated = EMULATE_FAIL;
 356        }
 357
 358        return emulated;
 359}
 360