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:
parent
063cb7cbc9
commit
229e16fd24
@ -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) {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user