forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
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 }
....@@ -389,6 +425,7 @@
389425
390426 data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift);
391427 if (!data->trig_mmio) {
428
+ iounmap(data->eoi_mmio);
392429 pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq);
393430 return -ENOMEM;
394431 }
....@@ -401,6 +438,24 @@
401438
402439 rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target,
403440 prio, sw_irq);
441
+
442
+ return rc == 0 ? 0 : -ENXIO;
443
+}
444
+
445
+static int xive_spapr_get_irq_config(u32 hw_irq, u32 *target, u8 *prio,
446
+ u32 *sw_irq)
447
+{
448
+ long rc;
449
+ unsigned long h_target;
450
+ unsigned long h_prio;
451
+ unsigned long h_sw_irq;
452
+
453
+ rc = plpar_int_get_source_config(0, hw_irq, &h_target, &h_prio,
454
+ &h_sw_irq);
455
+
456
+ *target = h_target;
457
+ *prio = h_prio;
458
+ *sw_irq = h_sw_irq;
404459
405460 return rc == 0 ? 0 : -ENXIO;
406461 }
....@@ -450,6 +505,9 @@
450505 rc = -EIO;
451506 } else {
452507 q->qpage = qpage;
508
+ if (is_secure_guest())
509
+ uv_share_page(PHYS_PFN(qpage_phys),
510
+ 1 << xive_alloc_order(order));
453511 }
454512 fail:
455513 return rc;
....@@ -483,6 +541,8 @@
483541 hw_cpu, prio);
484542
485543 alloc_order = xive_alloc_order(xive_queue_shift);
544
+ if (is_secure_guest())
545
+ uv_unshare_page(PHYS_PFN(__pa(q->qpage)), 1 << alloc_order);
486546 free_pages((unsigned long)q->qpage, alloc_order);
487547 q->qpage = NULL;
488548 }
....@@ -594,9 +654,28 @@
594654 plpar_int_sync(0, hw_irq);
595655 }
596656
657
+static int xive_spapr_debug_show(struct seq_file *m, void *private)
658
+{
659
+ struct xive_irq_bitmap *xibm;
660
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
661
+
662
+ if (!buf)
663
+ return -ENOMEM;
664
+
665
+ list_for_each_entry(xibm, &xive_irq_bitmaps, list) {
666
+ memset(buf, 0, PAGE_SIZE);
667
+ bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count);
668
+ seq_printf(m, "bitmap #%d: %s", xibm->count, buf);
669
+ }
670
+ kfree(buf);
671
+
672
+ return 0;
673
+}
674
+
597675 static const struct xive_ops xive_spapr_ops = {
598676 .populate_irq_data = xive_spapr_populate_irq_data,
599677 .configure_irq = xive_spapr_configure_irq,
678
+ .get_irq_config = xive_spapr_get_irq_config,
600679 .setup_queue = xive_spapr_setup_queue,
601680 .cleanup_queue = xive_spapr_cleanup_queue,
602681 .match = xive_spapr_match,
....@@ -610,6 +689,7 @@
610689 #ifdef CONFIG_SMP
611690 .get_ipi = xive_spapr_get_ipi,
612691 .put_ipi = xive_spapr_put_ipi,
692
+ .debug_show = xive_spapr_debug_show,
613693 #endif /* CONFIG_SMP */
614694 .name = "spapr",
615695 };
....@@ -631,6 +711,7 @@
631711 }
632712
633713 reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
714
+ of_node_put(rootdn);
634715 if (!reg) {
635716 pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n");
636717 return false;
....@@ -671,6 +752,55 @@
671752 return true;
672753 }
673754
755
+static const u8 *get_vec5_feature(unsigned int index)
756
+{
757
+ unsigned long root, chosen;
758
+ int size;
759
+ const u8 *vec5;
760
+
761
+ root = of_get_flat_dt_root();
762
+ chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
763
+ if (chosen == -FDT_ERR_NOTFOUND)
764
+ return NULL;
765
+
766
+ vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size);
767
+ if (!vec5)
768
+ return NULL;
769
+
770
+ if (size <= index)
771
+ return NULL;
772
+
773
+ return vec5 + index;
774
+}
775
+
776
+static bool __init xive_spapr_disabled(void)
777
+{
778
+ const u8 *vec5_xive;
779
+
780
+ vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT));
781
+ if (vec5_xive) {
782
+ u8 val;
783
+
784
+ val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT);
785
+ switch (val) {
786
+ case OV5_FEAT(OV5_XIVE_EITHER):
787
+ case OV5_FEAT(OV5_XIVE_LEGACY):
788
+ break;
789
+ case OV5_FEAT(OV5_XIVE_EXPLOIT):
790
+ /* Hypervisor only supports XIVE */
791
+ if (xive_cmdline_disabled)
792
+ pr_warn("WARNING: Ignoring cmdline option xive=off\n");
793
+ return false;
794
+ default:
795
+ pr_warn("%s: Unknown xive support option: 0x%x\n",
796
+ __func__, val);
797
+ break;
798
+ }
799
+ }
800
+
801
+ return xive_cmdline_disabled;
802
+}
803
+
674804 bool __init xive_spapr_init(void)
675805 {
676806 struct device_node *np;
....@@ -683,7 +813,7 @@
683813 const __be32 *reg;
684814 int i;
685815
686
- if (xive_cmdline_disabled)
816
+ if (xive_spapr_disabled())
687817 return false;
688818
689819 pr_devel("%s()\n", __func__);
....@@ -738,3 +868,5 @@
738868 pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10));
739869 return true;
740870 }
871
+
872
+machine_arch_initcall(pseries, xive_core_debug_init);