diff options
author | Zhang Xiantao <xiantao.zhang@intel.com> | 2007-12-02 09:35:57 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:17 -0500 |
commit | 8be5453f95933340a42c6e7fc7b66f3bb786fddd (patch) | |
tree | 7c17e5413f4085d1dd344c72ffad88b728ffadcd | |
parent | 2b5203ee6828e9cabab1e1fb42e53d72ab9351a6 (diff) |
KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface
This patch replaces lapic structure with kvm_vcpu in ioapic.c, making ioapic
independent of the local apic, as required by ia64.
Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/ioapic.c | 18 | ||||
-rw-r--r-- | drivers/kvm/irq.h | 5 | ||||
-rw-r--r-- | drivers/kvm/lapic.c | 23 |
3 files changed, 29 insertions, 17 deletions
diff --git a/drivers/kvm/ioapic.c b/drivers/kvm/ioapic.c index cf1d50b3549b..3629867a76bc 100644 --- a/drivers/kvm/ioapic.c +++ b/drivers/kvm/ioapic.c | |||
@@ -136,7 +136,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | 138 | static void ioapic_inj_irq(struct kvm_ioapic *ioapic, |
139 | struct kvm_lapic *target, | 139 | struct kvm_vcpu *vcpu, |
140 | u8 vector, u8 trig_mode, u8 delivery_mode) | 140 | u8 vector, u8 trig_mode, u8 delivery_mode) |
141 | { | 141 | { |
142 | ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode, | 142 | ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode, |
@@ -145,7 +145,7 @@ static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | |||
145 | ASSERT((delivery_mode == dest_Fixed) || | 145 | ASSERT((delivery_mode == dest_Fixed) || |
146 | (delivery_mode == dest_LowestPrio)); | 146 | (delivery_mode == dest_LowestPrio)); |
147 | 147 | ||
148 | kvm_apic_set_irq(target, vector, trig_mode); | 148 | kvm_apic_set_irq(vcpu, vector, trig_mode); |
149 | } | 149 | } |
150 | 150 | ||
151 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | 151 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, |
@@ -196,7 +196,6 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
196 | u8 vector = ioapic->redirtbl[irq].fields.vector; | 196 | u8 vector = ioapic->redirtbl[irq].fields.vector; |
197 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; | 197 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; |
198 | u32 deliver_bitmask; | 198 | u32 deliver_bitmask; |
199 | struct kvm_lapic *target; | ||
200 | struct kvm_vcpu *vcpu; | 199 | struct kvm_vcpu *vcpu; |
201 | int vcpu_id; | 200 | int vcpu_id; |
202 | 201 | ||
@@ -212,13 +211,13 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
212 | 211 | ||
213 | switch (delivery_mode) { | 212 | switch (delivery_mode) { |
214 | case dest_LowestPrio: | 213 | case dest_LowestPrio: |
215 | target = | 214 | vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector, |
216 | kvm_apic_round_robin(ioapic->kvm, vector, deliver_bitmask); | 215 | deliver_bitmask); |
217 | if (target != NULL) | 216 | if (vcpu != NULL) |
218 | ioapic_inj_irq(ioapic, target, vector, | 217 | ioapic_inj_irq(ioapic, vcpu, vector, |
219 | trig_mode, delivery_mode); | 218 | trig_mode, delivery_mode); |
220 | else | 219 | else |
221 | ioapic_debug("null round robin: " | 220 | ioapic_debug("null lowest prio vcpu: " |
222 | "mask=%x vector=%x delivery_mode=%x\n", | 221 | "mask=%x vector=%x delivery_mode=%x\n", |
223 | deliver_bitmask, vector, dest_LowestPrio); | 222 | deliver_bitmask, vector, dest_LowestPrio); |
224 | break; | 223 | break; |
@@ -229,8 +228,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
229 | deliver_bitmask &= ~(1 << vcpu_id); | 228 | deliver_bitmask &= ~(1 << vcpu_id); |
230 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 229 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
231 | if (vcpu) { | 230 | if (vcpu) { |
232 | target = vcpu->apic; | 231 | ioapic_inj_irq(ioapic, vcpu, vector, |
233 | ioapic_inj_irq(ioapic, target, vector, | ||
234 | trig_mode, delivery_mode); | 232 | trig_mode, delivery_mode); |
235 | } | 233 | } |
236 | } | 234 | } |
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h index 5ad3cfd7622d..78a34dde1cb9 100644 --- a/drivers/kvm/irq.h +++ b/drivers/kvm/irq.h | |||
@@ -145,14 +145,15 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu); | |||
145 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); | 145 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); |
146 | void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); | 146 | void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); |
147 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); | 147 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); |
148 | struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, | 148 | |
149 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | ||
149 | unsigned long bitmap); | 150 | unsigned long bitmap); |
150 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); | 151 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); |
151 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); | 152 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); |
152 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | 153 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); |
153 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector); | 154 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector); |
154 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | 155 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); |
155 | int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig); | 156 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig); |
156 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); | 157 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); |
157 | int kvm_ioapic_init(struct kvm *kvm); | 158 | int kvm_ioapic_init(struct kvm *kvm); |
158 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); | 159 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); |
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c index 64f74bd7093a..5efa6c0276c6 100644 --- a/drivers/kvm/lapic.c +++ b/drivers/kvm/lapic.c | |||
@@ -185,8 +185,10 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) | |||
185 | } | 185 | } |
186 | EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr); | 186 | EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr); |
187 | 187 | ||
188 | int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig) | 188 | int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) |
189 | { | 189 | { |
190 | struct kvm_lapic *apic = vcpu->apic; | ||
191 | |||
190 | if (!apic_test_and_set_irr(vec, apic)) { | 192 | if (!apic_test_and_set_irr(vec, apic)) { |
191 | /* a new pending irq is set in IRR */ | 193 | /* a new pending irq is set in IRR */ |
192 | if (trig) | 194 | if (trig) |
@@ -394,7 +396,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
394 | return result; | 396 | return result; |
395 | } | 397 | } |
396 | 398 | ||
397 | struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, | 399 | static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, |
398 | unsigned long bitmap) | 400 | unsigned long bitmap) |
399 | { | 401 | { |
400 | int last; | 402 | int last; |
@@ -422,6 +424,17 @@ struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, | |||
422 | return apic; | 424 | return apic; |
423 | } | 425 | } |
424 | 426 | ||
427 | struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | ||
428 | unsigned long bitmap) | ||
429 | { | ||
430 | struct kvm_lapic *apic; | ||
431 | |||
432 | apic = kvm_apic_round_robin(kvm, vector, bitmap); | ||
433 | if (apic) | ||
434 | return apic->vcpu; | ||
435 | return NULL; | ||
436 | } | ||
437 | |||
425 | static void apic_set_eoi(struct kvm_lapic *apic) | 438 | static void apic_set_eoi(struct kvm_lapic *apic) |
426 | { | 439 | { |
427 | int vector = apic_find_highest_isr(apic); | 440 | int vector = apic_find_highest_isr(apic); |
@@ -453,7 +466,7 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
453 | unsigned int delivery_mode = icr_low & APIC_MODE_MASK; | 466 | unsigned int delivery_mode = icr_low & APIC_MODE_MASK; |
454 | unsigned int vector = icr_low & APIC_VECTOR_MASK; | 467 | unsigned int vector = icr_low & APIC_VECTOR_MASK; |
455 | 468 | ||
456 | struct kvm_lapic *target; | 469 | struct kvm_vcpu *target; |
457 | struct kvm_vcpu *vcpu; | 470 | struct kvm_vcpu *vcpu; |
458 | unsigned long lpr_map = 0; | 471 | unsigned long lpr_map = 0; |
459 | int i; | 472 | int i; |
@@ -480,9 +493,9 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
480 | } | 493 | } |
481 | 494 | ||
482 | if (delivery_mode == APIC_DM_LOWEST) { | 495 | if (delivery_mode == APIC_DM_LOWEST) { |
483 | target = kvm_apic_round_robin(vcpu->kvm, vector, lpr_map); | 496 | target = kvm_get_lowest_prio_vcpu(vcpu->kvm, vector, lpr_map); |
484 | if (target != NULL) | 497 | if (target != NULL) |
485 | __apic_accept_irq(target, delivery_mode, | 498 | __apic_accept_irq(target->apic, delivery_mode, |
486 | vector, level, trig_mode); | 499 | vector, level, trig_mode); |
487 | } | 500 | } |
488 | } | 501 | } |