aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8259.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/i8259.c')
-rw-r--r--arch/x86/kvm/i8259.c48
1 files changed, 17 insertions, 31 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 4b7b73ce2098..19fe855e7953 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard 4 * Copyright (c) 2003-2004 Fabrice Bellard
5 * Copyright (c) 2007 Intel Corporation 5 * Copyright (c) 2007 Intel Corporation
6 * Copyright 2009 Red Hat, Inc. and/or its affilates. 6 * Copyright 2009 Red Hat, Inc. and/or its affiliates.
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal 9 * of this software and associated documentation files (the "Software"), to deal
@@ -39,7 +39,7 @@ static void pic_irq_request(struct kvm *kvm, int level);
39static void pic_lock(struct kvm_pic *s) 39static void pic_lock(struct kvm_pic *s)
40 __acquires(&s->lock) 40 __acquires(&s->lock)
41{ 41{
42 raw_spin_lock(&s->lock); 42 spin_lock(&s->lock);
43} 43}
44 44
45static void pic_unlock(struct kvm_pic *s) 45static void pic_unlock(struct kvm_pic *s)
@@ -51,7 +51,7 @@ static void pic_unlock(struct kvm_pic *s)
51 51
52 s->wakeup_needed = false; 52 s->wakeup_needed = false;
53 53
54 raw_spin_unlock(&s->lock); 54 spin_unlock(&s->lock);
55 55
56 if (wakeup) { 56 if (wakeup) {
57 kvm_for_each_vcpu(i, vcpu, s->kvm) { 57 kvm_for_each_vcpu(i, vcpu, s->kvm) {
@@ -62,11 +62,9 @@ static void pic_unlock(struct kvm_pic *s)
62 } 62 }
63 63
64 if (!found) 64 if (!found)
65 found = s->kvm->bsp_vcpu;
66
67 if (!found)
68 return; 65 return;
69 66
67 kvm_make_request(KVM_REQ_EVENT, found);
70 kvm_vcpu_kick(found); 68 kvm_vcpu_kick(found);
71 } 69 }
72} 70}
@@ -74,7 +72,6 @@ static void pic_unlock(struct kvm_pic *s)
74static void pic_clear_isr(struct kvm_kpic_state *s, int irq) 72static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
75{ 73{
76 s->isr &= ~(1 << irq); 74 s->isr &= ~(1 << irq);
77 s->isr_ack |= (1 << irq);
78 if (s != &s->pics_state->pics[0]) 75 if (s != &s->pics_state->pics[0])
79 irq += 8; 76 irq += 8;
80 /* 77 /*
@@ -88,16 +85,6 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
88 pic_lock(s->pics_state); 85 pic_lock(s->pics_state);
89} 86}
90 87
91void kvm_pic_clear_isr_ack(struct kvm *kvm)
92{
93 struct kvm_pic *s = pic_irqchip(kvm);
94
95 pic_lock(s);
96 s->pics[0].isr_ack = 0xff;
97 s->pics[1].isr_ack = 0xff;
98 pic_unlock(s);
99}
100
101/* 88/*
102 * set irq level. If an edge is detected, then the IRR is set to 1 89 * set irq level. If an edge is detected, then the IRR is set to 1
103 */ 90 */
@@ -280,7 +267,6 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
280 s->irr = 0; 267 s->irr = 0;
281 s->imr = 0; 268 s->imr = 0;
282 s->isr = 0; 269 s->isr = 0;
283 s->isr_ack = 0xff;
284 s->priority_add = 0; 270 s->priority_add = 0;
285 s->irq_base = 0; 271 s->irq_base = 0;
286 s->read_reg_select = 0; 272 s->read_reg_select = 0;
@@ -308,13 +294,17 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
308 addr &= 1; 294 addr &= 1;
309 if (addr == 0) { 295 if (addr == 0) {
310 if (val & 0x10) { 296 if (val & 0x10) {
311 kvm_pic_reset(s); /* init */
312 /*
313 * deassert a pending interrupt
314 */
315 pic_irq_request(s->pics_state->kvm, 0);
316 s->init_state = 1;
317 s->init4 = val & 1; 297 s->init4 = val & 1;
298 s->last_irr = 0;
299 s->imr = 0;
300 s->priority_add = 0;
301 s->special_mask = 0;
302 s->read_reg_select = 0;
303 if (!s->init4) {
304 s->special_fully_nested_mode = 0;
305 s->auto_eoi = 0;
306 }
307 s->init_state = 1;
318 if (val & 0x02) 308 if (val & 0x02)
319 printk(KERN_ERR "single mode not supported"); 309 printk(KERN_ERR "single mode not supported");
320 if (val & 0x08) 310 if (val & 0x08)
@@ -540,15 +530,11 @@ static int picdev_read(struct kvm_io_device *this,
540 */ 530 */
541static void pic_irq_request(struct kvm *kvm, int level) 531static void pic_irq_request(struct kvm *kvm, int level)
542{ 532{
543 struct kvm_vcpu *vcpu = kvm->bsp_vcpu;
544 struct kvm_pic *s = pic_irqchip(kvm); 533 struct kvm_pic *s = pic_irqchip(kvm);
545 int irq = pic_get_irq(&s->pics[0]);
546 534
547 s->output = level; 535 if (!s->output)
548 if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) {
549 s->pics[0].isr_ack &= ~(1 << irq);
550 s->wakeup_needed = true; 536 s->wakeup_needed = true;
551 } 537 s->output = level;
552} 538}
553 539
554static const struct kvm_io_device_ops picdev_ops = { 540static const struct kvm_io_device_ops picdev_ops = {
@@ -564,7 +550,7 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
564 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); 550 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
565 if (!s) 551 if (!s)
566 return NULL; 552 return NULL;
567 raw_spin_lock_init(&s->lock); 553 spin_lock_init(&s->lock);
568 s->kvm = kvm; 554 s->kvm = kvm;
569 s->pics[0].elcr_mask = 0xf8; 555 s->pics[0].elcr_mask = 0xf8;
570 s->pics[1].elcr_mask = 0xde; 556 s->pics[1].elcr_mask = 0xde;