linux/arch/powerpc/kvm/book3s_hv_rmhandlers.S
<<
>>
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 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  12 *
  13 * Derived from book3s_rmhandlers.S and other files, which are:
  14 *
  15 * Copyright SUSE Linux Products GmbH 2009
  16 *
  17 * Authors: Alexander Graf <agraf@suse.de>
  18 */
  19
  20#include <asm/ppc_asm.h>
  21#include <asm/kvm_asm.h>
  22#include <asm/reg.h>
  23#include <asm/page.h>
  24#include <asm/asm-offsets.h>
  25#include <asm/exception-64s.h>
  26
  27/*****************************************************************************
  28 *                                                                           *
  29 *        Real Mode handlers that need to be in the linear mapping           *
  30 *                                                                           *
  31 ****************************************************************************/
  32
  33        .globl  kvmppc_skip_interrupt
  34kvmppc_skip_interrupt:
  35        mfspr   r13,SPRN_SRR0
  36        addi    r13,r13,4
  37        mtspr   SPRN_SRR0,r13
  38        GET_SCRATCH0(r13)
  39        rfid
  40        b       .
  41
  42        .globl  kvmppc_skip_Hinterrupt
  43kvmppc_skip_Hinterrupt:
  44        mfspr   r13,SPRN_HSRR0
  45        addi    r13,r13,4
  46        mtspr   SPRN_HSRR0,r13
  47        GET_SCRATCH0(r13)
  48        hrfid
  49        b       .
  50
  51/*
  52 * Call kvmppc_handler_trampoline_enter in real mode.
  53 * Must be called with interrupts hard-disabled.
  54 *
  55 * Input Registers:
  56 *
  57 * LR = return address to continue at after eventually re-enabling MMU
  58 */
  59_GLOBAL(kvmppc_hv_entry_trampoline)
  60        mfmsr   r10
  61        LOAD_REG_ADDR(r5, kvmppc_hv_entry)
  62        li      r0,MSR_RI
  63        andc    r0,r10,r0
  64        li      r6,MSR_IR | MSR_DR
  65        andc    r6,r10,r6
  66        mtmsrd  r0,1            /* clear RI in MSR */
  67        mtsrr0  r5
  68        mtsrr1  r6
  69        RFI
  70
  71#define ULONG_SIZE              8
  72#define VCPU_GPR(n)             (VCPU_GPRS + (n * ULONG_SIZE))
  73
  74/******************************************************************************
  75 *                                                                            *
  76 *                               Entry code                                   *
  77 *                                                                            *
  78 *****************************************************************************/
  79
  80#define XICS_XIRR               4
  81#define XICS_QIRR               0xc
  82
  83/*
  84 * We come in here when wakened from nap mode on a secondary hw thread.
  85 * Relocation is off and most register values are lost.
  86 * r13 points to the PACA.
  87 */
  88        .globl  kvm_start_guest
  89kvm_start_guest:
  90        ld      r1,PACAEMERGSP(r13)
  91        subi    r1,r1,STACK_FRAME_OVERHEAD
  92
  93        /* get vcpu pointer */
  94        ld      r4, HSTATE_KVM_VCPU(r13)
  95
  96        /* We got here with an IPI; clear it */
  97        ld      r5, HSTATE_XICS_PHYS(r13)
  98        li      r0, 0xff
  99        li      r6, XICS_QIRR
 100        li      r7, XICS_XIRR
 101        lwzcix  r8, r5, r7              /* ack the interrupt */
 102        sync
 103        stbcix  r0, r5, r6              /* clear it */
 104        stwcix  r8, r5, r7              /* EOI it */
 105
 106.global kvmppc_hv_entry
 107kvmppc_hv_entry:
 108
 109        /* Required state:
 110         *
 111         * R4 = vcpu pointer
 112         * MSR = ~IR|DR
 113         * R13 = PACA
 114         * R1 = host R1
 115         * all other volatile GPRS = free
 116         */
 117        mflr    r0
 118        std     r0, HSTATE_VMHANDLER(r13)
 119
 120        ld      r14, VCPU_GPR(r14)(r4)
 121        ld      r15, VCPU_GPR(r15)(r4)
 122        ld      r16, VCPU_GPR(r16)(r4)
 123        ld      r17, VCPU_GPR(r17)(r4)
 124        ld      r18, VCPU_GPR(r18)(r4)
 125        ld      r19, VCPU_GPR(r19)(r4)
 126        ld      r20, VCPU_GPR(r20)(r4)
 127        ld      r21, VCPU_GPR(r21)(r4)
 128        ld      r22, VCPU_GPR(r22)(r4)
 129        ld      r23, VCPU_GPR(r23)(r4)
 130        ld      r24, VCPU_GPR(r24)(r4)
 131        ld      r25, VCPU_GPR(r25)(r4)
 132        ld      r26, VCPU_GPR(r26)(r4)
 133        ld      r27, VCPU_GPR(r27)(r4)
 134        ld      r28, VCPU_GPR(r28)(r4)
 135        ld      r29, VCPU_GPR(r29)(r4)
 136        ld      r30, VCPU_GPR(r30)(r4)
 137        ld      r31, VCPU_GPR(r31)(r4)
 138
 139        /* Load guest PMU registers */
 140        /* R4 is live here (vcpu pointer) */
 141        li      r3, 1
 142        sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
 143        mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
 144        isync
 145        lwz     r3, VCPU_PMC(r4)        /* always load up guest PMU registers */
 146        lwz     r5, VCPU_PMC + 4(r4)    /* to prevent information leak */
 147        lwz     r6, VCPU_PMC + 8(r4)
 148        lwz     r7, VCPU_PMC + 12(r4)
 149        lwz     r8, VCPU_PMC + 16(r4)
 150        lwz     r9, VCPU_PMC + 20(r4)
 151BEGIN_FTR_SECTION
 152        lwz     r10, VCPU_PMC + 24(r4)
 153        lwz     r11, VCPU_PMC + 28(r4)
 154END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 155        mtspr   SPRN_PMC1, r3
 156        mtspr   SPRN_PMC2, r5
 157        mtspr   SPRN_PMC3, r6
 158        mtspr   SPRN_PMC4, r7
 159        mtspr   SPRN_PMC5, r8
 160        mtspr   SPRN_PMC6, r9
 161BEGIN_FTR_SECTION
 162        mtspr   SPRN_PMC7, r10
 163        mtspr   SPRN_PMC8, r11
 164END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 165        ld      r3, VCPU_MMCR(r4)
 166        ld      r5, VCPU_MMCR + 8(r4)
 167        ld      r6, VCPU_MMCR + 16(r4)
 168        mtspr   SPRN_MMCR1, r5
 169        mtspr   SPRN_MMCRA, r6
 170        mtspr   SPRN_MMCR0, r3
 171        isync
 172
 173        /* Load up FP, VMX and VSX registers */
 174        bl      kvmppc_load_fp
 175
 176BEGIN_FTR_SECTION
 177        /* Switch DSCR to guest value */
 178        ld      r5, VCPU_DSCR(r4)
 179        mtspr   SPRN_DSCR, r5
 180END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 181
 182        /*
 183         * Set the decrementer to the guest decrementer.
 184         */
 185        ld      r8,VCPU_DEC_EXPIRES(r4)
 186        mftb    r7
 187        subf    r3,r7,r8
 188        mtspr   SPRN_DEC,r3
 189        stw     r3,VCPU_DEC(r4)
 190
 191        ld      r5, VCPU_SPRG0(r4)
 192        ld      r6, VCPU_SPRG1(r4)
 193        ld      r7, VCPU_SPRG2(r4)
 194        ld      r8, VCPU_SPRG3(r4)
 195        mtspr   SPRN_SPRG0, r5
 196        mtspr   SPRN_SPRG1, r6
 197        mtspr   SPRN_SPRG2, r7
 198        mtspr   SPRN_SPRG3, r8
 199
 200        /* Save R1 in the PACA */
 201        std     r1, HSTATE_HOST_R1(r13)
 202
 203        /* Increment yield count if they have a VPA */
 204        ld      r3, VCPU_VPA(r4)
 205        cmpdi   r3, 0
 206        beq     25f
 207        lwz     r5, LPPACA_YIELDCOUNT(r3)
 208        addi    r5, r5, 1
 209        stw     r5, LPPACA_YIELDCOUNT(r3)
 21025:
 211        /* Load up DAR and DSISR */
 212        ld      r5, VCPU_DAR(r4)
 213        lwz     r6, VCPU_DSISR(r4)
 214        mtspr   SPRN_DAR, r5
 215        mtspr   SPRN_DSISR, r6
 216
 217        /* Set partition DABR */
 218        li      r5,3
 219        ld      r6,VCPU_DABR(r4)
 220        mtspr   SPRN_DABRX,r5
 221        mtspr   SPRN_DABR,r6
 222
 223BEGIN_FTR_SECTION
 224        /* Restore AMR and UAMOR, set AMOR to all 1s */
 225        ld      r5,VCPU_AMR(r4)
 226        ld      r6,VCPU_UAMOR(r4)
 227        li      r7,-1
 228        mtspr   SPRN_AMR,r5
 229        mtspr   SPRN_UAMOR,r6
 230        mtspr   SPRN_AMOR,r7
 231END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 232
 233        /* Clear out SLB */
 234        li      r6,0
 235        slbmte  r6,r6
 236        slbia
 237        ptesync
 238
 239BEGIN_FTR_SECTION
 240        b       30f
 241END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 242        /*
 243         * POWER7 host -> guest partition switch code.
 244         * We don't have to lock against concurrent tlbies,
 245         * but we do have to coordinate across hardware threads.
 246         */
 247        /* Increment entry count iff exit count is zero. */
 248        ld      r5,HSTATE_KVM_VCORE(r13)
 249        addi    r9,r5,VCORE_ENTRY_EXIT
 25021:     lwarx   r3,0,r9
 251        cmpwi   r3,0x100                /* any threads starting to exit? */
 252        bge     secondary_too_late      /* if so we're too late to the party */
 253        addi    r3,r3,1
 254        stwcx.  r3,0,r9
 255        bne     21b
 256
 257        /* Primary thread switches to guest partition. */
 258        ld      r9,VCPU_KVM(r4)         /* pointer to struct kvm */
 259        lwz     r6,VCPU_PTID(r4)
 260        cmpwi   r6,0
 261        bne     20f
 262        ld      r6,KVM_SDR1(r9)
 263        lwz     r7,KVM_LPID(r9)
 264        li      r0,LPID_RSVD            /* switch to reserved LPID */
 265        mtspr   SPRN_LPID,r0
 266        ptesync
 267        mtspr   SPRN_SDR1,r6            /* switch to partition page table */
 268        mtspr   SPRN_LPID,r7
 269        isync
 270        li      r0,1
 271        stb     r0,VCORE_IN_GUEST(r5)   /* signal secondaries to continue */
 272        b       10f
 273
 274        /* Secondary threads wait for primary to have done partition switch */
 27520:     lbz     r0,VCORE_IN_GUEST(r5)
 276        cmpwi   r0,0
 277        beq     20b
 278
 279        /* Set LPCR.  Set the MER bit if there is a pending external irq. */
 28010:     ld      r8,KVM_LPCR(r9)
 281        ld      r0,VCPU_PENDING_EXC(r4)
 282        li      r7,(1 << BOOK3S_IRQPRIO_EXTERNAL)
 283        oris    r7,r7,(1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h
 284        and.    r0,r0,r7
 285        beq     11f
 286        ori     r8,r8,LPCR_MER
 28711:     mtspr   SPRN_LPCR,r8
 288        ld      r8,KVM_RMOR(r9)
 289        mtspr   SPRN_RMOR,r8
 290        isync
 291
 292        /* Check if HDEC expires soon */
 293        mfspr   r3,SPRN_HDEC
 294        cmpwi   r3,10
 295        li      r12,BOOK3S_INTERRUPT_HV_DECREMENTER
 296        mr      r9,r4
 297        blt     hdec_soon
 298
 299        /*
 300         * Invalidate the TLB if we could possibly have stale TLB
 301         * entries for this partition on this core due to the use
 302         * of tlbiel.
 303         * XXX maybe only need this on primary thread?
 304         */
 305        ld      r9,VCPU_KVM(r4)         /* pointer to struct kvm */
 306        lwz     r5,VCPU_VCPUID(r4)
 307        lhz     r6,PACAPACAINDEX(r13)
 308        rldimi  r6,r5,0,62              /* XXX map as if threads 1:1 p:v */
 309        lhz     r8,VCPU_LAST_CPU(r4)
 310        sldi    r7,r6,1                 /* see if this is the same vcpu */
 311        add     r7,r7,r9                /* as last ran on this pcpu */
 312        lhz     r0,KVM_LAST_VCPU(r7)
 313        cmpw    r6,r8                   /* on the same cpu core as last time? */
 314        bne     3f
 315        cmpw    r0,r5                   /* same vcpu as this core last ran? */
 316        beq     1f
 3173:      sth     r6,VCPU_LAST_CPU(r4)    /* if not, invalidate partition TLB */
 318        sth     r5,KVM_LAST_VCPU(r7)
 319        li      r6,128
 320        mtctr   r6
 321        li      r7,0x800                /* IS field = 0b10 */
 322        ptesync
 3232:      tlbiel  r7
 324        addi    r7,r7,0x1000
 325        bdnz    2b
 326        ptesync
 3271:
 328
 329        /* Save purr/spurr */
 330        mfspr   r5,SPRN_PURR
 331        mfspr   r6,SPRN_SPURR
 332        std     r5,HSTATE_PURR(r13)
 333        std     r6,HSTATE_SPURR(r13)
 334        ld      r7,VCPU_PURR(r4)
 335        ld      r8,VCPU_SPURR(r4)
 336        mtspr   SPRN_PURR,r7
 337        mtspr   SPRN_SPURR,r8
 338        b       31f
 339
 340        /*
 341         * PPC970 host -> guest partition switch code.
 342         * We have to lock against concurrent tlbies,
 343         * using native_tlbie_lock to lock against host tlbies
 344         * and kvm->arch.tlbie_lock to lock against guest tlbies.
 345         * We also have to invalidate the TLB since its
 346         * entries aren't tagged with the LPID.
 347         */
 34830:     ld      r9,VCPU_KVM(r4)         /* pointer to struct kvm */
 349
 350        /* first take native_tlbie_lock */
 351        .section ".toc","aw"
 352toc_tlbie_lock:
 353        .tc     native_tlbie_lock[TC],native_tlbie_lock
 354        .previous
 355        ld      r3,toc_tlbie_lock@toc(2)
 356        lwz     r8,PACA_LOCK_TOKEN(r13)
 35724:     lwarx   r0,0,r3
 358        cmpwi   r0,0
 359        bne     24b
 360        stwcx.  r8,0,r3
 361        bne     24b
 362        isync
 363
 364        ld      r7,KVM_LPCR(r9)         /* use kvm->arch.lpcr to store HID4 */
 365        li      r0,0x18f
 366        rotldi  r0,r0,HID4_LPID5_SH     /* all lpid bits in HID4 = 1 */
 367        or      r0,r7,r0
 368        ptesync
 369        sync
 370        mtspr   SPRN_HID4,r0            /* switch to reserved LPID */
 371        isync
 372        li      r0,0
 373        stw     r0,0(r3)                /* drop native_tlbie_lock */
 374
 375        /* invalidate the whole TLB */
 376        li      r0,256
 377        mtctr   r0
 378        li      r6,0
 37925:     tlbiel  r6
 380        addi    r6,r6,0x1000
 381        bdnz    25b
 382        ptesync
 383
 384        /* Take the guest's tlbie_lock */
 385        addi    r3,r9,KVM_TLBIE_LOCK
 38624:     lwarx   r0,0,r3
 387        cmpwi   r0,0
 388        bne     24b
 389        stwcx.  r8,0,r3
 390        bne     24b
 391        isync
 392        ld      r6,KVM_SDR1(r9)
 393        mtspr   SPRN_SDR1,r6            /* switch to partition page table */
 394
 395        /* Set up HID4 with the guest's LPID etc. */
 396        sync
 397        mtspr   SPRN_HID4,r7
 398        isync
 399
 400        /* drop the guest's tlbie_lock */
 401        li      r0,0
 402        stw     r0,0(r3)
 403
 404        /* Check if HDEC expires soon */
 405        mfspr   r3,SPRN_HDEC
 406        cmpwi   r3,10
 407        li      r12,BOOK3S_INTERRUPT_HV_DECREMENTER
 408        mr      r9,r4
 409        blt     hdec_soon
 410
 411        /* Enable HDEC interrupts */
 412        mfspr   r0,SPRN_HID0
 413        li      r3,1
 414        rldimi  r0,r3, HID0_HDICE_SH, 64-HID0_HDICE_SH-1
 415        sync
 416        mtspr   SPRN_HID0,r0
 417        mfspr   r0,SPRN_HID0
 418        mfspr   r0,SPRN_HID0
 419        mfspr   r0,SPRN_HID0
 420        mfspr   r0,SPRN_HID0
 421        mfspr   r0,SPRN_HID0
 422        mfspr   r0,SPRN_HID0
 423
 424        /* Load up guest SLB entries */
 42531:     lwz     r5,VCPU_SLB_MAX(r4)
 426        cmpwi   r5,0
 427        beq     9f
 428        mtctr   r5
 429        addi    r6,r4,VCPU_SLB
 4301:      ld      r8,VCPU_SLB_E(r6)
 431        ld      r9,VCPU_SLB_V(r6)
 432        slbmte  r9,r8
 433        addi    r6,r6,VCPU_SLB_SIZE
 434        bdnz    1b
 4359:
 436
 437        /* Restore state of CTRL run bit; assume 1 on entry */
 438        lwz     r5,VCPU_CTRL(r4)
 439        andi.   r5,r5,1
 440        bne     4f
 441        mfspr   r6,SPRN_CTRLF
 442        clrrdi  r6,r6,1
 443        mtspr   SPRN_CTRLT,r6
 4444:
 445        ld      r6, VCPU_CTR(r4)
 446        lwz     r7, VCPU_XER(r4)
 447
 448        mtctr   r6
 449        mtxer   r7
 450
 451        /* Move SRR0 and SRR1 into the respective regs */
 452        ld      r6, VCPU_SRR0(r4)
 453        ld      r7, VCPU_SRR1(r4)
 454        mtspr   SPRN_SRR0, r6
 455        mtspr   SPRN_SRR1, r7
 456
 457        ld      r10, VCPU_PC(r4)
 458
 459        ld      r11, VCPU_MSR(r4)       /* r10 = vcpu->arch.msr & ~MSR_HV */
 460        rldicl  r11, r11, 63 - MSR_HV_LG, 1
 461        rotldi  r11, r11, 1 + MSR_HV_LG
 462        ori     r11, r11, MSR_ME
 463
 464fast_guest_return:
 465        mtspr   SPRN_HSRR0,r10
 466        mtspr   SPRN_HSRR1,r11
 467
 468        /* Activate guest mode, so faults get handled by KVM */
 469        li      r9, KVM_GUEST_MODE_GUEST
 470        stb     r9, HSTATE_IN_GUEST(r13)
 471
 472        /* Enter guest */
 473
 474        ld      r5, VCPU_LR(r4)
 475        lwz     r6, VCPU_CR(r4)
 476        mtlr    r5
 477        mtcr    r6
 478
 479        ld      r0, VCPU_GPR(r0)(r4)
 480        ld      r1, VCPU_GPR(r1)(r4)
 481        ld      r2, VCPU_GPR(r2)(r4)
 482        ld      r3, VCPU_GPR(r3)(r4)
 483        ld      r5, VCPU_GPR(r5)(r4)
 484        ld      r6, VCPU_GPR(r6)(r4)
 485        ld      r7, VCPU_GPR(r7)(r4)
 486        ld      r8, VCPU_GPR(r8)(r4)
 487        ld      r9, VCPU_GPR(r9)(r4)
 488        ld      r10, VCPU_GPR(r10)(r4)
 489        ld      r11, VCPU_GPR(r11)(r4)
 490        ld      r12, VCPU_GPR(r12)(r4)
 491        ld      r13, VCPU_GPR(r13)(r4)
 492
 493        ld      r4, VCPU_GPR(r4)(r4)
 494
 495        hrfid
 496        b       .
 497
 498/******************************************************************************
 499 *                                                                            *
 500 *                               Exit code                                    *
 501 *                                                                            *
 502 *****************************************************************************/
 503
 504/*
 505 * We come here from the first-level interrupt handlers.
 506 */
 507        .globl  kvmppc_interrupt
 508kvmppc_interrupt:
 509        /*
 510         * Register contents:
 511         * R12          = interrupt vector
 512         * R13          = PACA
 513         * guest CR, R12 saved in shadow VCPU SCRATCH1/0
 514         * guest R13 saved in SPRN_SCRATCH0
 515         */
 516        /* abuse host_r2 as third scratch area; we get r2 from PACATOC(r13) */
 517        std     r9, HSTATE_HOST_R2(r13)
 518        ld      r9, HSTATE_KVM_VCPU(r13)
 519
 520        /* Save registers */
 521
 522        std     r0, VCPU_GPR(r0)(r9)
 523        std     r1, VCPU_GPR(r1)(r9)
 524        std     r2, VCPU_GPR(r2)(r9)
 525        std     r3, VCPU_GPR(r3)(r9)
 526        std     r4, VCPU_GPR(r4)(r9)
 527        std     r5, VCPU_GPR(r5)(r9)
 528        std     r6, VCPU_GPR(r6)(r9)
 529        std     r7, VCPU_GPR(r7)(r9)
 530        std     r8, VCPU_GPR(r8)(r9)
 531        ld      r0, HSTATE_HOST_R2(r13)
 532        std     r0, VCPU_GPR(r9)(r9)
 533        std     r10, VCPU_GPR(r10)(r9)
 534        std     r11, VCPU_GPR(r11)(r9)
 535        ld      r3, HSTATE_SCRATCH0(r13)
 536        lwz     r4, HSTATE_SCRATCH1(r13)
 537        std     r3, VCPU_GPR(r12)(r9)
 538        stw     r4, VCPU_CR(r9)
 539
 540        /* Restore R1/R2 so we can handle faults */
 541        ld      r1, HSTATE_HOST_R1(r13)
 542        ld      r2, PACATOC(r13)
 543
 544        mfspr   r10, SPRN_SRR0
 545        mfspr   r11, SPRN_SRR1
 546        std     r10, VCPU_SRR0(r9)
 547        std     r11, VCPU_SRR1(r9)
 548        andi.   r0, r12, 2              /* need to read HSRR0/1? */
 549        beq     1f
 550        mfspr   r10, SPRN_HSRR0
 551        mfspr   r11, SPRN_HSRR1
 552        clrrdi  r12, r12, 2
 5531:      std     r10, VCPU_PC(r9)
 554        std     r11, VCPU_MSR(r9)
 555
 556        GET_SCRATCH0(r3)
 557        mflr    r4
 558        std     r3, VCPU_GPR(r13)(r9)
 559        std     r4, VCPU_LR(r9)
 560
 561        /* Unset guest mode */
 562        li      r0, KVM_GUEST_MODE_NONE
 563        stb     r0, HSTATE_IN_GUEST(r13)
 564
 565        stw     r12,VCPU_TRAP(r9)
 566
 567        /* See if this is a leftover HDEC interrupt */
 568        cmpwi   r12,BOOK3S_INTERRUPT_HV_DECREMENTER
 569        bne     2f
 570        mfspr   r3,SPRN_HDEC
 571        cmpwi   r3,0
 572        bge     ignore_hdec
 5732:
 574        /* See if this is something we can handle in real mode */
 575        cmpwi   r12,BOOK3S_INTERRUPT_SYSCALL
 576        beq     hcall_try_real_mode
 577hcall_real_cont:
 578
 579        /* Check for mediated interrupts (could be done earlier really ...) */
 580BEGIN_FTR_SECTION
 581        cmpwi   r12,BOOK3S_INTERRUPT_EXTERNAL
 582        bne+    1f
 583        ld      r5,VCPU_KVM(r9)
 584        ld      r5,KVM_LPCR(r5)
 585        andi.   r0,r11,MSR_EE
 586        beq     1f
 587        andi.   r0,r5,LPCR_MER
 588        bne     bounce_ext_interrupt
 5891:
 590END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 591
 592        /* Save DEC */
 593        mfspr   r5,SPRN_DEC
 594        mftb    r6
 595        extsw   r5,r5
 596        add     r5,r5,r6
 597        std     r5,VCPU_DEC_EXPIRES(r9)
 598
 599        /* Save HEIR (HV emulation assist reg) in last_inst
 600           if this is an HEI (HV emulation interrupt, e40) */
 601        li      r3,-1
 602BEGIN_FTR_SECTION
 603        cmpwi   r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST
 604        bne     11f
 605        mfspr   r3,SPRN_HEIR
 606END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 60711:     stw     r3,VCPU_LAST_INST(r9)
 608
 609        /* Save more register state  */
 610        mfxer   r5
 611        mfdar   r6
 612        mfdsisr r7
 613        mfctr   r8
 614
 615        stw     r5, VCPU_XER(r9)
 616        std     r6, VCPU_DAR(r9)
 617        stw     r7, VCPU_DSISR(r9)
 618        std     r8, VCPU_CTR(r9)
 619        /* grab HDAR & HDSISR if HV data storage interrupt (HDSI) */
 620BEGIN_FTR_SECTION
 621        cmpwi   r12,BOOK3S_INTERRUPT_H_DATA_STORAGE
 622        beq     6f
 623END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 6247:      std     r6, VCPU_FAULT_DAR(r9)
 625        stw     r7, VCPU_FAULT_DSISR(r9)
 626
 627        /* Save guest CTRL register, set runlatch to 1 */
 628        mfspr   r6,SPRN_CTRLF
 629        stw     r6,VCPU_CTRL(r9)
 630        andi.   r0,r6,1
 631        bne     4f
 632        ori     r6,r6,1
 633        mtspr   SPRN_CTRLT,r6
 6344:
 635        /* Read the guest SLB and save it away */
 636        lwz     r0,VCPU_SLB_NR(r9)      /* number of entries in SLB */
 637        mtctr   r0
 638        li      r6,0
 639        addi    r7,r9,VCPU_SLB
 640        li      r5,0
 6411:      slbmfee r8,r6
 642        andis.  r0,r8,SLB_ESID_V@h
 643        beq     2f
 644        add     r8,r8,r6                /* put index in */
 645        slbmfev r3,r6
 646        std     r8,VCPU_SLB_E(r7)
 647        std     r3,VCPU_SLB_V(r7)
 648        addi    r7,r7,VCPU_SLB_SIZE
 649        addi    r5,r5,1
 6502:      addi    r6,r6,1
 651        bdnz    1b
 652        stw     r5,VCPU_SLB_MAX(r9)
 653
 654        /*
 655         * Save the guest PURR/SPURR
 656         */
 657BEGIN_FTR_SECTION
 658        mfspr   r5,SPRN_PURR
 659        mfspr   r6,SPRN_SPURR
 660        ld      r7,VCPU_PURR(r9)
 661        ld      r8,VCPU_SPURR(r9)
 662        std     r5,VCPU_PURR(r9)
 663        std     r6,VCPU_SPURR(r9)
 664        subf    r5,r7,r5
 665        subf    r6,r8,r6
 666
 667        /*
 668         * Restore host PURR/SPURR and add guest times
 669         * so that the time in the guest gets accounted.
 670         */
 671        ld      r3,HSTATE_PURR(r13)
 672        ld      r4,HSTATE_SPURR(r13)
 673        add     r3,r3,r5
 674        add     r4,r4,r6
 675        mtspr   SPRN_PURR,r3
 676        mtspr   SPRN_SPURR,r4
 677END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_201)
 678
 679        /* Clear out SLB */
 680        li      r5,0
 681        slbmte  r5,r5
 682        slbia
 683        ptesync
 684
 685hdec_soon:
 686BEGIN_FTR_SECTION
 687        b       32f
 688END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 689        /*
 690         * POWER7 guest -> host partition switch code.
 691         * We don't have to lock against tlbies but we do
 692         * have to coordinate the hardware threads.
 693         */
 694        /* Increment the threads-exiting-guest count in the 0xff00
 695           bits of vcore->entry_exit_count */
 696        lwsync
 697        ld      r5,HSTATE_KVM_VCORE(r13)
 698        addi    r6,r5,VCORE_ENTRY_EXIT
 69941:     lwarx   r3,0,r6
 700        addi    r0,r3,0x100
 701        stwcx.  r0,0,r6
 702        bne     41b
 703
 704        /*
 705         * At this point we have an interrupt that we have to pass
 706         * up to the kernel or qemu; we can't handle it in real mode.
 707         * Thus we have to do a partition switch, so we have to
 708         * collect the other threads, if we are the first thread
 709         * to take an interrupt.  To do this, we set the HDEC to 0,
 710         * which causes an HDEC interrupt in all threads within 2ns
 711         * because the HDEC register is shared between all 4 threads.
 712         * However, we don't need to bother if this is an HDEC
 713         * interrupt, since the other threads will already be on their
 714         * way here in that case.
 715         */
 716        cmpwi   r12,BOOK3S_INTERRUPT_HV_DECREMENTER
 717        beq     40f
 718        cmpwi   r3,0x100        /* Are we the first here? */
 719        bge     40f
 720        cmpwi   r3,1
 721        ble     40f
 722        li      r0,0
 723        mtspr   SPRN_HDEC,r0
 72440:
 725
 726        /* Secondary threads wait for primary to do partition switch */
 727        ld      r4,VCPU_KVM(r9)         /* pointer to struct kvm */
 728        ld      r5,HSTATE_KVM_VCORE(r13)
 729        lwz     r3,VCPU_PTID(r9)
 730        cmpwi   r3,0
 731        beq     15f
 732        HMT_LOW
 73313:     lbz     r3,VCORE_IN_GUEST(r5)
 734        cmpwi   r3,0
 735        bne     13b
 736        HMT_MEDIUM
 737        b       16f
 738
 739        /* Primary thread waits for all the secondaries to exit guest */
 74015:     lwz     r3,VCORE_ENTRY_EXIT(r5)
 741        srwi    r0,r3,8
 742        clrldi  r3,r3,56
 743        cmpw    r3,r0
 744        bne     15b
 745        isync
 746
 747        /* Primary thread switches back to host partition */
 748        ld      r6,KVM_HOST_SDR1(r4)
 749        lwz     r7,KVM_HOST_LPID(r4)
 750        li      r8,LPID_RSVD            /* switch to reserved LPID */
 751        mtspr   SPRN_LPID,r8
 752        ptesync
 753        mtspr   SPRN_SDR1,r6            /* switch to partition page table */
 754        mtspr   SPRN_LPID,r7
 755        isync
 756        li      r0,0
 757        stb     r0,VCORE_IN_GUEST(r5)
 758        lis     r8,0x7fff               /* MAX_INT@h */
 759        mtspr   SPRN_HDEC,r8
 760
 76116:     ld      r8,KVM_HOST_LPCR(r4)
 762        mtspr   SPRN_LPCR,r8
 763        isync
 764        b       33f
 765
 766        /*
 767         * PPC970 guest -> host partition switch code.
 768         * We have to lock against concurrent tlbies, and
 769         * we have to flush the whole TLB.
 770         */
 77132:     ld      r4,VCPU_KVM(r9)         /* pointer to struct kvm */
 772
 773        /* Take the guest's tlbie_lock */
 774        lwz     r8,PACA_LOCK_TOKEN(r13)
 775        addi    r3,r4,KVM_TLBIE_LOCK
 77624:     lwarx   r0,0,r3
 777        cmpwi   r0,0
 778        bne     24b
 779        stwcx.  r8,0,r3
 780        bne     24b
 781        isync
 782
 783        ld      r7,KVM_HOST_LPCR(r4)    /* use kvm->arch.host_lpcr for HID4 */
 784        li      r0,0x18f
 785        rotldi  r0,r0,HID4_LPID5_SH     /* all lpid bits in HID4 = 1 */
 786        or      r0,r7,r0
 787        ptesync
 788        sync
 789        mtspr   SPRN_HID4,r0            /* switch to reserved LPID */
 790        isync
 791        li      r0,0
 792        stw     r0,0(r3)                /* drop guest tlbie_lock */
 793
 794        /* invalidate the whole TLB */
 795        li      r0,256
 796        mtctr   r0
 797        li      r6,0
 79825:     tlbiel  r6
 799        addi    r6,r6,0x1000
 800        bdnz    25b
 801        ptesync
 802
 803        /* take native_tlbie_lock */
 804        ld      r3,toc_tlbie_lock@toc(2)
 80524:     lwarx   r0,0,r3
 806        cmpwi   r0,0
 807        bne     24b
 808        stwcx.  r8,0,r3
 809        bne     24b
 810        isync
 811
 812        ld      r6,KVM_HOST_SDR1(r4)
 813        mtspr   SPRN_SDR1,r6            /* switch to host page table */
 814
 815        /* Set up host HID4 value */
 816        sync
 817        mtspr   SPRN_HID4,r7
 818        isync
 819        li      r0,0
 820        stw     r0,0(r3)                /* drop native_tlbie_lock */
 821
 822        lis     r8,0x7fff               /* MAX_INT@h */
 823        mtspr   SPRN_HDEC,r8
 824
 825        /* Disable HDEC interrupts */
 826        mfspr   r0,SPRN_HID0
 827        li      r3,0
 828        rldimi  r0,r3, HID0_HDICE_SH, 64-HID0_HDICE_SH-1
 829        sync
 830        mtspr   SPRN_HID0,r0
 831        mfspr   r0,SPRN_HID0
 832        mfspr   r0,SPRN_HID0
 833        mfspr   r0,SPRN_HID0
 834        mfspr   r0,SPRN_HID0
 835        mfspr   r0,SPRN_HID0
 836        mfspr   r0,SPRN_HID0
 837
 838        /* load host SLB entries */
 83933:     ld      r8,PACA_SLBSHADOWPTR(r13)
 840
 841        .rept   SLB_NUM_BOLTED
 842        ld      r5,SLBSHADOW_SAVEAREA(r8)
 843        ld      r6,SLBSHADOW_SAVEAREA+8(r8)
 844        andis.  r7,r5,SLB_ESID_V@h
 845        beq     1f
 846        slbmte  r6,r5
 8471:      addi    r8,r8,16
 848        .endr
 849
 850        /* Save and reset AMR and UAMOR before turning on the MMU */
 851BEGIN_FTR_SECTION
 852        mfspr   r5,SPRN_AMR
 853        mfspr   r6,SPRN_UAMOR
 854        std     r5,VCPU_AMR(r9)
 855        std     r6,VCPU_UAMOR(r9)
 856        li      r6,0
 857        mtspr   SPRN_AMR,r6
 858END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 859
 860        /* Restore host DABR and DABRX */
 861        ld      r5,HSTATE_DABR(r13)
 862        li      r6,7
 863        mtspr   SPRN_DABR,r5
 864        mtspr   SPRN_DABRX,r6
 865
 866        /* Switch DSCR back to host value */
 867BEGIN_FTR_SECTION
 868        mfspr   r8, SPRN_DSCR
 869        ld      r7, HSTATE_DSCR(r13)
 870        std     r8, VCPU_DSCR(r7)
 871        mtspr   SPRN_DSCR, r7
 872END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 873
 874        /* Save non-volatile GPRs */
 875        std     r14, VCPU_GPR(r14)(r9)
 876        std     r15, VCPU_GPR(r15)(r9)
 877        std     r16, VCPU_GPR(r16)(r9)
 878        std     r17, VCPU_GPR(r17)(r9)
 879        std     r18, VCPU_GPR(r18)(r9)
 880        std     r19, VCPU_GPR(r19)(r9)
 881        std     r20, VCPU_GPR(r20)(r9)
 882        std     r21, VCPU_GPR(r21)(r9)
 883        std     r22, VCPU_GPR(r22)(r9)
 884        std     r23, VCPU_GPR(r23)(r9)
 885        std     r24, VCPU_GPR(r24)(r9)
 886        std     r25, VCPU_GPR(r25)(r9)
 887        std     r26, VCPU_GPR(r26)(r9)
 888        std     r27, VCPU_GPR(r27)(r9)
 889        std     r28, VCPU_GPR(r28)(r9)
 890        std     r29, VCPU_GPR(r29)(r9)
 891        std     r30, VCPU_GPR(r30)(r9)
 892        std     r31, VCPU_GPR(r31)(r9)
 893
 894        /* Save SPRGs */
 895        mfspr   r3, SPRN_SPRG0
 896        mfspr   r4, SPRN_SPRG1
 897        mfspr   r5, SPRN_SPRG2
 898        mfspr   r6, SPRN_SPRG3
 899        std     r3, VCPU_SPRG0(r9)
 900        std     r4, VCPU_SPRG1(r9)
 901        std     r5, VCPU_SPRG2(r9)
 902        std     r6, VCPU_SPRG3(r9)
 903
 904        /* Increment yield count if they have a VPA */
 905        ld      r8, VCPU_VPA(r9)        /* do they have a VPA? */
 906        cmpdi   r8, 0
 907        beq     25f
 908        lwz     r3, LPPACA_YIELDCOUNT(r8)
 909        addi    r3, r3, 1
 910        stw     r3, LPPACA_YIELDCOUNT(r8)
 91125:
 912        /* Save PMU registers if requested */
 913        /* r8 and cr0.eq are live here */
 914        li      r3, 1
 915        sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
 916        mfspr   r4, SPRN_MMCR0          /* save MMCR0 */
 917        mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable ints */
 918        isync
 919        beq     21f                     /* if no VPA, save PMU stuff anyway */
 920        lbz     r7, LPPACA_PMCINUSE(r8)
 921        cmpwi   r7, 0                   /* did they ask for PMU stuff to be saved? */
 922        bne     21f
 923        std     r3, VCPU_MMCR(r9)       /* if not, set saved MMCR0 to FC */
 924        b       22f
 92521:     mfspr   r5, SPRN_MMCR1
 926        mfspr   r6, SPRN_MMCRA
 927        std     r4, VCPU_MMCR(r9)
 928        std     r5, VCPU_MMCR + 8(r9)
 929        std     r6, VCPU_MMCR + 16(r9)
 930        mfspr   r3, SPRN_PMC1
 931        mfspr   r4, SPRN_PMC2
 932        mfspr   r5, SPRN_PMC3
 933        mfspr   r6, SPRN_PMC4
 934        mfspr   r7, SPRN_PMC5
 935        mfspr   r8, SPRN_PMC6
 936BEGIN_FTR_SECTION
 937        mfspr   r10, SPRN_PMC7
 938        mfspr   r11, SPRN_PMC8
 939END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 940        stw     r3, VCPU_PMC(r9)
 941        stw     r4, VCPU_PMC + 4(r9)
 942        stw     r5, VCPU_PMC + 8(r9)
 943        stw     r6, VCPU_PMC + 12(r9)
 944        stw     r7, VCPU_PMC + 16(r9)
 945        stw     r8, VCPU_PMC + 20(r9)
 946BEGIN_FTR_SECTION
 947        stw     r10, VCPU_PMC + 24(r9)
 948        stw     r11, VCPU_PMC + 28(r9)
 949END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 95022:
 951        /* save FP state */
 952        mr      r3, r9
 953        bl      .kvmppc_save_fp
 954
 955        /* Secondary threads go off to take a nap on POWER7 */
 956BEGIN_FTR_SECTION
 957        lwz     r0,VCPU_PTID(r3)
 958        cmpwi   r0,0
 959        bne     secondary_nap
 960END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
 961
 962        /*
 963         * Reload DEC.  HDEC interrupts were disabled when
 964         * we reloaded the host's LPCR value.
 965         */
 966        ld      r3, HSTATE_DECEXP(r13)
 967        mftb    r4
 968        subf    r4, r4, r3
 969        mtspr   SPRN_DEC, r4
 970
 971        /* Reload the host's PMU registers */
 972        ld      r3, PACALPPACAPTR(r13)  /* is the host using the PMU? */
 973        lbz     r4, LPPACA_PMCINUSE(r3)
 974        cmpwi   r4, 0
 975        beq     23f                     /* skip if not */
 976        lwz     r3, HSTATE_PMC(r13)
 977        lwz     r4, HSTATE_PMC + 4(r13)
 978        lwz     r5, HSTATE_PMC + 8(r13)
 979        lwz     r6, HSTATE_PMC + 12(r13)
 980        lwz     r8, HSTATE_PMC + 16(r13)
 981        lwz     r9, HSTATE_PMC + 20(r13)
 982BEGIN_FTR_SECTION
 983        lwz     r10, HSTATE_PMC + 24(r13)
 984        lwz     r11, HSTATE_PMC + 28(r13)
 985END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 986        mtspr   SPRN_PMC1, r3
 987        mtspr   SPRN_PMC2, r4
 988        mtspr   SPRN_PMC3, r5
 989        mtspr   SPRN_PMC4, r6
 990        mtspr   SPRN_PMC5, r8
 991        mtspr   SPRN_PMC6, r9
 992BEGIN_FTR_SECTION
 993        mtspr   SPRN_PMC7, r10
 994        mtspr   SPRN_PMC8, r11
 995END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 996        ld      r3, HSTATE_MMCR(r13)
 997        ld      r4, HSTATE_MMCR + 8(r13)
 998        ld      r5, HSTATE_MMCR + 16(r13)
 999        mtspr   SPRN_MMCR1, r4
1000        mtspr   SPRN_MMCRA, r5
1001        mtspr   SPRN_MMCR0, r3
1002        isync
100323:
1004        /*
1005         * For external and machine check interrupts, we need
1006         * to call the Linux handler to process the interrupt.
1007         * We do that by jumping to the interrupt vector address
1008         * which we have in r12.  The [h]rfid at the end of the
1009         * handler will return to the book3s_hv_interrupts.S code.
1010         * For other interrupts we do the rfid to get back
1011         * to the book3s_interrupts.S code here.
1012         */
1013        ld      r8, HSTATE_VMHANDLER(r13)
1014        ld      r7, HSTATE_HOST_MSR(r13)
1015
1016        cmpwi   r12, BOOK3S_INTERRUPT_EXTERNAL
1017        beq     11f
1018        cmpwi   r12, BOOK3S_INTERRUPT_MACHINE_CHECK
1019
1020        /* RFI into the highmem handler, or branch to interrupt handler */
102112:     mfmsr   r6
1022        mtctr   r12
1023        li      r0, MSR_RI
1024        andc    r6, r6, r0
1025        mtmsrd  r6, 1                   /* Clear RI in MSR */
1026        mtsrr0  r8
1027        mtsrr1  r7
1028        beqctr
1029        RFI
1030
103111:
1032BEGIN_FTR_SECTION
1033        b       12b
1034END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
1035        mtspr   SPRN_HSRR0, r8
1036        mtspr   SPRN_HSRR1, r7
1037        ba      0x500
1038
10396:      mfspr   r6,SPRN_HDAR
1040        mfspr   r7,SPRN_HDSISR
1041        b       7b
1042
1043/*
1044 * Try to handle an hcall in real mode.
1045 * Returns to the guest if we handle it, or continues on up to
1046 * the kernel if we can't (i.e. if we don't have a handler for
1047 * it, or if the handler returns H_TOO_HARD).
1048 */
1049        .globl  hcall_try_real_mode
1050hcall_try_real_mode:
1051        ld      r3,VCPU_GPR(r3)(r9)
1052        andi.   r0,r11,MSR_PR
1053        bne     hcall_real_cont
1054        clrrdi  r3,r3,2
1055        cmpldi  r3,hcall_real_table_end - hcall_real_table
1056        bge     hcall_real_cont
1057        LOAD_REG_ADDR(r4, hcall_real_table)
1058        lwzx    r3,r3,r4
1059        cmpwi   r3,0
1060        beq     hcall_real_cont
1061        add     r3,r3,r4
1062        mtctr   r3
1063        mr      r3,r9           /* get vcpu pointer */
1064        ld      r4,VCPU_GPR(r4)(r9)
1065        bctrl
1066        cmpdi   r3,H_TOO_HARD
1067        beq     hcall_real_fallback
1068        ld      r4,HSTATE_KVM_VCPU(r13)
1069        std     r3,VCPU_GPR(r3)(r4)
1070        ld      r10,VCPU_PC(r4)
1071        ld      r11,VCPU_MSR(r4)
1072        b       fast_guest_return
1073
1074        /* We've attempted a real mode hcall, but it's punted it back
1075         * to userspace.  We need to restore some clobbered volatiles
1076         * before resuming the pass-it-to-qemu path */
1077hcall_real_fallback:
1078        li      r12,BOOK3S_INTERRUPT_SYSCALL
1079        ld      r9, HSTATE_KVM_VCPU(r13)
1080        ld      r11, VCPU_MSR(r9)
1081
1082        b       hcall_real_cont
1083
1084        .globl  hcall_real_table
1085hcall_real_table:
1086        .long   0               /* 0 - unused */
1087        .long   .kvmppc_h_remove - hcall_real_table
1088        .long   .kvmppc_h_enter - hcall_real_table
1089        .long   .kvmppc_h_read - hcall_real_table
1090        .long   0               /* 0x10 - H_CLEAR_MOD */
1091        .long   0               /* 0x14 - H_CLEAR_REF */
1092        .long   .kvmppc_h_protect - hcall_real_table
1093        .long   0               /* 0x1c - H_GET_TCE */
1094        .long   .kvmppc_h_put_tce - hcall_real_table
1095        .long   0               /* 0x24 - H_SET_SPRG0 */
1096        .long   .kvmppc_h_set_dabr - hcall_real_table
1097        .long   0               /* 0x2c */
1098        .long   0               /* 0x30 */
1099        .long   0               /* 0x34 */
1100        .long   0               /* 0x38 */
1101        .long   0               /* 0x3c */
1102        .long   0               /* 0x40 */
1103        .long   0               /* 0x44 */
1104        .long   0               /* 0x48 */
1105        .long   0               /* 0x4c */
1106        .long   0               /* 0x50 */
1107        .long   0               /* 0x54 */
1108        .long   0               /* 0x58 */
1109        .long   0               /* 0x5c */
1110        .long   0               /* 0x60 */
1111        .long   0               /* 0x64 */
1112        .long   0               /* 0x68 */
1113        .long   0               /* 0x6c */
1114        .long   0               /* 0x70 */
1115        .long   0               /* 0x74 */
1116        .long   0               /* 0x78 */
1117        .long   0               /* 0x7c */
1118        .long   0               /* 0x80 */
1119        .long   0               /* 0x84 */
1120        .long   0               /* 0x88 */
1121        .long   0               /* 0x8c */
1122        .long   0               /* 0x90 */
1123        .long   0               /* 0x94 */
1124        .long   0               /* 0x98 */
1125        .long   0               /* 0x9c */
1126        .long   0               /* 0xa0 */
1127        .long   0               /* 0xa4 */
1128        .long   0               /* 0xa8 */
1129        .long   0               /* 0xac */
1130        .long   0               /* 0xb0 */
1131        .long   0               /* 0xb4 */
1132        .long   0               /* 0xb8 */
1133        .long   0               /* 0xbc */
1134        .long   0               /* 0xc0 */
1135        .long   0               /* 0xc4 */
1136        .long   0               /* 0xc8 */
1137        .long   0               /* 0xcc */
1138        .long   0               /* 0xd0 */
1139        .long   0               /* 0xd4 */
1140        .long   0               /* 0xd8 */
1141        .long   0               /* 0xdc */
1142        .long   0               /* 0xe0 */
1143        .long   0               /* 0xe4 */
1144        .long   0               /* 0xe8 */
1145        .long   0               /* 0xec */
1146        .long   0               /* 0xf0 */
1147        .long   0               /* 0xf4 */
1148        .long   0               /* 0xf8 */
1149        .long   0               /* 0xfc */
1150        .long   0               /* 0x100 */
1151        .long   0               /* 0x104 */
1152        .long   0               /* 0x108 */
1153        .long   0               /* 0x10c */
1154        .long   0               /* 0x110 */
1155        .long   0               /* 0x114 */
1156        .long   0               /* 0x118 */
1157        .long   0               /* 0x11c */
1158        .long   0               /* 0x120 */
1159        .long   .kvmppc_h_bulk_remove - hcall_real_table
1160hcall_real_table_end:
1161
1162ignore_hdec:
1163        mr      r4,r9
1164        b       fast_guest_return
1165
1166bounce_ext_interrupt:
1167        mr      r4,r9
1168        mtspr   SPRN_SRR0,r10
1169        mtspr   SPRN_SRR1,r11
1170        li      r10,BOOK3S_INTERRUPT_EXTERNAL
1171        LOAD_REG_IMMEDIATE(r11,MSR_SF | MSR_ME);
1172        b       fast_guest_return
1173
1174_GLOBAL(kvmppc_h_set_dabr)
1175        std     r4,VCPU_DABR(r3)
1176        mtspr   SPRN_DABR,r4
1177        li      r3,0
1178        blr
1179
1180secondary_too_late:
1181        ld      r5,HSTATE_KVM_VCORE(r13)
1182        HMT_LOW
118313:     lbz     r3,VCORE_IN_GUEST(r5)
1184        cmpwi   r3,0
1185        bne     13b
1186        HMT_MEDIUM
1187        ld      r11,PACA_SLBSHADOWPTR(r13)
1188
1189        .rept   SLB_NUM_BOLTED
1190        ld      r5,SLBSHADOW_SAVEAREA(r11)
1191        ld      r6,SLBSHADOW_SAVEAREA+8(r11)
1192        andis.  r7,r5,SLB_ESID_V@h
1193        beq     1f
1194        slbmte  r6,r5
11951:      addi    r11,r11,16
1196        .endr
1197        b       50f
1198
1199secondary_nap:
1200        /* Clear any pending IPI */
120150:     ld      r5, HSTATE_XICS_PHYS(r13)
1202        li      r0, 0xff
1203        li      r6, XICS_QIRR
1204        stbcix  r0, r5, r6
1205
1206        /* increment the nap count and then go to nap mode */
1207        ld      r4, HSTATE_KVM_VCORE(r13)
1208        addi    r4, r4, VCORE_NAP_COUNT
1209        lwsync                          /* make previous updates visible */
121051:     lwarx   r3, 0, r4
1211        addi    r3, r3, 1
1212        stwcx.  r3, 0, r4
1213        bne     51b
1214        isync
1215
1216        mfspr   r4, SPRN_LPCR
1217        li      r0, LPCR_PECE
1218        andc    r4, r4, r0
1219        ori     r4, r4, LPCR_PECE0      /* exit nap on interrupt */
1220        mtspr   SPRN_LPCR, r4
1221        li      r0, 0
1222        std     r0, HSTATE_SCRATCH0(r13)
1223        ptesync
1224        ld      r0, HSTATE_SCRATCH0(r13)
12251:      cmpd    r0, r0
1226        bne     1b
1227        nap
1228        b       .
1229
1230/*
1231 * Save away FP, VMX and VSX registers.
1232 * r3 = vcpu pointer
1233 */
1234_GLOBAL(kvmppc_save_fp)
1235        mfmsr   r9
1236        ori     r8,r9,MSR_FP
1237#ifdef CONFIG_ALTIVEC
1238BEGIN_FTR_SECTION
1239        oris    r8,r8,MSR_VEC@h
1240END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1241#endif
1242#ifdef CONFIG_VSX
1243BEGIN_FTR_SECTION
1244        oris    r8,r8,MSR_VSX@h
1245END_FTR_SECTION_IFSET(CPU_FTR_VSX)
1246#endif
1247        mtmsrd  r8
1248        isync
1249#ifdef CONFIG_VSX
1250BEGIN_FTR_SECTION
1251        reg = 0
1252        .rept   32
1253        li      r6,reg*16+VCPU_VSRS
1254        STXVD2X(reg,r6,r3)
1255        reg = reg + 1
1256        .endr
1257FTR_SECTION_ELSE
1258#endif
1259        reg = 0
1260        .rept   32
1261        stfd    reg,reg*8+VCPU_FPRS(r3)
1262        reg = reg + 1
1263        .endr
1264#ifdef CONFIG_VSX
1265ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
1266#endif
1267        mffs    fr0
1268        stfd    fr0,VCPU_FPSCR(r3)
1269
1270#ifdef CONFIG_ALTIVEC
1271BEGIN_FTR_SECTION
1272        reg = 0
1273        .rept   32
1274        li      r6,reg*16+VCPU_VRS
1275        stvx    reg,r6,r3
1276        reg = reg + 1
1277        .endr
1278        mfvscr  vr0
1279        li      r6,VCPU_VSCR
1280        stvx    vr0,r6,r3
1281END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1282#endif
1283        mfspr   r6,SPRN_VRSAVE
1284        stw     r6,VCPU_VRSAVE(r3)
1285        mtmsrd  r9
1286        isync
1287        blr
1288
1289/*
1290 * Load up FP, VMX and VSX registers
1291 * r4 = vcpu pointer
1292 */
1293        .globl  kvmppc_load_fp
1294kvmppc_load_fp:
1295        mfmsr   r9
1296        ori     r8,r9,MSR_FP
1297#ifdef CONFIG_ALTIVEC
1298BEGIN_FTR_SECTION
1299        oris    r8,r8,MSR_VEC@h
1300END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1301#endif
1302#ifdef CONFIG_VSX
1303BEGIN_FTR_SECTION
1304        oris    r8,r8,MSR_VSX@h
1305END_FTR_SECTION_IFSET(CPU_FTR_VSX)
1306#endif
1307        mtmsrd  r8
1308        isync
1309        lfd     fr0,VCPU_FPSCR(r4)
1310        MTFSF_L(fr0)
1311#ifdef CONFIG_VSX
1312BEGIN_FTR_SECTION
1313        reg = 0
1314        .rept   32
1315        li      r7,reg*16+VCPU_VSRS
1316        LXVD2X(reg,r7,r4)
1317        reg = reg + 1
1318        .endr
1319FTR_SECTION_ELSE
1320#endif
1321        reg = 0
1322        .rept   32
1323        lfd     reg,reg*8+VCPU_FPRS(r4)
1324        reg = reg + 1
1325        .endr
1326#ifdef CONFIG_VSX
1327ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
1328#endif
1329
1330#ifdef CONFIG_ALTIVEC
1331BEGIN_FTR_SECTION
1332        li      r7,VCPU_VSCR
1333        lvx     vr0,r7,r4
1334        mtvscr  vr0
1335        reg = 0
1336        .rept   32
1337        li      r7,reg*16+VCPU_VRS
1338        lvx     reg,r7,r4
1339        reg = reg + 1
1340        .endr
1341END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1342#endif
1343        lwz     r7,VCPU_VRSAVE(r4)
1344        mtspr   SPRN_VRSAVE,r7
1345        blr
1346