aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-05-22 11:25:14 -0400
committerAlexander Graf <agraf@suse.de>2014-05-30 08:26:26 -0400
commitaae6559651dd9d779da79f30de02033557fe263b (patch)
treee20739fdfd363f9322c89f4730ae5b22034f4ead /arch/powerpc/kvm
parent42188365f92c2d6bc89c9441a5e9305c1354e8a6 (diff)
KVM: PPC: MPIC: Reset IRQ source private members
When we reset the in-kernel MPIC controller, we forget to reset some hidden state such as destmask and output. This state is usually set when the guest writes to the IDR register for a specific IRQ line. To make sure we stay in sync and don't forget hidden state, treat reset of the IDR register as a simple write of the IDR register. That automatically updates all the hidden state as well. Reported-by: Paul Janzen <pcj@pauljanzen.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/mpic.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index efbd9962a209..b68d0dc9479a 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -126,6 +126,8 @@ static int openpic_cpu_write_internal(void *opaque, gpa_t addr,
126 u32 val, int idx); 126 u32 val, int idx);
127static int openpic_cpu_read_internal(void *opaque, gpa_t addr, 127static int openpic_cpu_read_internal(void *opaque, gpa_t addr,
128 u32 *ptr, int idx); 128 u32 *ptr, int idx);
129static inline void write_IRQreg_idr(struct openpic *opp, int n_IRQ,
130 uint32_t val);
129 131
130enum irq_type { 132enum irq_type {
131 IRQ_TYPE_NORMAL = 0, 133 IRQ_TYPE_NORMAL = 0,
@@ -528,7 +530,6 @@ static void openpic_reset(struct openpic *opp)
528 /* Initialise IRQ sources */ 530 /* Initialise IRQ sources */
529 for (i = 0; i < opp->max_irq; i++) { 531 for (i = 0; i < opp->max_irq; i++) {
530 opp->src[i].ivpr = opp->ivpr_reset; 532 opp->src[i].ivpr = opp->ivpr_reset;
531 opp->src[i].idr = opp->idr_reset;
532 533
533 switch (opp->src[i].type) { 534 switch (opp->src[i].type) {
534 case IRQ_TYPE_NORMAL: 535 case IRQ_TYPE_NORMAL:
@@ -543,6 +544,8 @@ static void openpic_reset(struct openpic *opp)
543 case IRQ_TYPE_FSLSPECIAL: 544 case IRQ_TYPE_FSLSPECIAL:
544 break; 545 break;
545 } 546 }
547
548 write_IRQreg_idr(opp, i, opp->idr_reset);
546 } 549 }
547 /* Initialise IRQ destinations */ 550 /* Initialise IRQ destinations */
548 for (i = 0; i < MAX_CPU; i++) { 551 for (i = 0; i < MAX_CPU; i++) {