Merge branch 'fixes' into next
authorMichael Ellerman <mpe@ellerman.id.au>
Mon, 1 Jul 2019 04:04:39 +0000 (14:04 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 1 Jul 2019 04:04:39 +0000 (14:04 +1000)
Merge our fixes branch into next, this brings in a number of commits
that fix bugs we don't want to hit in next, in particular the fix for
CVE-2019-12817.

39 files changed:
Documentation/admin-guide/kernel-parameters.txt
arch/powerpc/Kconfig
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/book3s/64/radix.h
arch/powerpc/include/asm/opal-api.h
arch/powerpc/include/asm/ps3stor.h
arch/powerpc/kernel/cacheinfo.c
arch/powerpc/kernel/cacheinfo.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/swsusp_32.S
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/ldstfp.S
arch/powerpc/mm/book3s64/hash_native.c
arch/powerpc/mm/book3s64/hash_utils.c
arch/powerpc/mm/book3s64/pgtable.c
arch/powerpc/mm/book3s64/radix_pgtable.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/perf/imc-pmu.c
arch/powerpc/platforms/powermac/sleep.S
arch/powerpc/platforms/powernv/idle.c
arch/powerpc/platforms/powernv/npu-dma.c
arch/powerpc/platforms/powernv/opal-hmi.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/hvconsole.c
arch/powerpc/platforms/pseries/mobility.c
arch/powerpc/sysdev/xive/spapr.c
drivers/misc/cxl/cxl.h
drivers/misc/cxl/debugfs.c
drivers/misc/ocxl/pci.c
drivers/tty/hvc/hvc_vio.c
include/uapi/misc/ocxl.h
tools/testing/selftests/powerpc/tm/tm-vmxcopy.c

index 138f6664b2e29fe4ca71225fde00ac2ea695a941..a4c3538857e937d46ff712a99efcc7b601936886 100644 (file)
                        register save and restore. The kernel will only save
                        legacy floating-point registers on task switch.
 
-       nohugeiomap     [KNL,x86] Disable kernel huge I/O mappings.
+       nohugeiomap     [KNL,x86,PPC] Disable kernel huge I/O mappings.
 
        nosmt           [KNL,S390] Disable symmetric multithreading (SMT).
                        Equivalent to smt=1.
index 8c1c636308c8e6544fc781a3f4cbda6310ba95d1..f0e5b38d52e817db6a8e2028b7592fb8437dcdaf 100644 (file)
@@ -167,6 +167,7 @@ config PPC
        select GENERIC_STRNLEN_USER
        select GENERIC_TIME_VSYSCALL
        select HAVE_ARCH_AUDITSYSCALL
+       select HAVE_ARCH_HUGE_VMAP              if PPC_BOOK3S_64 && PPC_RADIX_MMU
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_ARCH_KASAN                  if PPC32
        select HAVE_ARCH_KGDB
index ccf00a8b98c6ab422d70f82974b03e5e457dff97..5faceeefd9f999fe6ef4c70df5d9bdedbac68ee2 100644 (file)
@@ -274,6 +274,14 @@ extern unsigned long __vmalloc_end;
 #define VMALLOC_START  __vmalloc_start
 #define VMALLOC_END    __vmalloc_end
 
+static inline unsigned int ioremap_max_order(void)
+{
+       if (radix_enabled())
+               return PUD_SHIFT;
+       return 7 + PAGE_SHIFT; /* default from linux/vmalloc.h */
+}
+#define IOREMAP_MAX_ORDER ioremap_max_order()
+
 extern unsigned long __kernel_virt_start;
 extern unsigned long __kernel_virt_size;
 extern unsigned long __kernel_io_start;
index 574eca33f8930d4d52bc2c9cebfd8ed696ee0a20..e04a839cb5b9f9f273750643684a1d7bf6d1385e 100644 (file)
@@ -266,6 +266,9 @@ extern void radix__vmemmap_remove_mapping(unsigned long start,
 extern int radix__map_kernel_page(unsigned long ea, unsigned long pa,
                                 pgprot_t flags, unsigned int psz);
 
+extern int radix__ioremap_range(unsigned long ea, phys_addr_t pa,
+                               unsigned long size, pgprot_t prot, int nid);
+
 static inline unsigned long radix__get_tree_size(void)
 {
        unsigned long rts_field;
index e1577cfa718621f293707821a687e0e525edcbdf..2492fe248e1e5e6e6eb6ef7acf137ebaf6d54609 100644 (file)
@@ -568,6 +568,7 @@ enum OpalHMI_XstopType {
        CHECKSTOP_TYPE_UNKNOWN  =       0,
        CHECKSTOP_TYPE_CORE     =       1,
        CHECKSTOP_TYPE_NX       =       2,
+       CHECKSTOP_TYPE_NPU      =       3
 };
 
 enum OpalHMI_CoreXstopReason {
index 6fcaf714fa50254aa86eae83883a0ec86e369e43..d5767ba0670b9d5ee9a3660b8100dbc02ad742ac 100644 (file)
@@ -51,7 +51,7 @@ struct ps3_storage_device {
        unsigned int num_regions;
        unsigned long accessible_regions;
        unsigned int region_idx;                /* first accessible region */
-       struct ps3_storage_region regions[0];   /* Must be last */
+       struct ps3_storage_region regions[];    /* Must be last */
 };
 
 static inline struct ps3_storage_device *to_ps3_storage_device(struct device *dev)
index 862e2890bd3df464ee7740865db97ce0de4c30a0..42c559efe060ce23641b2496ec2bcd03cce5e3a0 100644 (file)
@@ -896,4 +896,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id)
        if (cache)
                cache_cpu_clear(cache, cpu_id);
 }
+
+void cacheinfo_teardown(void)
+{
+       unsigned int cpu;
+
+       lockdep_assert_cpus_held();
+
+       for_each_online_cpu(cpu)
+               cacheinfo_cpu_offline(cpu);
+}
+
+void cacheinfo_rebuild(void)
+{
+       unsigned int cpu;
+
+       lockdep_assert_cpus_held();
+
+       for_each_online_cpu(cpu)
+               cacheinfo_cpu_online(cpu);
+}
+
 #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */
index 955f5e999f1b81e8faad5a653f2777b0f65912c3..52bd3fc6642da11329abb3ec465f6709b897a651 100644 (file)
@@ -6,4 +6,8 @@
 extern void cacheinfo_cpu_online(unsigned int cpu_id);
 extern void cacheinfo_cpu_offline(unsigned int cpu_id);
 
+/* Allow migration/suspend to tear down and rebuild the hierarchy. */
+extern void cacheinfo_teardown(void);
+extern void cacheinfo_rebuild(void);
+
 #endif /* _PPC_CACHEINFO_H */
index 73ba246ca11d2b12d6abe6fe28449190160e00de..6c51aa845bcee6c7c003c0068808d985243227c8 100644 (file)
@@ -1746,7 +1746,7 @@ handle_page_fault:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_page_fault
        cmpdi   r3,0
-       beq+    12f
+       beq+    ret_from_except_lite
        bl      save_nvgprs
        mr      r5,r3
        addi    r3,r1,STACK_FRAME_OVERHEAD
@@ -1761,7 +1761,12 @@ handle_dabr_fault:
        ld      r5,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_break
-12:    b       ret_from_except_lite
+       /*
+        * do_break() may have changed the NV GPRS while handling a breakpoint.
+        * If so, we need to restore them with their updated values. Don't use
+        * ret_from_except_lite here.
+        */
+       b       ret_from_except
 
 
 #ifdef CONFIG_PPC_BOOK3S_64
index 5321a11c283586a4242fdae2547aebd666da9803..259be7f6d551f1a0b6d69dcfc820600675dbff96 100644 (file)
@@ -904,6 +904,7 @@ p_toc:      .8byte  __toc_start + 0x8000 - 0b
 /*
  * This is where the main kernel code starts.
  */
+__REF
 start_here_multiplatform:
        /* set up the TOC */
        bl      relative_toc
@@ -979,6 +980,7 @@ start_here_multiplatform:
        RFI
        b       .       /* prevent speculative execution */
 
+       .previous
        /* This is where all platforms converge execution */
 
 start_here_common:
index 24191ea2d9a78393d9f7ad26da0daabc0eb91ca1..64ad92016b63f2027d7121edb56dcb16545e1066 100644 (file)
@@ -45,6 +45,8 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge)
        if (addr0 & 0x02000000) {
                flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
                flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+               if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
+                       flags |= IORESOURCE_MEM_64;
                flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
                if (addr0 & 0x40000000)
                        flags |= IORESOURCE_PREFETCH
index 61795c39de21587030e597374d382ba6edfe487b..a3fb90bb5a3968d4570db3469d235146bf571449 100644 (file)
@@ -172,6 +172,7 @@ static unsigned long __prombss prom_tce_alloc_end;
 
 #ifdef CONFIG_PPC_PSERIES
 static bool __prombss prom_radix_disable;
+static bool __prombss prom_xive_disable;
 #endif
 
 struct platform_support {
@@ -808,6 +809,12 @@ static void __init early_cmdline_parse(void)
        }
        if (prom_radix_disable)
                prom_debug("Radix disabled from cmdline\n");
+
+       opt = prom_strstr(prom_cmd_line, "xive=off");
+       if (opt) {
+               prom_xive_disable = true;
+               prom_debug("XIVE disabled from cmdline\n");
+       }
 #endif /* CONFIG_PPC_PSERIES */
 }
 
@@ -1216,10 +1223,17 @@ static void __init prom_parse_xive_model(u8 val,
        switch (val) {
        case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */
                prom_debug("XIVE - either mode supported\n");
-               support->xive = true;
+               support->xive = !prom_xive_disable;
                break;
        case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */
                prom_debug("XIVE - exploitation mode supported\n");
+               if (prom_xive_disable) {
+                       /*
+                        * If we __have__ to do XIVE, we're better off ignoring
+                        * the command line rather than not booting.
+                        */
+                       prom_printf("WARNING: Ignoring cmdline option xive=off\n");
+               }
                support->xive = true;
                break;
        case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */
@@ -1566,9 +1580,6 @@ static void __init reserve_mem(u64 base, u64 size)
 static void __init prom_init_mem(void)
 {
        phandle node;
-#ifdef DEBUG_PROM
-       char *path;
-#endif
        char type[64];
        unsigned int plen;
        cell_t *p, *endp;
@@ -1590,9 +1601,6 @@ static void __init prom_init_mem(void)
        prom_debug("root_size_cells: %x\n", rsc);
 
        prom_debug("scanning memory:\n");
-#ifdef DEBUG_PROM
-       path = prom_scratch;
-#endif
 
        for (node = 0; prom_next_node(&node); ) {
                type[0] = 0;
@@ -1617,9 +1625,10 @@ static void __init prom_init_mem(void)
                endp = p + (plen / sizeof(cell_t));
 
 #ifdef DEBUG_PROM
-               memset(path, 0, sizeof(prom_scratch));
-               call_prom("package-to-path", 3, 1, node, path, sizeof(prom_scratch) - 1);
-               prom_debug("  node %s :\n", path);
+               memset(prom_scratch, 0, sizeof(prom_scratch));
+               call_prom("package-to-path", 3, 1, node, prom_scratch,
+                         sizeof(prom_scratch) - 1);
+               prom_debug("  node %s :\n", prom_scratch);
 #endif /* DEBUG_PROM */
 
                while ((endp - p) >= (rac + rsc)) {
index 7a919e9a3400bb9a41cc98b42875b1285e9f5f02..cbdf86228eaaa7c0d64082979d265e332de42bbc 100644 (file)
 #define SL_IBAT2       0x48
 #define SL_DBAT3       0x50
 #define SL_IBAT3       0x58
-#define SL_TB          0x60
-#define SL_R2          0x68
-#define SL_CR          0x6c
-#define SL_LR          0x70
-#define SL_R12         0x74    /* r12 to r31 */
+#define SL_DBAT4       0x60
+#define SL_IBAT4       0x68
+#define SL_DBAT5       0x70
+#define SL_IBAT5       0x78
+#define SL_DBAT6       0x80
+#define SL_IBAT6       0x88
+#define SL_DBAT7       0x90
+#define SL_IBAT7       0x98
+#define SL_TB          0xa0
+#define SL_R2          0xa8
+#define SL_CR          0xac
+#define SL_LR          0xb0
+#define SL_R12         0xb4    /* r12 to r31 */
 #define SL_SIZE                (SL_R12 + 80)
 
        .section .data
@@ -114,6 +122,41 @@ _GLOBAL(swsusp_arch_suspend)
        mfibatl r4,3
        stw     r4,SL_IBAT3+4(r11)
 
+BEGIN_MMU_FTR_SECTION
+       mfspr   r4,SPRN_DBAT4U
+       stw     r4,SL_DBAT4(r11)
+       mfspr   r4,SPRN_DBAT4L
+       stw     r4,SL_DBAT4+4(r11)
+       mfspr   r4,SPRN_DBAT5U
+       stw     r4,SL_DBAT5(r11)
+       mfspr   r4,SPRN_DBAT5L
+       stw     r4,SL_DBAT5+4(r11)
+       mfspr   r4,SPRN_DBAT6U
+       stw     r4,SL_DBAT6(r11)
+       mfspr   r4,SPRN_DBAT6L
+       stw     r4,SL_DBAT6+4(r11)
+       mfspr   r4,SPRN_DBAT7U
+       stw     r4,SL_DBAT7(r11)
+       mfspr   r4,SPRN_DBAT7L
+       stw     r4,SL_DBAT7+4(r11)
+       mfspr   r4,SPRN_IBAT4U
+       stw     r4,SL_IBAT4(r11)
+       mfspr   r4,SPRN_IBAT4L
+       stw     r4,SL_IBAT4+4(r11)
+       mfspr   r4,SPRN_IBAT5U
+       stw     r4,SL_IBAT5(r11)
+       mfspr   r4,SPRN_IBAT5L
+       stw     r4,SL_IBAT5+4(r11)
+       mfspr   r4,SPRN_IBAT6U
+       stw     r4,SL_IBAT6(r11)
+       mfspr   r4,SPRN_IBAT6L
+       stw     r4,SL_IBAT6+4(r11)
+       mfspr   r4,SPRN_IBAT7U
+       stw     r4,SL_IBAT7(r11)
+       mfspr   r4,SPRN_IBAT7L
+       stw     r4,SL_IBAT7+4(r11)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+
 #if  0
        /* Backup various CPU config stuffs */
        bl      __save_cpu_setup
@@ -279,27 +322,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        mtibatu 3,r4
        lwz     r4,SL_IBAT3+4(r11)
        mtibatl 3,r4
-#endif
-
 BEGIN_MMU_FTR_SECTION
-       li      r4,0
+       lwz     r4,SL_DBAT4(r11)
        mtspr   SPRN_DBAT4U,r4
+       lwz     r4,SL_DBAT4+4(r11)
        mtspr   SPRN_DBAT4L,r4
+       lwz     r4,SL_DBAT5(r11)
        mtspr   SPRN_DBAT5U,r4
+       lwz     r4,SL_DBAT5+4(r11)
        mtspr   SPRN_DBAT5L,r4
+       lwz     r4,SL_DBAT6(r11)
        mtspr   SPRN_DBAT6U,r4
+       lwz     r4,SL_DBAT6+4(r11)
        mtspr   SPRN_DBAT6L,r4
+       lwz     r4,SL_DBAT7(r11)
        mtspr   SPRN_DBAT7U,r4
+       lwz     r4,SL_DBAT7+4(r11)
        mtspr   SPRN_DBAT7L,r4
+       lwz     r4,SL_IBAT4(r11)
        mtspr   SPRN_IBAT4U,r4
+       lwz     r4,SL_IBAT4+4(r11)
        mtspr   SPRN_IBAT4L,r4
+       lwz     r4,SL_IBAT5(r11)
        mtspr   SPRN_IBAT5U,r4
+       lwz     r4,SL_IBAT5+4(r11)
        mtspr   SPRN_IBAT5L,r4
+       lwz     r4,SL_IBAT6(r11)
        mtspr   SPRN_IBAT6U,r4
+       lwz     r4,SL_IBAT6+4(r11)
        mtspr   SPRN_IBAT6L,r4
+       lwz     r4,SL_IBAT7(r11)
        mtspr   SPRN_IBAT7U,r4
+       lwz     r4,SL_IBAT7+4(r11)
        mtspr   SPRN_IBAT7L,r4
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+#endif
 
        /* Flush all TLBs */
        lis     r4,0x1000
index d5fc624e0655073d8570869b8f101d536fd21740..a104743291a9d3928ca11bcd83eb43bdb98b407d 100644 (file)
@@ -3607,6 +3607,8 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
 
        vcpu->arch.slb_max = 0;
        dec = mfspr(SPRN_DEC);
+       if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */
+               dec = (s32) dec;
        tb = mftb();
        vcpu->arch.dec_expires = dec + tb;
        vcpu->cpu = -1;
@@ -4122,8 +4124,15 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run,
 
        preempt_enable();
 
-       /* cancel pending decrementer exception if DEC is now positive */
-       if (get_tb() < vcpu->arch.dec_expires && kvmppc_core_pending_dec(vcpu))
+       /*
+        * cancel pending decrementer exception if DEC is now positive, or if
+        * entering a nested guest in which case the decrementer is now owned
+        * by L2 and the L1 decrementer is provided in hdec_expires
+        */
+       if (kvmppc_core_pending_dec(vcpu) &&
+                       ((get_tb() < vcpu->arch.dec_expires) ||
+                        (trap == BOOK3S_INTERRUPT_SYSCALL &&
+                         kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED)))
                kvmppc_core_dequeue_dec(vcpu);
 
        trace_kvm_guest_exit(vcpu);
index c55f9c27bf7984704b80ac6fcbb986361f4ffc77..eebc782d89a53e7ad24a00301d48c44980679991 100644 (file)
@@ -49,7 +49,8 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST)   += test_emulate_step.o \
 obj-y                  += checksum_$(BITS).o checksum_wrappers.o \
                           string_$(BITS).o
 
-obj-y                  += sstep.o ldstfp.o quad.o
+obj-y                  += sstep.o
+obj-$(CONFIG_PPC_FPU)  += ldstfp.o
 obj64-y                        += quad.o
 
 obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
index 32e91994b6b259440e64c97886219e0a04258557..e388a3127cb6c4cd4cbaf70742cb19e274849216 100644 (file)
@@ -18,8 +18,6 @@
 #include <asm/asm-compat.h>
 #include <linux/errno.h>
 
-#ifdef CONFIG_PPC_FPU
-
 #define STKFRM (PPC_MIN_STKFRM + 16)
 
 /* Get the contents of frN into *p; N is in r3 and p is in r4. */
@@ -241,5 +239,3 @@ _GLOBAL(conv_dp_to_sp)
        MTMSRD(r6)
        isync
        blr
-
-#endif /* CONFIG_PPC_FPU */
index aaa28fd918fe4ce26a5bb0a46909ecff9ec877c3..47caecdbbbac6925924ba5cb18231b9ad8de74d0 100644 (file)
@@ -45,7 +45,7 @@
 #define HPTE_LOCK_BIT (56+3)
 #endif
 
-DEFINE_RAW_SPINLOCK(native_tlbie_lock);
+static DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 
 static inline void tlbiel_hash_set_isa206(unsigned int set, unsigned int is)
 {
index 919a861a8ec06ff25f0f96c7765e070ccf9cced4..1ff451892d7fa8817a9f9051f203b793f24d4096 100644 (file)
@@ -985,7 +985,7 @@ void __init hash__early_init_devtree(void)
        htab_scan_page_sizes();
 }
 
-struct hash_mm_context init_hash_mm_context;
+static struct hash_mm_context init_hash_mm_context;
 void __init hash__early_init_mmu(void)
 {
 #ifndef CONFIG_PPC_64K_PAGES
index ff98b663c83edb3cf950905cdb20f490453ff571..953850a602f77b49d16ca1993a1750844b9da124 100644 (file)
@@ -450,3 +450,24 @@ int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
 
        return true;
 }
+
+int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
+{
+       unsigned long i;
+
+       if (radix_enabled())
+               return radix__ioremap_range(ea, pa, size, prot, nid);
+
+       for (i = 0; i < size; i += PAGE_SIZE) {
+               int err = map_kernel_page(ea + i, pa + i, prot);
+               if (err) {
+                       if (slab_is_available())
+                               unmap_kernel_range(ea, size);
+                       else
+                               WARN_ON_ONCE(1); /* Should clean up */
+                       return err;
+               }
+       }
+
+       return 0;
+}
index c9bcf428dd2b38bf187763bec81705dc2d85b2aa..8904aa1243d8063a55db832ab52e6a963f289a1b 100644 (file)
@@ -11,6 +11,7 @@
 
 #define pr_fmt(fmt) "radix-mmu: " fmt
 
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/sched/mm.h>
 #include <linux/memblock.h>
@@ -323,7 +324,7 @@ static int __meminit create_physical_mapping(unsigned long start,
        return 0;
 }
 
-void __init radix_init_pgtable(void)
+static void __init radix_init_pgtable(void)
 {
        unsigned long rts_field;
        struct memblock_region *reg;
@@ -1122,3 +1123,123 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma,
 
        set_pte_at(mm, addr, ptep, pte);
 }
+
+int __init arch_ioremap_pud_supported(void)
+{
+       /* HPT does not cope with large pages in the vmalloc area */
+       return radix_enabled();
+}
+
+int __init arch_ioremap_pmd_supported(void)
+{
+       return radix_enabled();
+}
+
+int p4d_free_pud_page(p4d_t *p4d, unsigned long addr)
+{
+       return 0;
+}
+
+int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
+{
+       pte_t *ptep = (pte_t *)pud;
+       pte_t new_pud = pfn_pte(__phys_to_pfn(addr), prot);
+
+       if (!radix_enabled())
+               return 0;
+
+       set_pte_at(&init_mm, 0 /* radix unused */, ptep, new_pud);
+
+       return 1;
+}
+
+int pud_clear_huge(pud_t *pud)
+{
+       if (pud_huge(*pud)) {
+               pud_clear(pud);
+               return 1;
+       }
+
+       return 0;
+}
+
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
+{
+       pmd_t *pmd;
+       int i;
+
+       pmd = (pmd_t *)pud_page_vaddr(*pud);
+       pud_clear(pud);
+
+       flush_tlb_kernel_range(addr, addr + PUD_SIZE);
+
+       for (i = 0; i < PTRS_PER_PMD; i++) {
+               if (!pmd_none(pmd[i])) {
+                       pte_t *pte;
+                       pte = (pte_t *)pmd_page_vaddr(pmd[i]);
+
+                       pte_free_kernel(&init_mm, pte);
+               }
+       }
+
+       pmd_free(&init_mm, pmd);
+
+       return 1;
+}
+
+int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
+{
+       pte_t *ptep = (pte_t *)pmd;
+       pte_t new_pmd = pfn_pte(__phys_to_pfn(addr), prot);
+
+       if (!radix_enabled())
+               return 0;
+
+       set_pte_at(&init_mm, 0 /* radix unused */, ptep, new_pmd);
+
+       return 1;
+}
+
+int pmd_clear_huge(pmd_t *pmd)
+{
+       if (pmd_huge(*pmd)) {
+               pmd_clear(pmd);
+               return 1;
+       }
+
+       return 0;
+}
+
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
+{
+       pte_t *pte;
+
+       pte = (pte_t *)pmd_page_vaddr(*pmd);
+       pmd_clear(pmd);
+
+       flush_tlb_kernel_range(addr, addr + PMD_SIZE);
+
+       pte_free_kernel(&init_mm, pte);
+
+       return 1;
+}
+
+int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size,
+                       pgprot_t prot, int nid)
+{
+       if (likely(slab_is_available())) {
+               int err = ioremap_page_range(ea, ea + size, pa, prot);
+               if (err)
+                       unmap_kernel_range(ea, size);
+               return err;
+       } else {
+               unsigned long i;
+
+               for (i = 0; i < size; i += PAGE_SIZE) {
+                       int err = map_kernel_page(ea + i, pa + i, prot);
+                       if (WARN_ON_ONCE(err)) /* Should clean up */
+                               return err;
+               }
+               return 0;
+       }
+}
index 16ada373b32b5144d2e94941d56d9c3a07bf2f6c..f3aab4398082de8695e1564d3697755c5e2dc2b5 100644 (file)
@@ -365,7 +365,7 @@ void mark_initmem_nx(void)
        unsigned long numpages = PFN_UP((unsigned long)_einittext) -
                                 PFN_DOWN((unsigned long)_sinittext);
 
-       if (v_block_mapped((unsigned long)_stext) + 1)
+       if (v_block_mapped((unsigned long)_stext + 1))
                mmu_mark_initmem_nx();
        else
                change_page_attr(page, numpages, PAGE_KERNEL);
index d2d976ff8a0e2f2c33004229bef390ea65e3a20c..63cd811306435184b0545cf618fa34dc975914ad 100644 (file)
@@ -108,14 +108,30 @@ unsigned long ioremap_bot;
 unsigned long ioremap_bot = IOREMAP_BASE;
 #endif
 
+int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid)
+{
+       unsigned long i;
+
+       for (i = 0; i < size; i += PAGE_SIZE) {
+               int err = map_kernel_page(ea + i, pa + i, prot);
+               if (err) {
+                       if (slab_is_available())
+                               unmap_kernel_range(ea, size);
+                       else
+                               WARN_ON_ONCE(1); /* Should clean up */
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * __ioremap_at - Low level function to establish the page tables
  *                for an IO mapping
  */
 void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_t prot)
 {
-       unsigned long i;
-
        /* We don't support the 4K PFN hack with ioremap */
        if (pgprot_val(prot) & H_PAGE_4K_PFN)
                return NULL;
@@ -129,9 +145,8 @@ void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_
        WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
        WARN_ON(size & ~PAGE_MASK);
 
-       for (i = 0; i < size; i += PAGE_SIZE)
-               if (map_kernel_page((unsigned long)ea + i, pa + i, prot))
-                       return NULL;
+       if (ioremap_range((unsigned long)ea, pa, size, prot, NUMA_NO_NODE))
+               return NULL;
 
        return (void __iomem *)ea;
 }
@@ -182,8 +197,6 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
 
                area->phys_addr = paligned;
                ret = __ioremap_at(paligned, area->addr, size, prot);
-               if (!ret)
-                       vunmap(area->addr);
        } else {
                ret = __ioremap_at(paligned, (void *)ioremap_bot, size, prot);
                if (ret)
index 3bdfc1e3209647c29ce497c5a64d7a5a15c65b90..dea243185ea4bc883de803e976d0be39cf4d3202 100644 (file)
@@ -362,7 +362,14 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu)
         */
        nid = cpu_to_node(cpu);
        l_cpumask = cpumask_of_node(nid);
-       target = cpumask_any_but(l_cpumask, cpu);
+       target = cpumask_last(l_cpumask);
+
+       /*
+        * If this(target) is the last cpu in the cpumask for this chip,
+        * check for any possible online cpu in the chip.
+        */
+       if (unlikely(target == cpu))
+               target = cpumask_any_but(l_cpumask, cpu);
 
        /*
         * Update the cpumask with the target cpu and
@@ -667,7 +674,10 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)
                return 0;
 
        /* Find any online cpu in that core except the current "cpu" */
-       ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu);
+       ncpu = cpumask_last(cpu_sibling_mask(cpu));
+
+       if (unlikely(ncpu == cpu))
+               ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu);
 
        if (ncpu >= 0 && ncpu < nr_cpu_ids) {
                cpumask_set_cpu(ncpu, &core_imc_cpumask);
index fb64b09cad9dad25ef3e9838f8eae8f4ac2f56d4..eb583bd9a75d27541f5a7dd040218aaf34dd3964 100644 (file)
 #define SL_IBAT2       0x48
 #define SL_DBAT3       0x50
 #define SL_IBAT3       0x58
-#define SL_TB          0x60
-#define SL_R2          0x68
-#define SL_CR          0x6c
-#define SL_R12         0x70    /* r12 to r31 */
+#define SL_DBAT4       0x60
+#define SL_IBAT4       0x68
+#define SL_DBAT5       0x70
+#define SL_IBAT5       0x78
+#define SL_DBAT6       0x80
+#define SL_IBAT6       0x88
+#define SL_DBAT7       0x90
+#define SL_IBAT7       0x98
+#define SL_TB          0xa0
+#define SL_R2          0xa8
+#define SL_CR          0xac
+#define SL_R12         0xb0    /* r12 to r31 */
 #define SL_SIZE                (SL_R12 + 80)
 
        .section .text
@@ -126,6 +134,41 @@ _GLOBAL(low_sleep_handler)
        mfibatl r4,3
        stw     r4,SL_IBAT3+4(r1)
 
+BEGIN_MMU_FTR_SECTION
+       mfspr   r4,SPRN_DBAT4U
+       stw     r4,SL_DBAT4(r1)
+       mfspr   r4,SPRN_DBAT4L
+       stw     r4,SL_DBAT4+4(r1)
+       mfspr   r4,SPRN_DBAT5U
+       stw     r4,SL_DBAT5(r1)
+       mfspr   r4,SPRN_DBAT5L
+       stw     r4,SL_DBAT5+4(r1)
+       mfspr   r4,SPRN_DBAT6U
+       stw     r4,SL_DBAT6(r1)
+       mfspr   r4,SPRN_DBAT6L
+       stw     r4,SL_DBAT6+4(r1)
+       mfspr   r4,SPRN_DBAT7U
+       stw     r4,SL_DBAT7(r1)
+       mfspr   r4,SPRN_DBAT7L
+       stw     r4,SL_DBAT7+4(r1)
+       mfspr   r4,SPRN_IBAT4U
+       stw     r4,SL_IBAT4(r1)
+       mfspr   r4,SPRN_IBAT4L
+       stw     r4,SL_IBAT4+4(r1)
+       mfspr   r4,SPRN_IBAT5U
+       stw     r4,SL_IBAT5(r1)
+       mfspr   r4,SPRN_IBAT5L
+       stw     r4,SL_IBAT5+4(r1)
+       mfspr   r4,SPRN_IBAT6U
+       stw     r4,SL_IBAT6(r1)
+       mfspr   r4,SPRN_IBAT6L
+       stw     r4,SL_IBAT6+4(r1)
+       mfspr   r4,SPRN_IBAT7U
+       stw     r4,SL_IBAT7(r1)
+       mfspr   r4,SPRN_IBAT7L
+       stw     r4,SL_IBAT7+4(r1)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
+
        /* Backup various CPU config stuffs */
        bl      __save_cpu_setup
 
@@ -326,22 +369,37 @@ grackle_wake_up:
        mtibatl 3,r4
 
 BEGIN_MMU_FTR_SECTION
-       li      r4,0
+       lwz     r4,SL_DBAT4(r1)
        mtspr   SPRN_DBAT4U,r4
+       lwz     r4,SL_DBAT4+4(r1)
        mtspr   SPRN_DBAT4L,r4
+       lwz     r4,SL_DBAT5(r1)
        mtspr   SPRN_DBAT5U,r4
+       lwz     r4,SL_DBAT5+4(r1)
        mtspr   SPRN_DBAT5L,r4
+       lwz     r4,SL_DBAT6(r1)
        mtspr   SPRN_DBAT6U,r4
+       lwz     r4,SL_DBAT6+4(r1)
        mtspr   SPRN_DBAT6L,r4
+       lwz     r4,SL_DBAT7(r1)
        mtspr   SPRN_DBAT7U,r4
+       lwz     r4,SL_DBAT7+4(r1)
        mtspr   SPRN_DBAT7L,r4
+       lwz     r4,SL_IBAT4(r1)
        mtspr   SPRN_IBAT4U,r4
+       lwz     r4,SL_IBAT4+4(r1)
        mtspr   SPRN_IBAT4L,r4
+       lwz     r4,SL_IBAT5(r1)
        mtspr   SPRN_IBAT5U,r4
+       lwz     r4,SL_IBAT5+4(r1)
        mtspr   SPRN_IBAT5L,r4
+       lwz     r4,SL_IBAT6(r1)
        mtspr   SPRN_IBAT6U,r4
+       lwz     r4,SL_IBAT6+4(r1)
        mtspr   SPRN_IBAT6L,r4
+       lwz     r4,SL_IBAT7(r1)
        mtspr   SPRN_IBAT7U,r4
+       lwz     r4,SL_IBAT7+4(r1)
        mtspr   SPRN_IBAT7L,r4
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
 
index c9133f7908ca167181132a6d3d1ec03dbadc2ea0..77f2e0a4ee3723bfa55060867adfe23a3ef6a95b 100644 (file)
@@ -1159,10 +1159,10 @@ static void __init pnv_power9_idle_init(void)
                        pnv_deepest_stop_psscr_mask);
        }
 
-       pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%lld\n",
+       pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%llx\n",
                pnv_first_spr_loss_level);
 
-       pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%lld\n",
+       pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%llx\n",
                pnv_first_tb_loss_level);
 }
 
index 495550432f3d62fd50a2aeacdfd902a5f20303b8..dc1058efc24fcaa7b42ff77c9bc8e7a11c50a2a7 100644 (file)
@@ -31,9 +31,22 @@ static DEFINE_SPINLOCK(npu_context_lock);
 static struct pci_dev *get_pci_dev(struct device_node *dn)
 {
        struct pci_dn *pdn = PCI_DN(dn);
+       struct pci_dev *pdev;
 
-       return pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus),
+       pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus),
                                           pdn->busno, pdn->devfn);
+
+       /*
+        * pci_get_domain_bus_and_slot() increased the reference count of
+        * the PCI device, but callers don't need that actually as the PE
+        * already holds a reference to the device. Since callers aren't
+        * aware of the reference count change, call pci_dev_put() now to
+        * avoid leaks.
+        */
+       if (pdev)
+               pci_dev_put(pdev);
+
+       return pdev;
 }
 
 /* Given a NPU device get the associated PCI device. */
index 5cae375525d093854561cd8f5799d435374946bb..3e1f064a18db3ab7cd3d30d9b1e41d111266f566 100644 (file)
@@ -137,6 +137,43 @@ static void print_nx_checkstop_reason(const char *level,
                                        xstop_reason[i].description);
 }
 
+static void print_npu_checkstop_reason(const char *level,
+                                       struct OpalHMIEvent *hmi_evt)
+{
+       uint8_t reason, reason_count, i;
+
+       /*
+        * We may not have a checkstop reason on some combination of
+        * hardware and/or skiboot version
+        */
+       if (!hmi_evt->u.xstop_error.xstop_reason) {
+               printk("%s      NPU checkstop on chip %x\n", level,
+                       be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id));
+               return;
+       }
+
+       /*
+        * NPU2 has 3 FIRs. Reason encoded on a byte as:
+        *   2 bits for the FIR number
+        *   6 bits for the bit number
+        * It may be possible to find several reasons.
+        *
+        * We don't display a specific message per FIR bit as there
+        * are too many and most are meaningless without the workbook
+        * and/or hw team help anyway.
+        */
+       reason_count = sizeof(hmi_evt->u.xstop_error.xstop_reason) /
+               sizeof(reason);
+       for (i = 0; i < reason_count; i++) {
+               reason = (hmi_evt->u.xstop_error.xstop_reason >> (8 * i)) & 0xFF;
+               if (reason)
+                       printk("%s      NPU checkstop on chip %x: FIR%d bit %d is set\n",
+                               level,
+                               be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id),
+                               reason >> 6, reason & 0x3F);
+       }
+}
+
 static void print_checkstop_reason(const char *level,
                                        struct OpalHMIEvent *hmi_evt)
 {
@@ -148,6 +185,9 @@ static void print_checkstop_reason(const char *level,
        case CHECKSTOP_TYPE_NX:
                print_nx_checkstop_reason(level, hmi_evt);
                break;
+       case CHECKSTOP_TYPE_NPU:
+               print_npu_checkstop_reason(level, hmi_evt);
+               break;
        default:
                printk("%s      Unknown Malfunction Alert of type %d\n",
                       level, type);
index f2b063b027f0adb5c5064ee133f2ab355f788797..89b6ddc3ed38002ac04e561a3689f14226f5114d 100644 (file)
@@ -206,16 +206,18 @@ static int __init opal_register_exception_handlers(void)
        glue = 0x7000;
 
        /*
-        * Check if we are running on newer firmware that exports
-        * OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to patch
-        * the HMI interrupt and we catch it directly in Linux.
+        * Only ancient OPAL firmware requires this.
+        * Specifically, firmware from FW810.00 (released June 2014)
+        * through FW810.20 (Released October 2014).
         *
-        * For older firmware (i.e currently released POWER8 System Firmware
-        * as of today <= SV810_087), we fallback to old behavior and let OPAL
-        * patch the HMI vector and handle it inside OPAL firmware.
+        * Check if we are running on newer (post Oct 2014) firmware that
+        * exports the OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to
+        * patch the HMI interrupt and we catch it directly in Linux.
         *
-        * For newer firmware (in development/yet to be released) we will
-        * start catching/handling HMI directly in Linux.
+        * For older firmware (i.e < FW810.20), we fallback to old behavior and
+        * let OPAL patch the HMI vector and handle it inside OPAL firmware.
+        *
+        * For newer firmware we catch/handle the HMI directly in Linux.
         */
        if (!opal_check_token(OPAL_HANDLE_HMI)) {
                pr_info("Old firmware detected, OPAL handles HMIs.\n");
@@ -225,6 +227,11 @@ static int __init opal_register_exception_handlers(void)
                glue += 128;
        }
 
+       /*
+        * Only applicable to ancient firmware, all modern
+        * (post March 2015/skiboot 5.0) firmware will just return
+        * OPAL_UNSUPPORTED.
+        */
        opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
 #endif
 
index 17958043e7f7be29c17f90b369ab13842cef49ae..4989c576239801389cdf3336ef1305201baa55ee 100644 (file)
@@ -61,6 +61,10 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
 
        name = (char *)ccwa + be32_to_cpu(ccwa->name_offset);
        prop->name = kstrdup(name, GFP_KERNEL);
+       if (!prop->name) {
+               dlpar_free_cc_property(prop);
+               return NULL;
+       }
 
        prop->length = be32_to_cpu(ccwa->prop_length);
        value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset);
@@ -386,11 +390,11 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog)
        struct pseries_hp_work *work;
        struct pseries_hp_errorlog *hp_errlog_copy;
 
-       hp_errlog_copy = kmalloc(sizeof(struct pseries_hp_errorlog),
-                                GFP_KERNEL);
-       memcpy(hp_errlog_copy, hp_errlog, sizeof(struct pseries_hp_errorlog));
+       hp_errlog_copy = kmemdup(hp_errlog, sizeof(*hp_errlog), GFP_ATOMIC);
+       if (!hp_errlog_copy)
+               return;
 
-       work = kmalloc(sizeof(struct pseries_hp_work), GFP_KERNEL);
+       work = kmalloc(sizeof(struct pseries_hp_work), GFP_ATOMIC);
        if (work) {
                INIT_WORK((struct work_struct *)work, pseries_hp_work_fn);
                work->errlog = hp_errlog_copy;
index 47087832f8b2ecd56defcd64d7c5a467bac5085d..e6bd172bcf3057247adbbb9dfbe9bc2ae5fb85f4 100644 (file)
@@ -980,6 +980,9 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr)
        if (!memblock_size)
                return -EINVAL;
 
+       if (!pr->old_prop)
+               return 0;
+
        p = (__be32 *) pr->old_prop->value;
        if (!p)
                return -EINVAL;
index 74da18de853af670f911acc800e50d076bff4f8c..73ec15cd27080f256cd86ac57f04f48550686603 100644 (file)
@@ -62,7 +62,7 @@ EXPORT_SYMBOL(hvc_get_chars);
  * @vtermno: The vtermno or unit_address of the adapter from which the data
  *     originated.
  * @buf: The character buffer that contains the character data to send to
- *     firmware.
+ *     firmware. Must be at least 16 bytes, even if count is less than 16.
  * @count: Send this number of characters.
  */
 int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
index 88925f8ca8a0953c781995107f292b8ac7211b1a..b8c8096907d4d7d505f6b0749995b8859bad323f 100644 (file)
@@ -9,6 +9,7 @@
  * 2 as published by the Free Software Foundation.
  */
 
+#include <linux/cpu.h>
 #include <linux/kernel.h>
 #include <linux/kobject.h>
 #include <linux/smp.h>
@@ -22,6 +23,7 @@
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include "pseries.h"
+#include "../../kernel/cacheinfo.h"
 
 static struct kobject *mobility_kobj;
 
@@ -338,11 +340,28 @@ void post_mobility_fixup(void)
        if (rc)
                printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
 
+       /*
+        * We don't want CPUs to go online/offline while the device
+        * tree is being updated.
+        */
+       cpus_read_lock();
+
+       /*
+        * It's common for the destination firmware to replace cache
+        * nodes.  Release all of the cacheinfo hierarchy's references
+        * before updating the device tree.
+        */
+       cacheinfo_teardown();
+
        rc = pseries_devicetree_update(MIGRATION_SCOPE);
        if (rc)
                printk(KERN_ERR "Post-mobility device tree update "
                        "failed: %d\n", rc);
 
+       cacheinfo_rebuild();
+
+       cpus_read_unlock();
+
        /* Possibly switch to a new RFI flush type */
        pseries_setup_rfi_flush();
 
index 575db3b06a6b84acdcb7625dc3b1e2eaa688e882..2e2d1b8f810fb1c5fe1bfd2efeeb1a708efcf910 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/cpumask.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/libfdt.h>
 
 #include <asm/prom.h>
 #include <asm/io.h>
@@ -663,6 +664,55 @@ static bool xive_get_max_prio(u8 *max_prio)
        return true;
 }
 
+static const u8 *get_vec5_feature(unsigned int index)
+{
+       unsigned long root, chosen;
+       int size;
+       const u8 *vec5;
+
+       root = of_get_flat_dt_root();
+       chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
+       if (chosen == -FDT_ERR_NOTFOUND)
+               return NULL;
+
+       vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
+       if (!vec5)
+               return NULL;
+
+       if (size <= index)
+               return NULL;
+
+       return vec5 + index;
+}
+
+static bool xive_spapr_disabled(void)
+{
+       const u8 *vec5_xive;
+
+       vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT));
+       if (vec5_xive) {
+               u8 val;
+
+               val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT);
+               switch (val) {
+               case OV5_FEAT(OV5_XIVE_EITHER):
+               case OV5_FEAT(OV5_XIVE_LEGACY):
+                       break;
+               case OV5_FEAT(OV5_XIVE_EXPLOIT):
+                       /* Hypervisor only supports XIVE */
+                       if (xive_cmdline_disabled)
+                               pr_warn("WARNING: Ignoring cmdline option xive=off\n");
+                       return false;
+               default:
+                       pr_warn("%s: Unknown xive support option: 0x%x\n",
+                               __func__, val);
+                       break;
+               }
+       }
+
+       return xive_cmdline_disabled;
+}
+
 bool __init xive_spapr_init(void)
 {
        struct device_node *np;
@@ -675,7 +725,7 @@ bool __init xive_spapr_init(void)
        const __be32 *reg;
        int i;
 
-       if (xive_cmdline_disabled)
+       if (xive_spapr_disabled())
                return false;
 
        pr_devel("%s()\n", __func__);
index d1d927ccb589cf6ee712e28084021a8c3319c8b5..1e3e1ee683953caf21285f93ed5a69693dbc0995 100644 (file)
@@ -912,11 +912,11 @@ void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx);
 
 #ifdef CONFIG_DEBUG_FS
 
-int cxl_debugfs_init(void);
+void cxl_debugfs_init(void);
 void cxl_debugfs_exit(void);
-int cxl_debugfs_adapter_add(struct cxl *adapter);
+void cxl_debugfs_adapter_add(struct cxl *adapter);
 void cxl_debugfs_adapter_remove(struct cxl *adapter);
-int cxl_debugfs_afu_add(struct cxl_afu *afu);
+void cxl_debugfs_afu_add(struct cxl_afu *afu);
 void cxl_debugfs_afu_remove(struct cxl_afu *afu);
 void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir);
 void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir);
@@ -925,27 +925,24 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir);
 
 #else /* CONFIG_DEBUG_FS */
 
-static inline int __init cxl_debugfs_init(void)
+static inline void __init cxl_debugfs_init(void)
 {
-       return 0;
 }
 
 static inline void cxl_debugfs_exit(void)
 {
 }
 
-static inline int cxl_debugfs_adapter_add(struct cxl *adapter)
+static inline void cxl_debugfs_adapter_add(struct cxl *adapter)
 {
-       return 0;
 }
 
 static inline void cxl_debugfs_adapter_remove(struct cxl *adapter)
 {
 }
 
-static inline int cxl_debugfs_afu_add(struct cxl_afu *afu)
+static inline void cxl_debugfs_afu_add(struct cxl_afu *afu)
 {
-       return 0;
 }
 
 static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu)
index a1921d81593afcebadfa25058d5be9bc01b9053f..e199a8021ab91065a4f9d4b99e068fdf2cd1e978 100644 (file)
@@ -30,11 +30,11 @@ static int debugfs_io_u64_set(void *data, u64 val)
 DEFINE_DEBUGFS_ATTRIBUTE(fops_io_x64, debugfs_io_u64_get, debugfs_io_u64_set,
                         "0x%016llx\n");
 
-static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode,
-                                           struct dentry *parent, u64 __iomem *value)
+static void debugfs_create_io_x64(const char *name, umode_t mode,
+                                 struct dentry *parent, u64 __iomem *value)
 {
-       return debugfs_create_file_unsafe(name, mode, parent,
-                                         (void __force *)value, &fops_io_x64);
+       debugfs_create_file_unsafe(name, mode, parent, (void __force *)value,
+                                  &fops_io_x64);
 }
 
 void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir)
@@ -58,25 +58,22 @@ void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir)
        debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_TRACE));
 }
 
-int cxl_debugfs_adapter_add(struct cxl *adapter)
+void cxl_debugfs_adapter_add(struct cxl *adapter)
 {
        struct dentry *dir;
        char buf[32];
 
        if (!cxl_debugfs)
-               return -ENODEV;
+               return;
 
        snprintf(buf, 32, "card%i", adapter->adapter_num);
        dir = debugfs_create_dir(buf, cxl_debugfs);
-       if (IS_ERR(dir))
-               return PTR_ERR(dir);
        adapter->debugfs = dir;
 
        debugfs_create_io_x64("err_ivte", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_ErrIVTE));
 
        if (adapter->native->sl_ops->debugfs_add_adapter_regs)
                adapter->native->sl_ops->debugfs_add_adapter_regs(adapter, dir);
-       return 0;
 }
 
 void cxl_debugfs_adapter_remove(struct cxl *adapter)
@@ -100,18 +97,16 @@ void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir)
        debugfs_create_io_x64("trace", S_IRUSR | S_IWUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SLICE_TRACE));
 }
 
-int cxl_debugfs_afu_add(struct cxl_afu *afu)
+void cxl_debugfs_afu_add(struct cxl_afu *afu)
 {
        struct dentry *dir;
        char buf[32];
 
        if (!afu->adapter->debugfs)
-               return -ENODEV;
+               return;
 
        snprintf(buf, 32, "psl%i.%i", afu->adapter->adapter_num, afu->slice);
        dir = debugfs_create_dir(buf, afu->adapter->debugfs);
-       if (IS_ERR(dir))
-               return PTR_ERR(dir);
        afu->debugfs = dir;
 
        debugfs_create_io_x64("sr",         S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SR_An));
@@ -122,8 +117,6 @@ int cxl_debugfs_afu_add(struct cxl_afu *afu)
 
        if (afu->adapter->native->sl_ops->debugfs_add_afu_regs)
                afu->adapter->native->sl_ops->debugfs_add_afu_regs(afu, dir);
-
-       return 0;
 }
 
 void cxl_debugfs_afu_remove(struct cxl_afu *afu)
@@ -131,19 +124,12 @@ void cxl_debugfs_afu_remove(struct cxl_afu *afu)
        debugfs_remove_recursive(afu->debugfs);
 }
 
-int __init cxl_debugfs_init(void)
+void __init cxl_debugfs_init(void)
 {
-       struct dentry *ent;
-
        if (!cpu_has_feature(CPU_FTR_HVMODE))
-               return 0;
-
-       ent = debugfs_create_dir("cxl", NULL);
-       if (IS_ERR(ent))
-               return PTR_ERR(ent);
-       cxl_debugfs = ent;
+               return;
 
-       return 0;
+       cxl_debugfs = debugfs_create_dir("cxl", NULL);
 }
 
 void cxl_debugfs_exit(void)
index f2a3ef4b9bdde0b11728a7f1db2cc18ffd8cd71e..cb920aa88d3a1d48964317d2d429680d9f0cba0f 100644 (file)
@@ -41,7 +41,7 @@ static int ocxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return 0;
 }
 
-void ocxl_remove(struct pci_dev *dev)
+static void ocxl_remove(struct pci_dev *dev)
 {
        struct ocxl_fn *fn;
        struct ocxl_afu *afu;
index 6de6d4a1a221c1c0b24c936f863d121fc5cea88d..7af54d6ed5b8420f8d68fd74e9fb8db94e98ff69 100644 (file)
@@ -107,6 +107,14 @@ static int hvterm_raw_get_chars(uint32_t vtermno, char *buf, int count)
        return got;
 }
 
+/**
+ * hvterm_raw_put_chars: send characters to firmware for given vterm adapter
+ * @vtermno: The virtual terminal number.
+ * @buf: The characters to send. Because of the underlying hypercall in
+ *       hvc_put_chars(), this buffer must be at least 16 bytes long, even if
+ *       you are sending fewer chars.
+ * @count: number of chars to send.
+ */
 static int hvterm_raw_put_chars(uint32_t vtermno, const char *buf, int count)
 {
        struct hvterm_priv *pv = hvterm_privs[vtermno];
@@ -219,6 +227,7 @@ static const struct hv_ops hvterm_hvsi_ops = {
 static void udbg_hvc_putc(char c)
 {
        int count = -1;
+       unsigned char bounce_buffer[16];
 
        if (!hvterm_privs[0])
                return;
@@ -229,7 +238,12 @@ static void udbg_hvc_putc(char c)
        do {
                switch(hvterm_privs[0]->proto) {
                case HV_PROTOCOL_RAW:
-                       count = hvterm_raw_put_chars(0, &c, 1);
+                       /*
+                        * hvterm_raw_put_chars requires at least a 16-byte
+                        * buffer, so go via the bounce buffer
+                        */
+                       bounce_buffer[0] = c;
+                       count = hvterm_raw_put_chars(0, bounce_buffer, 1);
                        break;
                case HV_PROTOCOL_HVSI:
                        count = hvterm_hvsi_put_chars(0, &c, 1);
index 97937cfa3baae3ebc334fbb668806774a3542b85..6d29a60a896ab607c1e0c6d3e97a667abda1500b 100644 (file)
@@ -33,23 +33,23 @@ struct ocxl_ioctl_attach {
 };
 
 struct ocxl_ioctl_metadata {
-       __u16 version; // struct version, always backwards compatible
+       __u16 version; /* struct version, always backwards compatible */
 
-       // Version 0 fields
+       /* Version 0 fields */
        __u8  afu_version_major;
        __u8  afu_version_minor;
-       __u32 pasid;            // PASID assigned to the current context
+       __u32 pasid;            /* PASID assigned to the current context */
 
-       __u64 pp_mmio_size;     // Per PASID MMIO size
+       __u64 pp_mmio_size;     /* Per PASID MMIO size */
        __u64 global_mmio_size;
 
-       // End version 0 fields
+       /* End version 0 fields */
 
-       __u64 reserved[13]; // Total of 16*u64
+       __u64 reserved[13]; /* Total of 16*u64 */
 };
 
 struct ocxl_ioctl_p9_wait {
-       __u16 thread_id; // The thread ID required to wake this thread
+       __u16 thread_id; /* The thread ID required to wake this thread */
        __u16 reserved1;
        __u32 reserved2;
        __u64 reserved3[3];
index fe52811584ae0bfa9b3098e1c5e455bf9379e627..0815f06f3590a321563248be9cfae63e9d3407e0 100644 (file)
@@ -79,7 +79,7 @@ int test_vmxcopy()
 
                "5:;"
                "stxvd2x 40,0,%[vecoutptr];"
-               : [res]"=r"(aborted)
+               : [res]"=&r"(aborted)
                : [vecinptr]"r"(&vecin),
                  [vecoutptr]"r"(&vecout),
                  [map]"r"(a)