mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
KVM: s390: correctly handle injection of pgm irqs and per events
PER events can always co-exist with other program interrupts. For now, we always overwrite all program interrupt parameters when injecting any type of program interrupt. Let's handle that correctly by only overwriting the relevant portion of the program interrupt parameters. Therefore we can now inject PER events and ordinary program interrupts concurrently, resulting in no loss of program interrupts. This will especially by helpful when manually detecting PER events later - as both types might be triggered during one SIE exit. Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
66933b78e3
commit
238293b14d
1 changed files with 20 additions and 1 deletions
|
@ -972,7 +972,26 @@ static int __inject_prog(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
|
|||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
|
||||
irq->u.pgm.code, 0);
|
||||
|
||||
li->irq.pgm = irq->u.pgm;
|
||||
if (irq->u.pgm.code == PGM_PER) {
|
||||
li->irq.pgm.code |= PGM_PER;
|
||||
/* only modify PER related information */
|
||||
li->irq.pgm.per_address = irq->u.pgm.per_address;
|
||||
li->irq.pgm.per_code = irq->u.pgm.per_code;
|
||||
li->irq.pgm.per_atmid = irq->u.pgm.per_atmid;
|
||||
li->irq.pgm.per_access_id = irq->u.pgm.per_access_id;
|
||||
} else if (!(irq->u.pgm.code & PGM_PER)) {
|
||||
li->irq.pgm.code = (li->irq.pgm.code & PGM_PER) |
|
||||
irq->u.pgm.code;
|
||||
/* only modify non-PER information */
|
||||
li->irq.pgm.trans_exc_code = irq->u.pgm.trans_exc_code;
|
||||
li->irq.pgm.mon_code = irq->u.pgm.mon_code;
|
||||
li->irq.pgm.data_exc_code = irq->u.pgm.data_exc_code;
|
||||
li->irq.pgm.mon_class_nr = irq->u.pgm.mon_class_nr;
|
||||
li->irq.pgm.exc_access_id = irq->u.pgm.exc_access_id;
|
||||
li->irq.pgm.op_access_id = irq->u.pgm.op_access_id;
|
||||
} else {
|
||||
li->irq.pgm = irq->u.pgm;
|
||||
}
|
||||
set_bit(IRQ_PEND_PROG, &li->pending_irqs);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue