aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>2016-05-04 15:09:40 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2016-05-18 12:04:25 -0400
commit1e6e2755b635e85ce0b1ce827b7c375b6a0a890c (patch)
treef892fef66ac51b3c347982fedc66f4b025db849b
parent2086d3200dc9966c96a6c319a1214a94f00223f8 (diff)
KVM: x86: Misc LAPIC changes to expose helper functions
Exporting LAPIC utility functions and macros for re-use in SVM code. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Reviewed-by: Radim Krčmář <rkrcmar@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/lapic.c127
-rw-r--r--arch/x86/kvm/lapic.h29
2 files changed, 82 insertions, 74 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 1a2da0e5a373..f6f42f634e77 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -59,9 +59,8 @@
59/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ 59/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
60#define apic_debug(fmt, arg...) 60#define apic_debug(fmt, arg...)
61 61
62#define APIC_LVT_NUM 6
63/* 14 is the version for Xeon and Pentium 8.4.8*/ 62/* 14 is the version for Xeon and Pentium 8.4.8*/
64#define APIC_VERSION (0x14UL | ((APIC_LVT_NUM - 1) << 16)) 63#define APIC_VERSION (0x14UL | ((KVM_APIC_LVT_NUM - 1) << 16))
65#define LAPIC_MMIO_LENGTH (1 << 12) 64#define LAPIC_MMIO_LENGTH (1 << 12)
66/* followed define is not in apicdef.h */ 65/* followed define is not in apicdef.h */
67#define APIC_SHORT_MASK 0xc0000 66#define APIC_SHORT_MASK 0xc0000
@@ -73,14 +72,6 @@
73#define APIC_BROADCAST 0xFF 72#define APIC_BROADCAST 0xFF
74#define X2APIC_BROADCAST 0xFFFFFFFFul 73#define X2APIC_BROADCAST 0xFFFFFFFFul
75 74
76#define VEC_POS(v) ((v) & (32 - 1))
77#define REG_POS(v) (((v) >> 5) << 4)
78
79static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
80{
81 *((u32 *) (apic->regs + reg_off)) = val;
82}
83
84static inline int apic_test_vector(int vec, void *bitmap) 75static inline int apic_test_vector(int vec, void *bitmap)
85{ 76{
86 return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); 77 return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
@@ -94,11 +85,6 @@ bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector)
94 apic_test_vector(vector, apic->regs + APIC_IRR); 85 apic_test_vector(vector, apic->regs + APIC_IRR);
95} 86}
96 87
97static inline void apic_set_vector(int vec, void *bitmap)
98{
99 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
100}
101
102static inline void apic_clear_vector(int vec, void *bitmap) 88static inline void apic_clear_vector(int vec, void *bitmap)
103{ 89{
104 clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); 90 clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
@@ -212,7 +198,7 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val)
212{ 198{
213 bool enabled = val & APIC_SPIV_APIC_ENABLED; 199 bool enabled = val & APIC_SPIV_APIC_ENABLED;
214 200
215 apic_set_reg(apic, APIC_SPIV, val); 201 kvm_lapic_set_reg(apic, APIC_SPIV, val);
216 202
217 if (enabled != apic->sw_enabled) { 203 if (enabled != apic->sw_enabled) {
218 apic->sw_enabled = enabled; 204 apic->sw_enabled = enabled;
@@ -226,13 +212,13 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val)
226 212
227static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) 213static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id)
228{ 214{
229 apic_set_reg(apic, APIC_ID, id << 24); 215 kvm_lapic_set_reg(apic, APIC_ID, id << 24);
230 recalculate_apic_map(apic->vcpu->kvm); 216 recalculate_apic_map(apic->vcpu->kvm);
231} 217}
232 218
233static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id) 219static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id)
234{ 220{
235 apic_set_reg(apic, APIC_LDR, id); 221 kvm_lapic_set_reg(apic, APIC_LDR, id);
236 recalculate_apic_map(apic->vcpu->kvm); 222 recalculate_apic_map(apic->vcpu->kvm);
237} 223}
238 224
@@ -240,8 +226,8 @@ static inline void kvm_apic_set_x2apic_id(struct kvm_lapic *apic, u8 id)
240{ 226{
241 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); 227 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
242 228
243 apic_set_reg(apic, APIC_ID, id << 24); 229 kvm_lapic_set_reg(apic, APIC_ID, id << 24);
244 apic_set_reg(apic, APIC_LDR, ldr); 230 kvm_lapic_set_reg(apic, APIC_LDR, ldr);
245 recalculate_apic_map(apic->vcpu->kvm); 231 recalculate_apic_map(apic->vcpu->kvm);
246} 232}
247 233
@@ -287,10 +273,10 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu)
287 feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); 273 feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
288 if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31)))) 274 if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))))
289 v |= APIC_LVR_DIRECTED_EOI; 275 v |= APIC_LVR_DIRECTED_EOI;
290 apic_set_reg(apic, APIC_LVR, v); 276 kvm_lapic_set_reg(apic, APIC_LVR, v);
291} 277}
292 278
293static const unsigned int apic_lvt_mask[APIC_LVT_NUM] = { 279static const unsigned int apic_lvt_mask[KVM_APIC_LVT_NUM] = {
294 LVT_MASK , /* part LVTT mask, timer mode mask added at runtime */ 280 LVT_MASK , /* part LVTT mask, timer mode mask added at runtime */
295 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ 281 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
296 LVT_MASK | APIC_MODE_MASK, /* LVTPC */ 282 LVT_MASK | APIC_MODE_MASK, /* LVTPC */
@@ -349,16 +335,6 @@ void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
349} 335}
350EXPORT_SYMBOL_GPL(kvm_apic_update_irr); 336EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
351 337
352static inline void apic_set_irr(int vec, struct kvm_lapic *apic)
353{
354 apic_set_vector(vec, apic->regs + APIC_IRR);
355 /*
356 * irr_pending must be true if any interrupt is pending; set it after
357 * APIC_IRR to avoid race with apic_clear_irr
358 */
359 apic->irr_pending = true;
360}
361
362static inline int apic_search_irr(struct kvm_lapic *apic) 338static inline int apic_search_irr(struct kvm_lapic *apic)
363{ 339{
364 return find_highest_vector(apic->regs + APIC_IRR); 340 return find_highest_vector(apic->regs + APIC_IRR);
@@ -563,7 +539,7 @@ static void apic_update_ppr(struct kvm_lapic *apic)
563 apic, ppr, isr, isrv); 539 apic, ppr, isr, isrv);
564 540
565 if (old_ppr != ppr) { 541 if (old_ppr != ppr) {
566 apic_set_reg(apic, APIC_PROCPRI, ppr); 542 kvm_lapic_set_reg(apic, APIC_PROCPRI, ppr);
567 if (ppr < old_ppr) 543 if (ppr < old_ppr)
568 kvm_make_request(KVM_REQ_EVENT, apic->vcpu); 544 kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
569 } 545 }
@@ -571,7 +547,7 @@ static void apic_update_ppr(struct kvm_lapic *apic)
571 547
572static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) 548static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
573{ 549{
574 apic_set_reg(apic, APIC_TASKPRI, tpr); 550 kvm_lapic_set_reg(apic, APIC_TASKPRI, tpr);
575 apic_update_ppr(apic); 551 apic_update_ppr(apic);
576} 552}
577 553
@@ -668,6 +644,7 @@ bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
668 return false; 644 return false;
669 } 645 }
670} 646}
647EXPORT_SYMBOL_GPL(kvm_apic_match_dest);
671 648
672int kvm_vector_to_index(u32 vector, u32 dest_vcpus, 649int kvm_vector_to_index(u32 vector, u32 dest_vcpus,
673 const unsigned long *bitmap, u32 bitmap_size) 650 const unsigned long *bitmap, u32 bitmap_size)
@@ -921,7 +898,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
921 898
922 if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) { 899 if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) {
923 if (trig_mode) 900 if (trig_mode)
924 apic_set_vector(vector, apic->regs + APIC_TMR); 901 kvm_lapic_set_vector(vector, apic->regs + APIC_TMR);
925 else 902 else
926 apic_clear_vector(vector, apic->regs + APIC_TMR); 903 apic_clear_vector(vector, apic->regs + APIC_TMR);
927 } 904 }
@@ -929,7 +906,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
929 if (vcpu->arch.apicv_active) 906 if (vcpu->arch.apicv_active)
930 kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); 907 kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
931 else { 908 else {
932 apic_set_irr(vector, apic); 909 kvm_lapic_set_irr(vector, apic);
933 910
934 kvm_make_request(KVM_REQ_EVENT, vcpu); 911 kvm_make_request(KVM_REQ_EVENT, vcpu);
935 kvm_vcpu_kick(vcpu); 912 kvm_vcpu_kick(vcpu);
@@ -1186,7 +1163,7 @@ static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
1186 return container_of(dev, struct kvm_lapic, dev); 1163 return container_of(dev, struct kvm_lapic, dev);
1187} 1164}
1188 1165
1189static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len, 1166int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
1190 void *data) 1167 void *data)
1191{ 1168{
1192 unsigned char alignment = offset & 0xf; 1169 unsigned char alignment = offset & 0xf;
@@ -1223,6 +1200,7 @@ static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
1223 } 1200 }
1224 return 0; 1201 return 0;
1225} 1202}
1203EXPORT_SYMBOL_GPL(kvm_lapic_reg_read);
1226 1204
1227static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) 1205static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
1228{ 1206{
@@ -1240,7 +1218,7 @@ static int apic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
1240 if (!apic_mmio_in_range(apic, address)) 1218 if (!apic_mmio_in_range(apic, address))
1241 return -EOPNOTSUPP; 1219 return -EOPNOTSUPP;
1242 1220
1243 apic_reg_read(apic, offset, len, data); 1221 kvm_lapic_reg_read(apic, offset, len, data);
1244 1222
1245 return 0; 1223 return 0;
1246} 1224}
@@ -1425,7 +1403,7 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
1425 } 1403 }
1426} 1404}
1427 1405
1428static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) 1406int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1429{ 1407{
1430 int ret = 0; 1408 int ret = 0;
1431 1409
@@ -1457,7 +1435,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1457 1435
1458 case APIC_DFR: 1436 case APIC_DFR:
1459 if (!apic_x2apic_mode(apic)) { 1437 if (!apic_x2apic_mode(apic)) {
1460 apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); 1438 kvm_lapic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
1461 recalculate_apic_map(apic->vcpu->kvm); 1439 recalculate_apic_map(apic->vcpu->kvm);
1462 } else 1440 } else
1463 ret = 1; 1441 ret = 1;
@@ -1472,10 +1450,10 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1472 int i; 1450 int i;
1473 u32 lvt_val; 1451 u32 lvt_val;
1474 1452
1475 for (i = 0; i < APIC_LVT_NUM; i++) { 1453 for (i = 0; i < KVM_APIC_LVT_NUM; i++) {
1476 lvt_val = kvm_apic_get_reg(apic, 1454 lvt_val = kvm_apic_get_reg(apic,
1477 APIC_LVTT + 0x10 * i); 1455 APIC_LVTT + 0x10 * i);
1478 apic_set_reg(apic, APIC_LVTT + 0x10 * i, 1456 kvm_lapic_set_reg(apic, APIC_LVTT + 0x10 * i,
1479 lvt_val | APIC_LVT_MASKED); 1457 lvt_val | APIC_LVT_MASKED);
1480 } 1458 }
1481 apic_update_lvtt(apic); 1459 apic_update_lvtt(apic);
@@ -1486,14 +1464,14 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1486 } 1464 }
1487 case APIC_ICR: 1465 case APIC_ICR:
1488 /* No delay here, so we always clear the pending bit */ 1466 /* No delay here, so we always clear the pending bit */
1489 apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); 1467 kvm_lapic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
1490 apic_send_ipi(apic); 1468 apic_send_ipi(apic);
1491 break; 1469 break;
1492 1470
1493 case APIC_ICR2: 1471 case APIC_ICR2:
1494 if (!apic_x2apic_mode(apic)) 1472 if (!apic_x2apic_mode(apic))
1495 val &= 0xff000000; 1473 val &= 0xff000000;
1496 apic_set_reg(apic, APIC_ICR2, val); 1474 kvm_lapic_set_reg(apic, APIC_ICR2, val);
1497 break; 1475 break;
1498 1476
1499 case APIC_LVT0: 1477 case APIC_LVT0:
@@ -1507,7 +1485,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1507 val |= APIC_LVT_MASKED; 1485 val |= APIC_LVT_MASKED;
1508 1486
1509 val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4]; 1487 val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
1510 apic_set_reg(apic, reg, val); 1488 kvm_lapic_set_reg(apic, reg, val);
1511 1489
1512 break; 1490 break;
1513 1491
@@ -1515,7 +1493,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1515 if (!kvm_apic_sw_enabled(apic)) 1493 if (!kvm_apic_sw_enabled(apic))
1516 val |= APIC_LVT_MASKED; 1494 val |= APIC_LVT_MASKED;
1517 val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); 1495 val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask);
1518 apic_set_reg(apic, APIC_LVTT, val); 1496 kvm_lapic_set_reg(apic, APIC_LVTT, val);
1519 apic_update_lvtt(apic); 1497 apic_update_lvtt(apic);
1520 break; 1498 break;
1521 1499
@@ -1524,14 +1502,14 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1524 break; 1502 break;
1525 1503
1526 hrtimer_cancel(&apic->lapic_timer.timer); 1504 hrtimer_cancel(&apic->lapic_timer.timer);
1527 apic_set_reg(apic, APIC_TMICT, val); 1505 kvm_lapic_set_reg(apic, APIC_TMICT, val);
1528 start_apic_timer(apic); 1506 start_apic_timer(apic);
1529 break; 1507 break;
1530 1508
1531 case APIC_TDCR: 1509 case APIC_TDCR:
1532 if (val & 4) 1510 if (val & 4)
1533 apic_debug("KVM_WRITE:TDCR %x\n", val); 1511 apic_debug("KVM_WRITE:TDCR %x\n", val);
1534 apic_set_reg(apic, APIC_TDCR, val); 1512 kvm_lapic_set_reg(apic, APIC_TDCR, val);
1535 update_divide_count(apic); 1513 update_divide_count(apic);
1536 break; 1514 break;
1537 1515
@@ -1544,7 +1522,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1544 1522
1545 case APIC_SELF_IPI: 1523 case APIC_SELF_IPI:
1546 if (apic_x2apic_mode(apic)) { 1524 if (apic_x2apic_mode(apic)) {
1547 apic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff)); 1525 kvm_lapic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff));
1548 } else 1526 } else
1549 ret = 1; 1527 ret = 1;
1550 break; 1528 break;
@@ -1556,6 +1534,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
1556 apic_debug("Local APIC Write to read-only register %x\n", reg); 1534 apic_debug("Local APIC Write to read-only register %x\n", reg);
1557 return ret; 1535 return ret;
1558} 1536}
1537EXPORT_SYMBOL_GPL(kvm_lapic_reg_write);
1559 1538
1560static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, 1539static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
1561 gpa_t address, int len, const void *data) 1540 gpa_t address, int len, const void *data)
@@ -1585,14 +1564,14 @@ static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
1585 apic_debug("%s: offset 0x%x with length 0x%x, and value is " 1564 apic_debug("%s: offset 0x%x with length 0x%x, and value is "
1586 "0x%x\n", __func__, offset, len, val); 1565 "0x%x\n", __func__, offset, len, val);
1587 1566
1588 apic_reg_write(apic, offset & 0xff0, val); 1567 kvm_lapic_reg_write(apic, offset & 0xff0, val);
1589 1568
1590 return 0; 1569 return 0;
1591} 1570}
1592 1571
1593void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) 1572void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
1594{ 1573{
1595 apic_reg_write(vcpu->arch.apic, APIC_EOI, 0); 1574 kvm_lapic_reg_write(vcpu->arch.apic, APIC_EOI, 0);
1596} 1575}
1597EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); 1576EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
1598 1577
@@ -1604,10 +1583,10 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
1604 /* hw has done the conditional check and inst decode */ 1583 /* hw has done the conditional check and inst decode */
1605 offset &= 0xff0; 1584 offset &= 0xff0;
1606 1585
1607 apic_reg_read(vcpu->arch.apic, offset, 4, &val); 1586 kvm_lapic_reg_read(vcpu->arch.apic, offset, 4, &val);
1608 1587
1609 /* TODO: optimize to just emulate side effect w/o one more write */ 1588 /* TODO: optimize to just emulate side effect w/o one more write */
1610 apic_reg_write(vcpu->arch.apic, offset, val); 1589 kvm_lapic_reg_write(vcpu->arch.apic, offset, val);
1611} 1590}
1612EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode); 1591EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode);
1613 1592
@@ -1740,28 +1719,28 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
1740 kvm_apic_set_id(apic, vcpu->vcpu_id); 1719 kvm_apic_set_id(apic, vcpu->vcpu_id);
1741 kvm_apic_set_version(apic->vcpu); 1720 kvm_apic_set_version(apic->vcpu);
1742 1721
1743 for (i = 0; i < APIC_LVT_NUM; i++) 1722 for (i = 0; i < KVM_APIC_LVT_NUM; i++)
1744 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); 1723 kvm_lapic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
1745 apic_update_lvtt(apic); 1724 apic_update_lvtt(apic);
1746 if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_LINT0_REENABLED)) 1725 if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_LINT0_REENABLED))
1747 apic_set_reg(apic, APIC_LVT0, 1726 kvm_lapic_set_reg(apic, APIC_LVT0,
1748 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); 1727 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
1749 apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0)); 1728 apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0));
1750 1729
1751 apic_set_reg(apic, APIC_DFR, 0xffffffffU); 1730 kvm_lapic_set_reg(apic, APIC_DFR, 0xffffffffU);
1752 apic_set_spiv(apic, 0xff); 1731 apic_set_spiv(apic, 0xff);
1753 apic_set_reg(apic, APIC_TASKPRI, 0); 1732 kvm_lapic_set_reg(apic, APIC_TASKPRI, 0);
1754 if (!apic_x2apic_mode(apic)) 1733 if (!apic_x2apic_mode(apic))
1755 kvm_apic_set_ldr(apic, 0); 1734 kvm_apic_set_ldr(apic, 0);
1756 apic_set_reg(apic, APIC_ESR, 0); 1735 kvm_lapic_set_reg(apic, APIC_ESR, 0);
1757 apic_set_reg(apic, APIC_ICR, 0); 1736 kvm_lapic_set_reg(apic, APIC_ICR, 0);
1758 apic_set_reg(apic, APIC_ICR2, 0); 1737 kvm_lapic_set_reg(apic, APIC_ICR2, 0);
1759 apic_set_reg(apic, APIC_TDCR, 0); 1738 kvm_lapic_set_reg(apic, APIC_TDCR, 0);
1760 apic_set_reg(apic, APIC_TMICT, 0); 1739 kvm_lapic_set_reg(apic, APIC_TMICT, 0);
1761 for (i = 0; i < 8; i++) { 1740 for (i = 0; i < 8; i++) {
1762 apic_set_reg(apic, APIC_IRR + 0x10 * i, 0); 1741 kvm_lapic_set_reg(apic, APIC_IRR + 0x10 * i, 0);
1763 apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); 1742 kvm_lapic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
1764 apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); 1743 kvm_lapic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
1765 } 1744 }
1766 apic->irr_pending = vcpu->arch.apicv_active; 1745 apic->irr_pending = vcpu->arch.apicv_active;
1767 apic->isr_count = vcpu->arch.apicv_active ? 1 : 0; 1746 apic->isr_count = vcpu->arch.apicv_active ? 1 : 0;
@@ -2139,8 +2118,8 @@ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
2139 2118
2140 /* if this is ICR write vector before command */ 2119 /* if this is ICR write vector before command */
2141 if (reg == APIC_ICR) 2120 if (reg == APIC_ICR)
2142 apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); 2121 kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
2143 return apic_reg_write(apic, reg, (u32)data); 2122 return kvm_lapic_reg_write(apic, reg, (u32)data);
2144} 2123}
2145 2124
2146int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) 2125int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
@@ -2157,10 +2136,10 @@ int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
2157 return 1; 2136 return 1;
2158 } 2137 }
2159 2138
2160 if (apic_reg_read(apic, reg, 4, &low)) 2139 if (kvm_lapic_reg_read(apic, reg, 4, &low))
2161 return 1; 2140 return 1;
2162 if (reg == APIC_ICR) 2141 if (reg == APIC_ICR)
2163 apic_reg_read(apic, APIC_ICR2, 4, &high); 2142 kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high);
2164 2143
2165 *data = (((u64)high) << 32) | low; 2144 *data = (((u64)high) << 32) | low;
2166 2145
@@ -2176,8 +2155,8 @@ int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data)
2176 2155
2177 /* if this is ICR write vector before command */ 2156 /* if this is ICR write vector before command */
2178 if (reg == APIC_ICR) 2157 if (reg == APIC_ICR)
2179 apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); 2158 kvm_lapic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
2180 return apic_reg_write(apic, reg, (u32)data); 2159 return kvm_lapic_reg_write(apic, reg, (u32)data);
2181} 2160}
2182 2161
2183int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data) 2162int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
@@ -2188,10 +2167,10 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
2188 if (!lapic_in_kernel(vcpu)) 2167 if (!lapic_in_kernel(vcpu))
2189 return 1; 2168 return 1;
2190 2169
2191 if (apic_reg_read(apic, reg, 4, &low)) 2170 if (kvm_lapic_reg_read(apic, reg, 4, &low))
2192 return 1; 2171 return 1;
2193 if (reg == APIC_ICR) 2172 if (reg == APIC_ICR)
2194 apic_reg_read(apic, APIC_ICR2, 4, &high); 2173 kvm_lapic_reg_read(apic, APIC_ICR2, 4, &high);
2195 2174
2196 *data = (((u64)high) << 32) | low; 2175 *data = (((u64)high) << 32) | low;
2197 2176
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index f71183e502ee..a70cb62933b9 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -7,6 +7,7 @@
7 7
8#define KVM_APIC_INIT 0 8#define KVM_APIC_INIT 0
9#define KVM_APIC_SIPI 1 9#define KVM_APIC_SIPI 1
10#define KVM_APIC_LVT_NUM 6
10 11
11struct kvm_timer { 12struct kvm_timer {
12 struct hrtimer timer; 13 struct hrtimer timer;
@@ -59,6 +60,11 @@ void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
59void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); 60void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
60u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); 61u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
61void kvm_apic_set_version(struct kvm_vcpu *vcpu); 62void kvm_apic_set_version(struct kvm_vcpu *vcpu);
63int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val);
64int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
65 void *data);
66bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
67 int short_hand, unsigned int dest, int dest_mode);
62 68
63void __kvm_apic_update_irr(u32 *pir, void *regs); 69void __kvm_apic_update_irr(u32 *pir, void *regs);
64void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir); 70void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
@@ -99,11 +105,34 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
99int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); 105int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
100void kvm_lapic_init(void); 106void kvm_lapic_init(void);
101 107
108#define VEC_POS(v) ((v) & (32 - 1))
109#define REG_POS(v) (((v) >> 5) << 4)
110
111static inline void kvm_lapic_set_vector(int vec, void *bitmap)
112{
113 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
114}
115
116static inline void kvm_lapic_set_irr(int vec, struct kvm_lapic *apic)
117{
118 kvm_lapic_set_vector(vec, apic->regs + APIC_IRR);
119 /*
120 * irr_pending must be true if any interrupt is pending; set it after
121 * APIC_IRR to avoid race with apic_clear_irr
122 */
123 apic->irr_pending = true;
124}
125
102static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off) 126static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
103{ 127{
104 return *((u32 *) (apic->regs + reg_off)); 128 return *((u32 *) (apic->regs + reg_off));
105} 129}
106 130
131static inline void kvm_lapic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
132{
133 *((u32 *) (apic->regs + reg_off)) = val;
134}
135
107extern struct static_key kvm_no_apic_vcpu; 136extern struct static_key kvm_no_apic_vcpu;
108 137
109static inline bool lapic_in_kernel(struct kvm_vcpu *vcpu) 138static inline bool lapic_in_kernel(struct kvm_vcpu *vcpu)