forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 958e46acc8e900e8569dd467c1af9b8d2d019394
kernel/arch/powerpc/sysdev/xive/spapr.c
....@@ -1,10 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright 2016,2017 IBM Corporation.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation; either version
7
- * 2 of the License, or (at your option) any later version.
84 */
95
106 #define pr_fmt(fmt) "xive: " fmt
....@@ -20,7 +16,9 @@
2016 #include <linux/cpumask.h>
2117 #include <linux/mm.h>
2218 #include <linux/delay.h>
19
+#include <linux/libfdt.h>
2320
21
+#include <asm/machdep.h>
2422 #include <asm/prom.h>
2523 #include <asm/io.h>
2624 #include <asm/smp.h>
....@@ -29,6 +27,8 @@
2927 #include <asm/xive.h>
3028 #include <asm/xive-regs.h>
3129 #include <asm/hvcall.h>
30
+#include <asm/svm.h>
31
+#include <asm/ultravisor.h>
3232
3333 #include "xive-internal.h"
3434
....@@ -48,7 +48,7 @@
4848 {
4949 struct xive_irq_bitmap *xibm;
5050
51
- xibm = kzalloc(sizeof(*xibm), GFP_ATOMIC);
51
+ xibm = kzalloc(sizeof(*xibm), GFP_KERNEL);
5252 if (!xibm)
5353 return -ENOMEM;
5454
....@@ -56,6 +56,10 @@
5656 xibm->base = base;
5757 xibm->count = count;
5858 xibm->bitmap = kzalloc(xibm->count, GFP_KERNEL);
59
+ if (!xibm->bitmap) {
60
+ kfree(xibm);
61
+ return -ENOMEM;
62
+ }
5963 list_add(&xibm->list, &xive_irq_bitmaps);
6064
6165 pr_info("Using IRQ range [%x-%x]", xibm->base,
....@@ -210,6 +214,38 @@
210214 lisn, target, prio, rc);
211215 return rc;
212216 }
217
+
218
+ return 0;
219
+}
220
+
221
+static long plpar_int_get_source_config(unsigned long flags,
222
+ unsigned long lisn,
223
+ unsigned long *target,
224
+ unsigned long *prio,
225
+ unsigned long *sw_irq)
226
+{
227
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
228
+ long rc;
229
+
230
+ pr_devel("H_INT_GET_SOURCE_CONFIG flags=%lx lisn=%lx\n", flags, lisn);
231
+
232
+ do {
233
+ rc = plpar_hcall(H_INT_GET_SOURCE_CONFIG, retbuf, flags, lisn,
234
+ target, prio, sw_irq);
235
+ } while (plpar_busy_delay(rc));
236
+
237
+ if (rc) {
238
+ pr_err("H_INT_GET_SOURCE_CONFIG lisn=%ld failed %ld\n",
239
+ lisn, rc);
240
+ return rc;
241
+ }
242
+
243
+ *target = retbuf[0];
244
+ *prio = retbuf[1];
245
+ *sw_irq = retbuf[2];
246
+
247
+ pr_devel("H_INT_GET_SOURCE_CONFIG target=%lx prio=%lx sw_irq=%lx\n",
248
+ retbuf[0], retbuf[1], retbuf[2]);
213249
214250 return 0;
215251 }
....@@ -405,6 +441,24 @@
405441 return rc == 0 ? 0 : -ENXIO;
406442 }
407443
444
+static int xive_spapr_get_irq_config(u32 hw_irq, u32 *target, u8 *prio,
445
+ u32 *sw_irq)
446
+{
447
+ long rc;
448
+ unsigned long h_target;
449
+ unsigned long h_prio;
450
+ unsigned long h_sw_irq;
451
+
452
+ rc = plpar_int_get_source_config(0, hw_irq, &h_target, &h_prio,
453
+ &h_sw_irq);
454
+
455
+ *target = h_target;
456
+ *prio = h_prio;
457
+ *sw_irq = h_sw_irq;
458
+
459
+ return rc == 0 ? 0 : -ENXIO;
460
+}
461
+
408462 /* This can be called multiple time to change a queue configuration */
409463 static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio,
410464 __be32 *qpage, u32 order)
....@@ -450,6 +504,9 @@
450504 rc = -EIO;
451505 } else {
452506 q->qpage = qpage;
507
+ if (is_secure_guest())
508
+ uv_share_page(PHYS_PFN(qpage_phys),
509
+ 1 << xive_alloc_order(order));
453510 }
454511 fail:
455512 return rc;
....@@ -483,6 +540,8 @@
483540 hw_cpu, prio);
484541
485542 alloc_order = xive_alloc_order(xive_queue_shift);
543
+ if (is_secure_guest())
544
+ uv_unshare_page(PHYS_PFN(__pa(q->qpage)), 1 << alloc_order);
486545 free_pages((unsigned long)q->qpage, alloc_order);
487546 q->qpage = NULL;
488547 }
....@@ -594,9 +653,28 @@
594653 plpar_int_sync(0, hw_irq);
595654 }
596655
656
+static int xive_spapr_debug_show(struct seq_file *m, void *private)
657
+{
658
+ struct xive_irq_bitmap *xibm;
659
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
660
+
661
+ if (!buf)
662
+ return -ENOMEM;
663
+
664
+ list_for_each_entry(xibm, &xive_irq_bitmaps, list) {
665
+ memset(buf, 0, PAGE_SIZE);
666
+ bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count);
667
+ seq_printf(m, "bitmap #%d: %s", xibm->count, buf);
668
+ }
669
+ kfree(buf);
670
+
671
+ return 0;
672
+}
673
+
597674 static const struct xive_ops xive_spapr_ops = {
598675 .populate_irq_data = xive_spapr_populate_irq_data,
599676 .configure_irq = xive_spapr_configure_irq,
677
+ .get_irq_config = xive_spapr_get_irq_config,
600678 .setup_queue = xive_spapr_setup_queue,
601679 .cleanup_queue = xive_spapr_cleanup_queue,
602680 .match = xive_spapr_match,
....@@ -610,6 +688,7 @@
610688 #ifdef CONFIG_SMP
611689 .get_ipi = xive_spapr_get_ipi,
612690 .put_ipi = xive_spapr_put_ipi,
691
+ .debug_show = xive_spapr_debug_show,
613692 #endif /* CONFIG_SMP */
614693 .name = "spapr",
615694 };
....@@ -631,6 +710,7 @@
631710 }
632711
633712 reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
713
+ of_node_put(rootdn);
634714 if (!reg) {
635715 pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n");
636716 return false;
....@@ -671,6 +751,55 @@
671751 return true;
672752 }
673753
754
+static const u8 *get_vec5_feature(unsigned int index)
755
+{
756
+ unsigned long root, chosen;
757
+ int size;
758
+ const u8 *vec5;
759
+
760
+ root = of_get_flat_dt_root();
761
+ chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
762
+ if (chosen == -FDT_ERR_NOTFOUND)
763
+ return NULL;
764
+
765
+ vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
766
+ if (!vec5)
767
+ return NULL;
768
+
769
+ if (size <= index)
770
+ return NULL;
771
+
772
+ return vec5 + index;
773
+}
774
+
775
+static bool __init xive_spapr_disabled(void)
776
+{
777
+ const u8 *vec5_xive;
778
+
779
+ vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT));
780
+ if (vec5_xive) {
781
+ u8 val;
782
+
783
+ val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT);
784
+ switch (val) {
785
+ case OV5_FEAT(OV5_XIVE_EITHER):
786
+ case OV5_FEAT(OV5_XIVE_LEGACY):
787
+ break;
788
+ case OV5_FEAT(OV5_XIVE_EXPLOIT):
789
+ /* Hypervisor only supports XIVE */
790
+ if (xive_cmdline_disabled)
791
+ pr_warn("WARNING: Ignoring cmdline option xive=off\n");
792
+ return false;
793
+ default:
794
+ pr_warn("%s: Unknown xive support option: 0x%x\n",
795
+ __func__, val);
796
+ break;
797
+ }
798
+ }
799
+
800
+ return xive_cmdline_disabled;
801
+}
802
+
674803 bool __init xive_spapr_init(void)
675804 {
676805 struct device_node *np;
....@@ -683,7 +812,7 @@
683812 const __be32 *reg;
684813 int i;
685814
686
- if (xive_cmdline_disabled)
815
+ if (xive_spapr_disabled())
687816 return false;
688817
689818 pr_devel("%s()\n", __func__);
....@@ -738,3 +867,5 @@
738867 pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
739868 return true;
740869 }
870
+
871
+machine_arch_initcall(pseries, xive_core_debug_init);