14
14
#include <linux/irqdomain.h>
15
15
#include <linux/irqchip/chained_irq.h>
16
16
#include <linux/kernel.h>
17
+ #include <linux/kvm_para.h>
17
18
#include <linux/syscore_ops.h>
18
19
#include <asm/numa.h>
19
20
26
27
#define EIOINTC_REG_ISR 0x1800
27
28
#define EIOINTC_REG_ROUTE 0x1c00
28
29
30
+ #define EXTIOI_VIRT_FEATURES 0x40000000
31
+ #define EXTIOI_HAS_VIRT_EXTENSION BIT(0)
32
+ #define EXTIOI_HAS_ENABLE_OPTION BIT(1)
33
+ #define EXTIOI_HAS_INT_ENCODE BIT(2)
34
+ #define EXTIOI_HAS_CPU_ENCODE BIT(3)
35
+ #define EXTIOI_VIRT_CONFIG 0x40000004
36
+ #define EXTIOI_ENABLE BIT(1)
37
+ #define EXTIOI_ENABLE_INT_ENCODE BIT(2)
38
+ #define EXTIOI_ENABLE_CPU_ENCODE BIT(3)
39
+
29
40
#define VEC_REG_COUNT 4
30
41
#define VEC_COUNT_PER_REG 64
31
42
#define VEC_COUNT (VEC_REG_COUNT * VEC_COUNT_PER_REG)
32
43
#define VEC_REG_IDX (irq_id ) ((irq_id) / VEC_COUNT_PER_REG)
33
44
#define VEC_REG_BIT (irq_id ) ((irq_id) % VEC_COUNT_PER_REG)
34
45
#define EIOINTC_ALL_ENABLE 0xffffffff
46
+ #define EIOINTC_ALL_ENABLE_VEC_MASK (vector ) (EIOINTC_ALL_ENABLE & ~BIT(vector & 0x1f))
47
+ #define EIOINTC_REG_ENABLE_VEC (vector ) (EIOINTC_REG_ENABLE + ((vector >> 5) << 2))
48
+ #define EIOINTC_USE_CPU_ENCODE BIT(0)
35
49
36
50
#define MAX_EIO_NODES (NR_CPUS / CORES_PER_EIO_NODE)
37
51
52
+ /*
53
+ * Routing registers are 32bit, and there is 8-bit route setting for every
54
+ * interrupt vector. So one Route register contains four vectors routing
55
+ * information.
56
+ */
57
+ #define EIOINTC_REG_ROUTE_VEC (vector ) (EIOINTC_REG_ROUTE + (vector & ~0x03))
58
+ #define EIOINTC_REG_ROUTE_VEC_SHIFT (vector ) ((vector & 0x03) << 3)
59
+ #define EIOINTC_REG_ROUTE_VEC_MASK (vector ) (0xff << EIOINTC_REG_ROUTE_VEC_SHIFT(vector))
60
+
38
61
static int nr_pics ;
39
62
40
63
struct eiointc_priv {
@@ -44,6 +67,7 @@ struct eiointc_priv {
44
67
cpumask_t cpuspan_map ;
45
68
struct fwnode_handle * domain_handle ;
46
69
struct irq_domain * eiointc_domain ;
70
+ int flags ;
47
71
};
48
72
49
73
static struct eiointc_priv * eiointc_priv [MAX_IO_PICS ];
@@ -59,7 +83,10 @@ static void eiointc_enable(void)
59
83
60
84
static int cpu_to_eio_node (int cpu )
61
85
{
62
- return cpu_logical_map (cpu ) / CORES_PER_EIO_NODE ;
86
+ if (!kvm_para_has_feature (KVM_FEATURE_VIRT_EXTIOI ))
87
+ return cpu_logical_map (cpu ) / CORES_PER_EIO_NODE ;
88
+ else
89
+ return cpu_logical_map (cpu ) / CORES_PER_VEIO_NODE ;
63
90
}
64
91
65
92
#ifdef CONFIG_SMP
@@ -89,6 +116,17 @@ static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode,
89
116
}
90
117
}
91
118
119
+ static void veiointc_set_irq_route (unsigned int vector , unsigned int cpu )
120
+ {
121
+ unsigned long reg = EIOINTC_REG_ROUTE_VEC (vector );
122
+ unsigned int data ;
123
+
124
+ data = iocsr_read32 (reg );
125
+ data &= ~EIOINTC_REG_ROUTE_VEC_MASK (vector );
126
+ data |= cpu_logical_map (cpu ) << EIOINTC_REG_ROUTE_VEC_SHIFT (vector );
127
+ iocsr_write32 (data , reg );
128
+ }
129
+
92
130
static DEFINE_RAW_SPINLOCK (affinity_lock );
93
131
94
132
static int eiointc_set_irq_affinity (struct irq_data * d , const struct cpumask * affinity , bool force )
@@ -107,18 +145,24 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
107
145
}
108
146
109
147
vector = d -> hwirq ;
110
- regaddr = EIOINTC_REG_ENABLE + ((vector >> 5 ) << 2 );
111
-
112
- /* Mask target vector */
113
- csr_any_send (regaddr , EIOINTC_ALL_ENABLE & (~BIT (vector & 0x1F )),
114
- 0x0 , priv -> node * CORES_PER_EIO_NODE );
115
-
116
- /* Set route for target vector */
117
- eiointc_set_irq_route (vector , cpu , priv -> node , & priv -> node_map );
118
-
119
- /* Unmask target vector */
120
- csr_any_send (regaddr , EIOINTC_ALL_ENABLE ,
121
- 0x0 , priv -> node * CORES_PER_EIO_NODE );
148
+ regaddr = EIOINTC_REG_ENABLE_VEC (vector );
149
+
150
+ if (priv -> flags & EIOINTC_USE_CPU_ENCODE ) {
151
+ iocsr_write32 (EIOINTC_ALL_ENABLE_VEC_MASK (vector ), regaddr );
152
+ veiointc_set_irq_route (vector , cpu );
153
+ iocsr_write32 (EIOINTC_ALL_ENABLE , regaddr );
154
+ } else {
155
+ /* Mask target vector */
156
+ csr_any_send (regaddr , EIOINTC_ALL_ENABLE_VEC_MASK (vector ),
157
+ 0x0 , priv -> node * CORES_PER_EIO_NODE );
158
+
159
+ /* Set route for target vector */
160
+ eiointc_set_irq_route (vector , cpu , priv -> node , & priv -> node_map );
161
+
162
+ /* Unmask target vector */
163
+ csr_any_send (regaddr , EIOINTC_ALL_ENABLE ,
164
+ 0x0 , priv -> node * CORES_PER_EIO_NODE );
165
+ }
122
166
123
167
irq_data_update_effective_affinity (d , cpumask_of (cpu ));
124
168
@@ -142,17 +186,23 @@ static int eiointc_index(int node)
142
186
143
187
static int eiointc_router_init (unsigned int cpu )
144
188
{
145
- int i , bit ;
146
- uint32_t data ;
147
- uint32_t node = cpu_to_eio_node (cpu );
148
- int index = eiointc_index (node );
189
+ int i , bit , cores , index , node ;
190
+ unsigned int data ;
191
+
192
+ node = cpu_to_eio_node (cpu );
193
+ index = eiointc_index (node );
149
194
150
195
if (index < 0 ) {
151
196
pr_err ("Error: invalid nodemap!\n" );
152
- return -1 ;
197
+ return - EINVAL ;
153
198
}
154
199
155
- if ((cpu_logical_map (cpu ) % CORES_PER_EIO_NODE ) == 0 ) {
200
+ if (!(eiointc_priv [index ]-> flags & EIOINTC_USE_CPU_ENCODE ))
201
+ cores = CORES_PER_EIO_NODE ;
202
+ else
203
+ cores = CORES_PER_VEIO_NODE ;
204
+
205
+ if ((cpu_logical_map (cpu ) % cores ) == 0 ) {
156
206
eiointc_enable ();
157
207
158
208
for (i = 0 ; i < eiointc_priv [0 ]-> vec_count / 32 ; i ++ ) {
@@ -168,7 +218,9 @@ static int eiointc_router_init(unsigned int cpu)
168
218
169
219
for (i = 0 ; i < eiointc_priv [0 ]-> vec_count / 4 ; i ++ ) {
170
220
/* Route to Node-0 Core-0 */
171
- if (index == 0 )
221
+ if (eiointc_priv [index ]-> flags & EIOINTC_USE_CPU_ENCODE )
222
+ bit = cpu_logical_map (0 );
223
+ else if (index == 0 )
172
224
bit = BIT (cpu_logical_map (0 ));
173
225
else
174
226
bit = (eiointc_priv [index ]-> node << 4 ) | 1 ;
@@ -375,7 +427,7 @@ static int __init acpi_cascade_irqdomain_init(void)
375
427
static int __init eiointc_init (struct eiointc_priv * priv , int parent_irq ,
376
428
u64 node_map )
377
429
{
378
- int i ;
430
+ int i , val ;
379
431
380
432
node_map = node_map ? node_map : -1ULL ;
381
433
for_each_possible_cpu (i ) {
@@ -395,6 +447,20 @@ static int __init eiointc_init(struct eiointc_priv *priv, int parent_irq,
395
447
return - ENOMEM ;
396
448
}
397
449
450
+ if (kvm_para_has_feature (KVM_FEATURE_VIRT_EXTIOI )) {
451
+ val = iocsr_read32 (EXTIOI_VIRT_FEATURES );
452
+ /*
453
+ * With EXTIOI_ENABLE_CPU_ENCODE set
454
+ * interrupts can route to 256 vCPUs.
455
+ */
456
+ if (val & EXTIOI_HAS_CPU_ENCODE ) {
457
+ val = iocsr_read32 (EXTIOI_VIRT_CONFIG );
458
+ val |= EXTIOI_ENABLE_CPU_ENCODE ;
459
+ iocsr_write32 (val , EXTIOI_VIRT_CONFIG );
460
+ priv -> flags = EIOINTC_USE_CPU_ENCODE ;
461
+ }
462
+ }
463
+
398
464
eiointc_priv [nr_pics ++ ] = priv ;
399
465
eiointc_router_init (0 );
400
466
irq_set_chained_handler_and_data (parent_irq , eiointc_irq_dispatch , priv );
0 commit comments