Skip to content

Commit 13ce329

Browse files
legoaterpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Add controls for the EQ configuration
These controls will be used by the H_INT_SET_QUEUE_CONFIG and H_INT_GET_QUEUE_CONFIG hcalls from QEMU to configure the underlying Event Queue in the XIVE IC. They will also be used to restore the configuration of the XIVE EQs and to capture the internal run-time state of the EQs. Both 'get' and 'set' rely on an OPAL call to access the EQ toggle bit and EQ index which are updated by the XIVE IC when event notifications are enqueued in the EQ. The value of the guest physical address of the event queue is saved in the XIVE internal xive_q structure for later use. That is when migration needs to mark the EQ pages dirty to capture a consistent memory state of the VM. To be noted that H_INT_SET_QUEUE_CONFIG does not require the extra OPAL call setting the EQ toggle bit and EQ index to configure the EQ, but restoring the EQ state will. Signed-off-by: Cédric Le Goater <[email protected]> Reviewed-by: David Gibson <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent e8676ce commit 13ce329

File tree

6 files changed

+315
-6
lines changed

6 files changed

+315
-6
lines changed

Documentation/virtual/kvm/devices/xive.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,37 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
5353
-ENXIO: CPU event queues not configured or configuration of the
5454
underlying HW interrupt failed
5555
-EBUSY: No CPU available to serve interrupt
56+
57+
4. KVM_DEV_XIVE_GRP_EQ_CONFIG (read-write)
58+
Configures an event queue of a CPU
59+
Attributes:
60+
EQ descriptor identifier (64-bit)
61+
The EQ descriptor identifier is a tuple (server, priority) :
62+
bits: | 63 .... 32 | 31 .. 3 | 2 .. 0
63+
values: | unused | server | priority
64+
The kvm_device_attr.addr points to :
65+
struct kvm_ppc_xive_eq {
66+
__u32 flags;
67+
__u32 qshift;
68+
__u64 qaddr;
69+
__u32 qtoggle;
70+
__u32 qindex;
71+
__u8 pad[40];
72+
};
73+
- flags: queue flags
74+
KVM_XIVE_EQ_ALWAYS_NOTIFY (required)
75+
forces notification without using the coalescing mechanism
76+
provided by the XIVE END ESBs.
77+
- qshift: queue size (power of 2)
78+
- qaddr: real address of queue
79+
- qtoggle: current queue toggle bit
80+
- qindex: current queue index
81+
- pad: reserved for future use
82+
Errors:
83+
-ENOENT: Invalid CPU number
84+
-EINVAL: Invalid priority
85+
-EINVAL: Invalid flags
86+
-EINVAL: Invalid queue size
87+
-EINVAL: Invalid queue address
88+
-EFAULT: Invalid user pointer for attr->addr.
89+
-EIO: Configuration of the underlying HW failed

arch/powerpc/include/asm/xive.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ struct xive_q {
7373
u32 esc_irq;
7474
atomic_t count;
7575
atomic_t pending_count;
76+
u64 guest_qaddr;
77+
u32 guest_qshift;
7678
};
7779

7880
/* Global enable flags for the XIVE support */

arch/powerpc/include/uapi/asm/kvm.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ struct kvm_ppc_cpu_char {
681681
#define KVM_DEV_XIVE_GRP_CTRL 1
682682
#define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */
683683
#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */
684+
#define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */
684685

685686
/* Layout of 64-bit XIVE source attribute values */
686687
#define KVM_XIVE_LEVEL_SENSITIVE (1ULL << 0)
@@ -696,4 +697,22 @@ struct kvm_ppc_cpu_char {
696697
#define KVM_XIVE_SOURCE_EISN_SHIFT 33
697698
#define KVM_XIVE_SOURCE_EISN_MASK 0xfffffffe00000000ULL
698699

700+
/* Layout of 64-bit EQ identifier */
701+
#define KVM_XIVE_EQ_PRIORITY_SHIFT 0
702+
#define KVM_XIVE_EQ_PRIORITY_MASK 0x7
703+
#define KVM_XIVE_EQ_SERVER_SHIFT 3
704+
#define KVM_XIVE_EQ_SERVER_MASK 0xfffffff8ULL
705+
706+
/* Layout of EQ configuration values (64 bytes) */
707+
struct kvm_ppc_xive_eq {
708+
__u32 flags;
709+
__u32 qshift;
710+
__u64 qaddr;
711+
__u32 qtoggle;
712+
__u32 qindex;
713+
__u8 pad[40];
714+
};
715+
716+
#define KVM_XIVE_EQ_ALWAYS_NOTIFY 0x00000001
717+
699718
#endif /* __LINUX_KVM_POWERPC_H */

arch/powerpc/kvm/book3s_xive.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ static irqreturn_t xive_esc_irq(int irq, void *data)
166166
return IRQ_HANDLED;
167167
}
168168

169-
static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio)
169+
int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio,
170+
bool single_escalation)
170171
{
171172
struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
172173
struct xive_q *q = &xc->queues[prio];
@@ -185,7 +186,7 @@ static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio)
185186
return -EIO;
186187
}
187188

188-
if (xc->xive->single_escalation)
189+
if (single_escalation)
189190
name = kasprintf(GFP_KERNEL, "kvm-%d-%d",
190191
vcpu->kvm->arch.lpid, xc->server_num);
191192
else
@@ -217,7 +218,7 @@ static int xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio)
217218
* interrupt, thus leaving it effectively masked after
218219
* it fires once.
219220
*/
220-
if (xc->xive->single_escalation) {
221+
if (single_escalation) {
221222
struct irq_data *d = irq_get_irq_data(xc->esc_virq[prio]);
222223
struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
223224

@@ -291,7 +292,8 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio)
291292
continue;
292293
rc = xive_provision_queue(vcpu, prio);
293294
if (rc == 0 && !xive->single_escalation)
294-
xive_attach_escalation(vcpu, prio);
295+
kvmppc_xive_attach_escalation(vcpu, prio,
296+
xive->single_escalation);
295297
if (rc)
296298
return rc;
297299
}
@@ -1214,7 +1216,8 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
12141216
if (xive->qmap & (1 << i)) {
12151217
r = xive_provision_queue(vcpu, i);
12161218
if (r == 0 && !xive->single_escalation)
1217-
xive_attach_escalation(vcpu, i);
1219+
kvmppc_xive_attach_escalation(
1220+
vcpu, i, xive->single_escalation);
12181221
if (r)
12191222
goto bail;
12201223
} else {
@@ -1229,7 +1232,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
12291232
}
12301233

12311234
/* If not done above, attach priority 0 escalation */
1232-
r = xive_attach_escalation(vcpu, 0);
1235+
r = kvmppc_xive_attach_escalation(vcpu, 0, xive->single_escalation);
12331236
if (r)
12341237
goto bail;
12351238

arch/powerpc/kvm/book3s_xive.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ struct kvmppc_xive_src_block *kvmppc_xive_create_src_block(
272272
struct kvmppc_xive *xive, int irq);
273273
void kvmppc_xive_free_sources(struct kvmppc_xive_src_block *sb);
274274
int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio);
275+
int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio,
276+
bool single_escalation);
275277

276278
#endif /* CONFIG_KVM_XICS */
277279
#endif /* _KVM_PPC_BOOK3S_XICS_H */

0 commit comments

Comments
 (0)