History

Merge tag 'powerpc-4.9-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman: "Fixes marked for stable: - Prevent unlikely crash in copro_calculate_slb() (Frederic Barrat) - cxl: Prevent adapter reset if an active context exists (Vaibhav Jain) Fixes for code merged this cycle: - Fix boot on systems with uncompressed kernel image (Heiner Kallweit) - Drop dump_numa_memory_topology() (Michael Ellerman) - Fix numa topology console print (Aneesh Kumar K.V) - Ignore the pkey system calls for now (Stephen Rothwell)" * tag 'powerpc-4.9-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc: Ignore the pkey system calls for now powerpc: Fix numa topology console print powerpc/mm: Drop dump_numa_memory_topology() cxl: Prevent adapter reset if an active context exists powerpc/boot: Fix boot on systems with uncompressed kernel image powerpc/mm: Prevent unlikely crash in copro_calculate_slb()

Linus Torvalds committed 10 years ago

Commit dcd46932 parents a23b27a 78914ff13 files · +148 −50Browse files

Unified · Split

13 files
  1. Documentation/ABI/testing/sysfs-class-cxl +5 −2
  2. arch/powerpc/boot/main.c +16 −2
  3. arch/powerpc/include/asm/unistd.h +4 −0
  4. arch/powerpc/mm/copro_fault.c +2 −0
  5. arch/powerpc/mm/numa.c +5 −41
  6. drivers/misc/cxl/api.c +9 −0
  7. drivers/misc/cxl/context.c +3 −0
  8. drivers/misc/cxl/cxl.h +24 −0
  9. drivers/misc/cxl/file.c +11 −0
  10. drivers/misc/cxl/guest.c +3 −0
  11. drivers/misc/cxl/main.c +41 −1
  12. drivers/misc/cxl/pci.c +2 −0
  13. drivers/misc/cxl/sysfs.c +23 −4
Documentation/ABI/testing/sysfs-class-cxl+5−2
@@ -220,8 +220,11 @@ What: /sys/class/cxl/<card>/reset · 219 unmodified lines
220220 Date: October 2014
221221 Contact: linuxppc-dev@lists.ozlabs.org
222222 Description: write only
223− Writing 1 will issue a PERST to card which may cause the card
224− to reload the FPGA depending on load_image_on_perst.
223+ Writing 1 will issue a PERST to card provided there are no
224+ contexts active on any one of the card AFUs. This may cause
225+ the card to reload the FPGA depending on load_image_on_perst.
226+ Writing -1 will do a force PERST irrespective of any active
227+ contexts on the card AFUs.
225228 Users: https://github.com/ibm-capi/libcxl
226229
227230 What: /sys/class/cxl/<card>/perst_reloads_same_image (not in a guest)
arch/powerpc/boot/main.c+16−2
@@ -32,9 +32,16 @@ static struct addr_range prep_kernel(void) · 31 unmodified lines
3232 void *addr = 0;
3333 struct elf_info ei;
3434 long len;
35+ int uncompressed_image = 0;
3536
36− partial_decompress(vmlinuz_addr, vmlinuz_size,
37+ len = partial_decompress(vmlinuz_addr, vmlinuz_size,
3738 elfheader, sizeof(elfheader), 0);
39+ /* assume uncompressed data if -1 is returned */
40+ if (len == -1) {
41+ uncompressed_image = 1;
42+ memcpy(elfheader, vmlinuz_addr, sizeof(elfheader));
43+ printf("No valid compressed data found, assume uncompressed data\n\r");
44+ }
3845
3946 if (!parse_elf64(elfheader, &ei) && !parse_elf32(elfheader, &ei))
4047 fatal("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
@@ -67,6 +74,13 @@ static struct addr_range prep_kernel(void) · 26 unmodified lines
6774 "device tree\n\r");
6875 }
6976
77+ if (uncompressed_image) {
78+ memcpy(addr, vmlinuz_addr + ei.elfoffset, ei.loadsize);
79+ printf("0x%lx bytes of uncompressed data copied\n\r",
80+ ei.loadsize);
81+ goto out;
82+ }
83+
7084 /* Finally, decompress the kernel */
7185 printf("Decompressing (0x%p <- 0x%p:0x%p)...\n\r", addr,
7286 vmlinuz_addr, vmlinuz_addr+vmlinuz_size);
@@ -82,7 +96,7 @@ static struct addr_range prep_kernel(void) · 9 unmodified lines
8296 len, ei.loadsize);
8397
8498 printf("Done! Decompressed 0x%lx bytes\n\r", len);
85−
99+out:
86100 flush_cache(addr, ei.loadsize);
87101
88102 return (struct addr_range){addr, ei.memsize};
arch/powerpc/include/asm/unistd.h+4−0
@@ -16,6 +16,10 @@ · 15 unmodified lines
1616
1717 #define __NR__exit __NR_exit
1818
19+#define __IGNORE_pkey_mprotect
20+#define __IGNORE_pkey_alloc
21+#define __IGNORE_pkey_free
22+
1923 #ifndef __ASSEMBLY__
2024
2125 #include <linux/types.h>
arch/powerpc/mm/copro_fault.c+2−0
@@ -106,6 +106,8 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) · 105 unmodified lines
106106 switch (REGION_ID(ea)) {
107107 case USER_REGION_ID:
108108 pr_devel("%s: 0x%llx -- USER_REGION_ID\n", __func__, ea);
109+ if (mm == NULL)
110+ return 1;
109111 psize = get_slice_psize(mm, ea);
110112 ssize = user_segment_size(ea);
111113 vsid = get_vsid(mm->context.id, ea, ssize);
arch/powerpc/mm/numa.c+5−41
@@ -845,7 +845,7 @@ void __init dump_numa_cpu_topology(void) · 844 unmodified lines
845845 return;
846846
847847 for_each_online_node(node) {
848− printk(KERN_DEBUG "Node %d CPUs:", node);
848+ pr_info("Node %d CPUs:", node);
849849
850850 count = 0;
851851 /*
@@ -856,52 +856,18 @@ void __init dump_numa_cpu_topology(void) · 4 unmodified lines
856856 if (cpumask_test_cpu(cpu,
857857 node_to_cpumask_map[node])) {
858858 if (count == 0)
859− printk(" %u", cpu);
859+ pr_cont(" %u", cpu);
860860 ++count;
861861 } else {
862862 if (count > 1)
863− printk("-%u", cpu - 1);
863+ pr_cont("-%u", cpu - 1);
864864 count = 0;
865865 }
866866 }
867867
868868 if (count > 1)
869− printk("-%u", nr_cpu_ids - 1);
870− printk("\n");
871− }
872−}
873−
874−static void __init dump_numa_memory_topology(void)
875−{
876− unsigned int node;
877− unsigned int count;
878−
879− if (min_common_depth == -1 || !numa_enabled)
880− return;
881−
882− for_each_online_node(node) {
883− unsigned long i;
884−
885− printk(KERN_DEBUG "Node %d Memory:", node);
886−
887− count = 0;
888−
889− for (i = 0; i < memblock_end_of_DRAM();
890− i += (1 << SECTION_SIZE_BITS)) {
891− if (early_pfn_to_nid(i >> PAGE_SHIFT) == node) {
892− if (count == 0)
893− printk(" 0x%lx", i);
894− ++count;
895− } else {
896− if (count > 0)
897− printk("-0x%lx", i);
898− count = 0;
899− }
900− }
901−
902− if (count > 0)
903− printk("-0x%lx", i);
904− printk("\n");
869+ pr_cont("-%u", nr_cpu_ids - 1);
870+ pr_cont("\n");
905871 }
906872 }
907873
@@ -947,8 +913,6 @@ void __init initmem_init(void) · 39 unmodified lines
947913
948914 if (parse_numa_properties())
949915 setup_nonnuma();
950− else
951− dump_numa_memory_topology();
952916
953917 memblock_dump_all();
954918
drivers/misc/cxl/api.c+9−0
@@ -229,6 +229,14 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, · 228 unmodified lines
229229 if (ctx->status == STARTED)
230230 goto out; /* already started */
231231
232+ /*
233+ * Increment the mapped context count for adapter. This also checks
234+ * if adapter_context_lock is taken.
235+ */
236+ rc = cxl_adapter_context_get(ctx->afu->adapter);
237+ if (rc)
238+ goto out;
239+
232240 if (task) {
233241 ctx->pid = get_task_pid(task, PIDTYPE_PID);
234242 ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
@@ -240,6 +248,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, · 5 unmodified lines
240248
241249 if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
242250 put_pid(ctx->pid);
251+ cxl_adapter_context_put(ctx->afu->adapter);
243252 cxl_ctx_put();
244253 goto out;
245254 }
drivers/misc/cxl/context.c+3−0
@@ -238,6 +238,9 @@ int __detach_context(struct cxl_context *ctx) · 237 unmodified lines
238238 put_pid(ctx->glpid);
239239
240240 cxl_ctx_put();
241+
242+ /* Decrease the attached context count on the adapter */
243+ cxl_adapter_context_put(ctx->afu->adapter);
241244 return 0;
242245 }
243246
drivers/misc/cxl/cxl.h+24−0
@@ -618,6 +618,14 @@ struct cxl { · 617 unmodified lines
618618 bool perst_select_user;
619619 bool perst_same_image;
620620 bool psl_timebase_synced;
621+
622+ /*
623+ * number of contexts mapped on to this card. Possible values are:
624+ * >0: Number of contexts mapped and new one can be mapped.
625+ * 0: No active contexts and new ones can be mapped.
626+ * -1: No contexts mapped and new ones cannot be mapped.
627+ */
628+ atomic_t contexts_num;
621629 };
622630
623631 int cxl_pci_alloc_one_irq(struct cxl *adapter);
@@ -944,4 +952,20 @@ bool cxl_pci_is_vphb_device(struct pci_dev *dev); · 320 unmodified lines
944952
945953 /* decode AFU error bits in the PSL register PSL_SERR_An */
946954 void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr);
955+
956+/*
957+ * Increments the number of attached contexts on an adapter.
958+ * In case an adapter_context_lock is taken the return -EBUSY.
959+ */
960+int cxl_adapter_context_get(struct cxl *adapter);
961+
962+/* Decrements the number of attached contexts on an adapter */
963+void cxl_adapter_context_put(struct cxl *adapter);
964+
965+/* If no active contexts then prevents contexts from being attached */
966+int cxl_adapter_context_lock(struct cxl *adapter);
967+
968+/* Unlock the contexts-lock if taken. Warn and force unlock otherwise */
969+void cxl_adapter_context_unlock(struct cxl *adapter);
970+
947971 #endif
drivers/misc/cxl/file.c+11−0
@@ -205,11 +205,22 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, · 204 unmodified lines
205205 ctx->pid = get_task_pid(current, PIDTYPE_PID);
206206 ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
207207
208+ /*
209+ * Increment the mapped context count for adapter. This also checks
210+ * if adapter_context_lock is taken.
211+ */
212+ rc = cxl_adapter_context_get(ctx->afu->adapter);
213+ if (rc) {
214+ afu_release_irqs(ctx, ctx);
215+ goto out;
216+ }
217+
208218 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
209219
210220 if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
211221 amr))) {
212222 afu_release_irqs(ctx, ctx);
223+ cxl_adapter_context_put(ctx->afu->adapter);
213224 goto out;
214225 }
215226
drivers/misc/cxl/guest.c+3−0
@@ -1152,6 +1152,9 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic · 1151 unmodified lines
11521152 if ((rc = cxl_sysfs_adapter_add(adapter)))
11531153 goto err_put1;
11541154
1155+ /* release the context lock as the adapter is configured */
1156+ cxl_adapter_context_unlock(adapter);
1157+
11551158 return adapter;
11561159
11571160 err_put1:
drivers/misc/cxl/main.c+41−1
@@ -243,8 +243,10 @@ struct cxl *cxl_alloc_adapter(void) · 242 unmodified lines
243243 if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
244244 goto err2;
245245
246− return adapter;
246+ /* start with context lock taken */
247+ atomic_set(&adapter->contexts_num, -1);
247248
249+ return adapter;
248250 err2:
249251 cxl_remove_adapter_nr(adapter);
250252 err1:
@@ -286,6 +288,44 @@ int cxl_afu_select_best_mode(struct cxl_afu *afu) · 35 unmodified lines
286288 return 0;
287289 }
288290
291+int cxl_adapter_context_get(struct cxl *adapter)
292+{
293+ int rc;
294+
295+ rc = atomic_inc_unless_negative(&adapter->contexts_num);
296+ return rc >= 0 ? 0 : -EBUSY;
297+}
298+
299+void cxl_adapter_context_put(struct cxl *adapter)
300+{
301+ atomic_dec_if_positive(&adapter->contexts_num);
302+}
303+
304+int cxl_adapter_context_lock(struct cxl *adapter)
305+{
306+ int rc;
307+ /* no active contexts -> contexts_num == 0 */
308+ rc = atomic_cmpxchg(&adapter->contexts_num, 0, -1);
309+ return rc ? -EBUSY : 0;
310+}
311+
312+void cxl_adapter_context_unlock(struct cxl *adapter)
313+{
314+ int val = atomic_cmpxchg(&adapter->contexts_num, -1, 0);
315+
316+ /*
317+ * contexts lock taken -> contexts_num == -1
318+ * If not true then show a warning and force reset the lock.
319+ * This will happen when context_unlock was requested without
320+ * doing a context_lock.
321+ */
322+ if (val != -1) {
323+ atomic_set(&adapter->contexts_num, 0);
324+ WARN(1, "Adapter context unlocked with %d active contexts",
325+ val);
326+ }
327+}
328+
289329 static int __init init_cxl(void)
290330 {
291331 int rc = 0;
drivers/misc/cxl/pci.c+2−0
@@ -1487,6 +1487,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) · 1486 unmodified lines
14871487 if ((rc = cxl_native_register_psl_err_irq(adapter)))
14881488 goto err;
14891489
1490+ /* Release the context lock as adapter is configured */
1491+ cxl_adapter_context_unlock(adapter);
14901492 return 0;
14911493
14921494 err:
drivers/misc/cxl/sysfs.c+23−4
@@ -75,12 +75,31 @@ static ssize_t reset_adapter_store(struct device *device, · 74 unmodified lines
7575 int val;
7676
7777 rc = sscanf(buf, "%i", &val);
78− if ((rc != 1) || (val != 1))
78+ if ((rc != 1) || (val != 1 && val != -1))
7979 return -EINVAL;
8080
81− if ((rc = cxl_ops->adapter_reset(adapter)))
82− return rc;
83− return count;
81+ /*
82+ * See if we can lock the context mapping that's only allowed
83+ * when there are no contexts attached to the adapter. Once
84+ * taken this will also prevent any context from getting activated.
85+ */
86+ if (val == 1) {
87+ rc = cxl_adapter_context_lock(adapter);
88+ if (rc)
89+ goto out;
90+
91+ rc = cxl_ops->adapter_reset(adapter);
92+ /* In case reset failed release context lock */
93+ if (rc)
94+ cxl_adapter_context_unlock(adapter);
95+
96+ } else if (val == -1) {
97+ /* Perform a forced adapter reset */
98+ rc = cxl_ops->adapter_reset(adapter);
99+ }
100+
101+out:
102+ return rc ? rc : count;
84103 }
85104
86105 static ssize_t load_image_on_perst_show(struct device *device,