ppc/xics: preserve P and Q bits for KVM IRQs

Kernel commit 17d48610ae0f ("KVM: PPC: Book 3S: XICS: Implement ICS
P/Q states") added new bits to the state used by KVM IRQs. Currently,
QEMU does not preserve these bits, so migrating (or otherwise saving
and restoring) the guest state causes the P and Q bits to be cleared.

Clearing the P bit has no effect, because the kernel will set it based
on other data, but the loss of a set Q bit will cause a lost
interrupt.

This patch preserves the P and Q bits, correcting the problem.

Signed-off-by: Sam Bobroff <sam.bobroff@au1.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Sam Bobroff 2017-04-27 16:32:03 +10:00 committed by David Gibson
parent 063cb7cbc9
commit 229e16fd24
2 changed files with 14 additions and 0 deletions

View File

@ -229,6 +229,12 @@ static void ics_get_kvm_state(ICSState *ics)
| XICS_STATUS_REJECTED; | XICS_STATUS_REJECTED;
} }
} }
if (state & KVM_XICS_PRESENTED) {
irq->status |= XICS_STATUS_PRESENTED;
}
if (state & KVM_XICS_QUEUED) {
irq->status |= XICS_STATUS_QUEUED;
}
} }
} }
@ -266,6 +272,12 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
state |= KVM_XICS_PENDING; state |= KVM_XICS_PENDING;
} }
} }
if (irq->status & XICS_STATUS_PRESENTED) {
state |= KVM_XICS_PRESENTED;
}
if (irq->status & XICS_STATUS_QUEUED) {
state |= KVM_XICS_QUEUED;
}
ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr); ret = ioctl(kernel_xics_fd, KVM_SET_DEVICE_ATTR, &attr);
if (ret != 0) { if (ret != 0) {

View File

@ -144,6 +144,8 @@ struct ICSIRQState {
#define XICS_STATUS_SENT 0x2 #define XICS_STATUS_SENT 0x2
#define XICS_STATUS_REJECTED 0x4 #define XICS_STATUS_REJECTED 0x4
#define XICS_STATUS_MASKED_PENDING 0x8 #define XICS_STATUS_MASKED_PENDING 0x8
#define XICS_STATUS_PRESENTED 0x10
#define XICS_STATUS_QUEUED 0x20
uint8_t status; uint8_t status;
/* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */ /* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */
#define XICS_FLAGS_IRQ_LSI 0x1 #define XICS_FLAGS_IRQ_LSI 0x1