diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-02-15 12:30:20 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-02-15 12:30:20 +0100 |
commit | ee10689117c0186fd4fe7feca8d48c7316f65d70 (patch) | |
tree | fb2f7f75efa3f7ab5f1814fa1a4b4b3d67f884db /arch/powerpc | |
parent | 8ef81a9a453f9048c1683e40b540a4221986a2d1 (diff) | |
parent | 5982f0849e08fe4e4e7df5e345c4539ce9780b1b (diff) | |
download | linux-ee10689117c0186fd4fe7feca8d48c7316f65d70.tar.gz linux-ee10689117c0186fd4fe7feca8d48c7316f65d70.tar.bz2 linux-ee10689117c0186fd4fe7feca8d48c7316f65d70.zip |
Merge branch 'kvm-ppc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into HEAD
This brings in two fixes for potential host crashes, from Ben
Herrenschmidt and Nick Piggin.
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 8 | ||||
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 6 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_vio.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 34 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_rm_xics.c | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 70 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 5 |
9 files changed, 56 insertions, 87 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 8fa09fa500f0..14752eee3d0c 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -236,6 +236,11 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtctr reg; \ bctr +#define BRANCH_LINK_TO_FAR(reg, label) \ + __LOAD_FAR_HANDLER(reg, label); \ + mtctr reg; \ + bctrl + /* * KVM requires __LOAD_FAR_HANDLER. * @@ -260,6 +265,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define BRANCH_TO_COMMON(reg, label) \ b label +#define BRANCH_LINK_TO_FAR(reg, label) \ + bl label + #define BRANCH_TO_KVM(reg, label) \ b label diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 5c7db0f1a708..16efe7406776 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -67,7 +67,6 @@ int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func, int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func, uint64_t offset, uint32_t data); int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority); -int64_t opal_rm_set_xive(uint32_t isn, uint16_t server, uint8_t priority); int64_t opal_get_xive(uint32_t isn, __be16 *server, uint8_t *priority); int64_t opal_register_exception_handler(uint64_t opal_exception, uint64_t handler_address, @@ -220,18 +219,12 @@ int64_t opal_pci_set_power_state(uint64_t async_token, uint64_t id, int64_t opal_pci_poll2(uint64_t id, uint64_t data); int64_t opal_int_get_xirr(uint32_t *out_xirr, bool just_poll); -int64_t opal_rm_int_get_xirr(__be32 *out_xirr, bool just_poll); int64_t opal_int_set_cppr(uint8_t cppr); int64_t opal_int_eoi(uint32_t xirr); -int64_t opal_rm_int_eoi(uint32_t xirr); int64_t opal_int_set_mfrr(uint32_t cpu, uint8_t mfrr); -int64_t opal_rm_int_set_mfrr(uint32_t cpu, uint8_t mfrr); int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, uint32_t pe_num, uint32_t tce_size, uint64_t dma_addr, uint32_t npages); -int64_t opal_rm_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, - uint32_t pe_num, uint32_t tce_size, - uint64_t dma_addr, uint32_t npages); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 34a04a5fa468..76dd7738c122 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -982,7 +982,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN) EXCEPTION_PROLOG_COMMON_3(0xe60) addi r3,r1,STACK_FRAME_OVERHEAD - bl hmi_exception_realmode + BRANCH_LINK_TO_FAR(r4, hmi_exception_realmode) /* Windup the stack. */ /* Move original HSRR0 and HSRR1 into the respective regs */ ld r9,_MSR(r1) diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 72dac0b58061..5302e1ad82c2 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -250,7 +250,7 @@ fastsleep_workaround_at_entry: /* Fast sleep workaround */ li r3,1 li r4,1 - bl opal_rm_config_cpu_idle_state + bl opal_config_cpu_idle_state /* Clear Lock bit */ li r0,0 @@ -544,7 +544,7 @@ timebase_resync: */ ble cr3,clear_lock /* Time base re-sync */ - bl opal_rm_resync_timebase; + bl opal_resync_timebase; /* * If waking up from sleep, per core state is not lost, skip to * clear_lock. @@ -633,7 +633,7 @@ hypervisor_state_restored: fastsleep_workaround_at_exit: li r3,1 li r4,0 - bl opal_rm_config_cpu_idle_state + bl opal_config_cpu_idle_state b timebase_resync /* diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index c379ff5a4438..491c5d8120f7 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -171,6 +171,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, goto fail; } + ret = -ENOMEM; stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *), GFP_KERNEL); if (!stt) diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 96e7e609f621..c42a7e63b39e 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -29,11 +29,6 @@ #include <asm/opal.h> #include <asm/smp.h> -static bool in_realmode(void) -{ - return !(mfmsr() & MSR_IR); -} - #define KVM_CMA_CHUNK_ORDER 18 /* @@ -230,13 +225,10 @@ void kvmhv_rm_send_ipi(int cpu) /* Else poke the target with an IPI */ xics_phys = paca[cpu].kvm_hstate.xics_phys; - if (!in_realmode()) - opal_int_set_mfrr(get_hard_smp_processor_id(cpu), IPI_PRIORITY); - else if (xics_phys) + if (xics_phys) rm_writeb(xics_phys + XICS_MFRR, IPI_PRIORITY); else - opal_rm_int_set_mfrr(get_hard_smp_processor_id(cpu), - IPI_PRIORITY); + opal_int_set_mfrr(get_hard_smp_processor_id(cpu), IPI_PRIORITY); } /* @@ -419,10 +411,8 @@ static long kvmppc_read_one_intr(bool *again) /* Now read the interrupt from the ICP */ xics_phys = local_paca->kvm_hstate.xics_phys; rc = 0; - if (!in_realmode()) + if (!xics_phys) rc = opal_int_get_xirr(&xirr, false); - else if (!xics_phys) - rc = opal_rm_int_get_xirr(&xirr, false); else xirr = _lwzcix(xics_phys + XICS_XIRR); if (rc < 0) @@ -453,15 +443,12 @@ static long kvmppc_read_one_intr(bool *again) */ if (xisr == XICS_IPI) { rc = 0; - if (!in_realmode()) { - opal_int_set_mfrr(hard_smp_processor_id(), 0xff); - rc = opal_int_eoi(h_xirr); - } else if (xics_phys) { + if (xics_phys) { _stbcix(xics_phys + XICS_MFRR, 0xff); _stwcix(xics_phys + XICS_XIRR, xirr); } else { - opal_rm_int_set_mfrr(hard_smp_processor_id(), 0xff); - rc = opal_rm_int_eoi(h_xirr); + opal_int_set_mfrr(hard_smp_processor_id(), 0xff); + rc = opal_int_eoi(h_xirr); } /* If rc > 0, there is another interrupt pending */ *again = rc > 0; @@ -482,14 +469,11 @@ static long kvmppc_read_one_intr(bool *again) /* We raced with the host, * we need to resend that IPI, bummer */ - if (!in_realmode()) - opal_int_set_mfrr(hard_smp_processor_id(), - IPI_PRIORITY); - else if (xics_phys) + if (xics_phys) _stbcix(xics_phys + XICS_MFRR, IPI_PRIORITY); else - opal_rm_int_set_mfrr(hard_smp_processor_id(), - IPI_PRIORITY); + opal_int_set_mfrr(hard_smp_processor_id(), + IPI_PRIORITY); /* Let side effects complete */ smp_mb(); return 1; diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 0b2e388f4cdf..e78542d99cd6 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -36,7 +36,7 @@ EXPORT_SYMBOL(kvm_irq_bypass); static void icp_rm_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, u32 new_irq, bool check_resend); -static int xics_opal_rm_set_server(unsigned int hw_irq, int server_cpu); +static int xics_opal_set_server(unsigned int hw_irq, int server_cpu); /* -- ICS routines -- */ static void ics_rm_check_resend(struct kvmppc_xics *xics, @@ -720,7 +720,7 @@ static int ics_rm_eoi(struct kvm_vcpu *vcpu, u32 irq) ++vcpu->stat.pthru_host; if (state->intr_cpu != pcpu) { ++vcpu->stat.pthru_bad_aff; - xics_opal_rm_set_server(state->host_irq, pcpu); + xics_opal_set_server(state->host_irq, pcpu); } state->intr_cpu = -1; } @@ -781,16 +781,16 @@ static void icp_eoi(struct irq_chip *c, u32 hwirq, __be32 xirr, bool *again) if (xics_phys) { _stwcix(xics_phys + XICS_XIRR, xirr); } else { - rc = opal_rm_int_eoi(be32_to_cpu(xirr)); + rc = opal_int_eoi(be32_to_cpu(xirr)); *again = rc > 0; } } -static int xics_opal_rm_set_server(unsigned int hw_irq, int server_cpu) +static int xics_opal_set_server(unsigned int hw_irq, int server_cpu) { unsigned int mangle_cpu = get_hard_smp_processor_id(server_cpu) << 2; - return opal_rm_set_xive(hw_irq, mangle_cpu, DEFAULT_PRIORITY); + return opal_set_xive(hw_irq, mangle_cpu, DEFAULT_PRIORITY); } /* diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 3aa40f1b20f5..28799e557348 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -58,14 +58,16 @@ END_FTR_SECTION(0, 1); \ #define OPAL_CALL(name, token) \ _GLOBAL_TOC(name); \ + mfmsr r12; \ mflr r0; \ + andi. r11,r12,MSR_IR|MSR_DR; \ std r0,PPC_LR_STKOFF(r1); \ li r0,token; \ + beq opal_real_call; \ OPAL_BRANCH(opal_tracepoint_entry) \ - mfcr r12; \ - stw r12,8(r1); \ + mfcr r11; \ + stw r11,8(r1); \ li r11,0; \ - mfmsr r12; \ ori r11,r11,MSR_EE; \ std r12,PACASAVEDMSR(r13); \ andc r12,r12,r11; \ @@ -98,6 +100,30 @@ opal_return: mtcr r4; rfid +opal_real_call: + mfcr r11 + stw r11,8(r1) + /* Set opal return address */ + LOAD_REG_ADDR(r11, opal_return_realmode) + mtlr r11 + li r11,MSR_LE + andc r12,r12,r11 + mtspr SPRN_HSRR1,r12 + LOAD_REG_ADDR(r11,opal) + ld r12,8(r11) + ld r2,0(r11) + mtspr SPRN_HSRR0,r12 + hrfid + +opal_return_realmode: + FIXUP_ENDIAN + ld r2,PACATOC(r13); + lwz r11,8(r1); + ld r12,PPC_LR_STKOFF(r1) + mtcr r11; + mtlr r12 + blr + #ifdef CONFIG_TRACEPOINTS opal_tracepoint_entry: stdu r1,-STACKFRAMESIZE(r1) @@ -155,36 +181,6 @@ opal_tracepoint_return: blr #endif -#define OPAL_CALL_REAL(name, token) \ - _GLOBAL_TOC(name); \ - mflr r0; \ - std r0,PPC_LR_STKOFF(r1); \ - li r0,token; \ - mfcr r12; \ - stw r12,8(r1); \ - \ - /* Set opal return address */ \ - LOAD_REG_ADDR(r11, opal_return_realmode); \ - mtlr r11; \ - mfmsr r12; \ - li r11,MSR_LE; \ - andc r12,r12,r11; \ - mtspr SPRN_HSRR1,r12; \ - LOAD_REG_ADDR(r11,opal); \ - ld r12,8(r11); \ - ld r2,0(r11); \ - mtspr SPRN_HSRR0,r12; \ - hrfid - -opal_return_realmode: - FIXUP_ENDIAN - ld r2,PACATOC(r13); - lwz r11,8(r1); - ld r12,PPC_LR_STKOFF(r1) - mtcr r11; - mtlr r12 - blr - OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); @@ -208,7 +204,6 @@ OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE); OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD); OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD); OPAL_CALL(opal_set_xive, OPAL_SET_XIVE); -OPAL_CALL_REAL(opal_rm_set_xive, OPAL_SET_XIVE); OPAL_CALL(opal_get_xive, OPAL_GET_XIVE); OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); @@ -264,7 +259,6 @@ OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); -OPAL_CALL_REAL(opal_rm_resync_timebase, OPAL_RESYNC_TIMEBASE); OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); @@ -280,9 +274,7 @@ OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); OPAL_CALL(opal_get_param, OPAL_GET_PARAM); OPAL_CALL(opal_set_param, OPAL_SET_PARAM); OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); -OPAL_CALL_REAL(opal_rm_handle_hmi, OPAL_HANDLE_HMI); OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); -OPAL_CALL_REAL(opal_rm_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG); OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); @@ -304,11 +296,7 @@ OPAL_CALL(opal_pci_get_presence_state, OPAL_PCI_GET_PRESENCE_STATE); OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE); OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE); OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); -OPAL_CALL_REAL(opal_rm_int_get_xirr, OPAL_INT_GET_XIRR); OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); -OPAL_CALL_REAL(opal_rm_int_eoi, OPAL_INT_EOI); OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); -OPAL_CALL_REAL(opal_rm_int_set_mfrr, OPAL_INT_SET_MFRR); OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); -OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b07680cd2518..a897958edb88 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1962,11 +1962,6 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, if (phb->model == PNV_PHB_MODEL_PHB3 && phb->regs) pnv_pci_phb3_tce_invalidate(pe, rm, shift, index, npages); - else if (rm) - opal_rm_pci_tce_kill(phb->opal_id, - OPAL_PCI_TCE_KILL_PAGES, - pe->pe_number, 1u << shift, - index << shift, npages); else opal_pci_tce_kill(phb->opal_id, OPAL_PCI_TCE_KILL_PAGES, |