lapic.c (0a379e21c503b2ff66b44d588df9f231e9b0b9ca) | lapic.c (9ed96e87c5748de4c2807ef17e81287c7304186c) |
---|---|
1 2/* 3 * Local APIC virtualization 4 * 5 * Copyright (C) 2006 Qumranet, Inc. 6 * Copyright (C) 2007 Novell 7 * Copyright (C) 2007 Intel 8 * Copyright 2009 Red Hat, Inc. and/or its affiliates. --- 57 unchanged lines hidden (view full) --- 66#define APIC_DEST_NOSHORT 0x0 67#define APIC_DEST_MASK 0x800 68#define MAX_APIC_VECTOR 256 69#define APIC_VECTORS_PER_REG 32 70 71#define VEC_POS(v) ((v) & (32 - 1)) 72#define REG_POS(v) (((v) >> 5) << 4) 73 | 1 2/* 3 * Local APIC virtualization 4 * 5 * Copyright (C) 2006 Qumranet, Inc. 6 * Copyright (C) 2007 Novell 7 * Copyright (C) 2007 Intel 8 * Copyright 2009 Red Hat, Inc. and/or its affiliates. --- 57 unchanged lines hidden (view full) --- 66#define APIC_DEST_NOSHORT 0x0 67#define APIC_DEST_MASK 0x800 68#define MAX_APIC_VECTOR 256 69#define APIC_VECTORS_PER_REG 32 70 71#define VEC_POS(v) ((v) & (32 - 1)) 72#define REG_POS(v) (((v) >> 5) << 4) 73 |
74static unsigned int min_timer_period_us = 500; 75module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR); 76 | |
77static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) 78{ 79 *((u32 *) (apic->regs + reg_off)) = val; 80} 81 82static inline int apic_test_vector(int vec, void *bitmap) 83{ 84 return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); --- 53 unchanged lines hidden (view full) --- 138 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ 139 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) 140 141static inline int kvm_apic_id(struct kvm_lapic *apic) 142{ 143 return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; 144} 145 | 74static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) 75{ 76 *((u32 *) (apic->regs + reg_off)) = val; 77} 78 79static inline int apic_test_vector(int vec, void *bitmap) 80{ 81 return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); --- 53 unchanged lines hidden (view full) --- 135 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ 136 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) 137 138static inline int kvm_apic_id(struct kvm_lapic *apic) 139{ 140 return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; 141} 142 |
146#define KVM_X2APIC_CID_BITS 0 147 | |
148static void recalculate_apic_map(struct kvm *kvm) 149{ 150 struct kvm_apic_map *new, *old = NULL; 151 struct kvm_vcpu *vcpu; 152 int i; 153 154 new = kzalloc(sizeof(struct kvm_apic_map), GFP_KERNEL); 155 --- 21 unchanged lines hidden (view full) --- 177 * We take advatage of this while building logical id loockup 178 * table. After reset APICs are in xapic/flat mode, so if we 179 * find apic with different setting we assume this is the mode 180 * OS wants all apics to be in; build lookup table accordingly. 181 */ 182 if (apic_x2apic_mode(apic)) { 183 new->ldr_bits = 32; 184 new->cid_shift = 16; | 143static void recalculate_apic_map(struct kvm *kvm) 144{ 145 struct kvm_apic_map *new, *old = NULL; 146 struct kvm_vcpu *vcpu; 147 int i; 148 149 new = kzalloc(sizeof(struct kvm_apic_map), GFP_KERNEL); 150 --- 21 unchanged lines hidden (view full) --- 172 * We take advatage of this while building logical id loockup 173 * table. After reset APICs are in xapic/flat mode, so if we 174 * find apic with different setting we assume this is the mode 175 * OS wants all apics to be in; build lookup table accordingly. 176 */ 177 if (apic_x2apic_mode(apic)) { 178 new->ldr_bits = 32; 179 new->cid_shift = 16; |
185 new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; 186 new->lid_mask = 0xffff; | 180 new->cid_mask = new->lid_mask = 0xffff; |
187 } else if (kvm_apic_sw_enabled(apic) && 188 !new->cid_mask /* flat mode */ && 189 kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { 190 new->cid_shift = 4; 191 new->cid_mask = 0xf; 192 new->lid_mask = 0xf; 193 } 194 --- 235 unchanged lines hidden (view full) --- 430 return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED; 431} 432 433static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) 434{ 435 u8 val; 436 if (pv_eoi_get_user(vcpu, &val) < 0) 437 apic_debug("Can't read EOI MSR value: 0x%llx\n", | 181 } else if (kvm_apic_sw_enabled(apic) && 182 !new->cid_mask /* flat mode */ && 183 kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { 184 new->cid_shift = 4; 185 new->cid_mask = 0xf; 186 new->lid_mask = 0xf; 187 } 188 --- 235 unchanged lines hidden (view full) --- 424 return vcpu->arch.pv_eoi.msr_val & KVM_MSR_ENABLED; 425} 426 427static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) 428{ 429 u8 val; 430 if (pv_eoi_get_user(vcpu, &val) < 0) 431 apic_debug("Can't read EOI MSR value: 0x%llx\n", |
438 (unsigned long long)vcpi->arch.pv_eoi.msr_val); | 432 (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
439 return val & 0x1; 440} 441 442static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) 443{ 444 if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { 445 apic_debug("Can't set EOI MSR value: 0x%llx\n", | 433 return val & 0x1; 434} 435 436static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) 437{ 438 if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { 439 apic_debug("Can't set EOI MSR value: 0x%llx\n", |
446 (unsigned long long)vcpi->arch.pv_eoi.msr_val); | 440 (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
447 return; 448 } 449 __set_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); 450} 451 452static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) 453{ 454 if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { 455 apic_debug("Can't clear EOI MSR value: 0x%llx\n", | 441 return; 442 } 443 __set_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); 444} 445 446static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) 447{ 448 if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { 449 apic_debug("Can't clear EOI MSR value: 0x%llx\n", |
456 (unsigned long long)vcpi->arch.pv_eoi.msr_val); | 450 (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
457 return; 458 } 459 __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); 460} 461 462static inline int apic_find_highest_isr(struct kvm_lapic *apic) 463{ 464 int result; --- 374 unchanged lines hidden (view full) --- 839{ 840 ktime_t remaining; 841 s64 ns; 842 u32 tmcct; 843 844 ASSERT(apic != NULL); 845 846 /* if initial count is 0, current count should also be 0 */ | 451 return; 452 } 453 __clear_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention); 454} 455 456static inline int apic_find_highest_isr(struct kvm_lapic *apic) 457{ 458 int result; --- 374 unchanged lines hidden (view full) --- 833{ 834 ktime_t remaining; 835 s64 ns; 836 u32 tmcct; 837 838 ASSERT(apic != NULL); 839 840 /* if initial count is 0, current count should also be 0 */ |
847 if (kvm_apic_get_reg(apic, APIC_TMICT) == 0 || 848 apic->lapic_timer.period == 0) | 841 if (kvm_apic_get_reg(apic, APIC_TMICT) == 0) |
849 return 0; 850 851 remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); 852 if (ktime_to_ns(remaining) < 0) 853 remaining = ktime_set(0, 0); 854 855 ns = mod_64(ktime_to_ns(remaining), apic->lapic_timer.period); 856 tmcct = div64_u64(ns, --- 488 unchanged lines hidden (view full) --- 1345 struct kvm_lapic *apic = vcpu->arch.apic; 1346 1347 if (!apic) { 1348 value |= MSR_IA32_APICBASE_BSP; 1349 vcpu->arch.apic_base = value; 1350 return; 1351 } 1352 | 842 return 0; 843 844 remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); 845 if (ktime_to_ns(remaining) < 0) 846 remaining = ktime_set(0, 0); 847 848 ns = mod_64(ktime_to_ns(remaining), apic->lapic_timer.period); 849 tmcct = div64_u64(ns, --- 488 unchanged lines hidden (view full) --- 1338 struct kvm_lapic *apic = vcpu->arch.apic; 1339 1340 if (!apic) { 1341 value |= MSR_IA32_APICBASE_BSP; 1342 vcpu->arch.apic_base = value; 1343 return; 1344 } 1345 |
1353 if (!kvm_vcpu_is_bsp(apic->vcpu)) 1354 value &= ~MSR_IA32_APICBASE_BSP; 1355 vcpu->arch.apic_base = value; 1356 | |
1357 /* update jump label if enable bit changes */ 1358 if ((vcpu->arch.apic_base ^ value) & MSR_IA32_APICBASE_ENABLE) { 1359 if (value & MSR_IA32_APICBASE_ENABLE) 1360 static_key_slow_dec_deferred(&apic_hw_disabled); 1361 else 1362 static_key_slow_inc(&apic_hw_disabled.key); 1363 recalculate_apic_map(vcpu->kvm); 1364 } 1365 | 1346 /* update jump label if enable bit changes */ 1347 if ((vcpu->arch.apic_base ^ value) & MSR_IA32_APICBASE_ENABLE) { 1348 if (value & MSR_IA32_APICBASE_ENABLE) 1349 static_key_slow_dec_deferred(&apic_hw_disabled); 1350 else 1351 static_key_slow_inc(&apic_hw_disabled.key); 1352 recalculate_apic_map(vcpu->kvm); 1353 } 1354 |
1355 if (!kvm_vcpu_is_bsp(apic->vcpu)) 1356 value &= ~MSR_IA32_APICBASE_BSP; 1357 1358 vcpu->arch.apic_base = value; |
|
1366 if ((old_value ^ value) & X2APIC_ENABLE) { 1367 if (value & X2APIC_ENABLE) { 1368 u32 id = kvm_apic_id(apic); 1369 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); 1370 kvm_apic_set_ldr(apic, ldr); 1371 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, true); 1372 } else 1373 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, false); --- 316 unchanged lines hidden (view full) --- 1690 return; 1691 vector = apic_set_eoi(apic); 1692 trace_kvm_pv_eoi(apic, vector); 1693} 1694 1695void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) 1696{ 1697 u32 data; | 1359 if ((old_value ^ value) & X2APIC_ENABLE) { 1360 if (value & X2APIC_ENABLE) { 1361 u32 id = kvm_apic_id(apic); 1362 u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); 1363 kvm_apic_set_ldr(apic, ldr); 1364 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, true); 1365 } else 1366 kvm_x86_ops->set_virtual_x2apic_mode(vcpu, false); --- 316 unchanged lines hidden (view full) --- 1683 return; 1684 vector = apic_set_eoi(apic); 1685 trace_kvm_pv_eoi(apic, vector); 1686} 1687 1688void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) 1689{ 1690 u32 data; |
1691 void *vapic; |
|
1698 1699 if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention)) 1700 apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic); 1701 1702 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) 1703 return; 1704 | 1692 1693 if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention)) 1694 apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic); 1695 1696 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) 1697 return; 1698 |
1705 kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, 1706 sizeof(u32)); | 1699 vapic = kmap_atomic(vcpu->arch.apic->vapic_page); 1700 data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)); 1701 kunmap_atomic(vapic); |
1707 1708 apic_set_tpr(vcpu->arch.apic, data & 0xff); 1709} 1710 1711/* 1712 * apic_sync_pv_eoi_to_guest - called before vmentry 1713 * 1714 * Detect whether it's safe to enable PV EOI and --- 19 unchanged lines hidden (view full) --- 1734 pv_eoi_set_pending(apic->vcpu); 1735} 1736 1737void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) 1738{ 1739 u32 data, tpr; 1740 int max_irr, max_isr; 1741 struct kvm_lapic *apic = vcpu->arch.apic; | 1702 1703 apic_set_tpr(vcpu->arch.apic, data & 0xff); 1704} 1705 1706/* 1707 * apic_sync_pv_eoi_to_guest - called before vmentry 1708 * 1709 * Detect whether it's safe to enable PV EOI and --- 19 unchanged lines hidden (view full) --- 1729 pv_eoi_set_pending(apic->vcpu); 1730} 1731 1732void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) 1733{ 1734 u32 data, tpr; 1735 int max_irr, max_isr; 1736 struct kvm_lapic *apic = vcpu->arch.apic; |
1737 void *vapic; |
|
1742 1743 apic_sync_pv_eoi_to_guest(vcpu, apic); 1744 1745 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) 1746 return; 1747 1748 tpr = kvm_apic_get_reg(apic, APIC_TASKPRI) & 0xff; 1749 max_irr = apic_find_highest_irr(apic); 1750 if (max_irr < 0) 1751 max_irr = 0; 1752 max_isr = apic_find_highest_isr(apic); 1753 if (max_isr < 0) 1754 max_isr = 0; 1755 data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24); 1756 | 1738 1739 apic_sync_pv_eoi_to_guest(vcpu, apic); 1740 1741 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) 1742 return; 1743 1744 tpr = kvm_apic_get_reg(apic, APIC_TASKPRI) & 0xff; 1745 max_irr = apic_find_highest_irr(apic); 1746 if (max_irr < 0) 1747 max_irr = 0; 1748 max_isr = apic_find_highest_isr(apic); 1749 if (max_isr < 0) 1750 max_isr = 0; 1751 data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24); 1752 |
1757 kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, 1758 sizeof(u32)); | 1753 vapic = kmap_atomic(vcpu->arch.apic->vapic_page); 1754 *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data; 1755 kunmap_atomic(vapic); |
1759} 1760 | 1756} 1757 |
1761int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) | 1758void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) |
1762{ | 1759{ |
1763 if (vapic_addr) { 1764 if (kvm_gfn_to_hva_cache_init(vcpu->kvm, 1765 &vcpu->arch.apic->vapic_cache, 1766 vapic_addr, sizeof(u32))) 1767 return -EINVAL; | 1760 vcpu->arch.apic->vapic_addr = vapic_addr; 1761 if (vapic_addr) |
1768 __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); | 1762 __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); |
1769 } else { | 1763 else |
1770 __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); | 1764 __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); |
1771 } 1772 1773 vcpu->arch.apic->vapic_addr = vapic_addr; 1774 return 0; | |
1775} 1776 1777int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1778{ 1779 struct kvm_lapic *apic = vcpu->arch.apic; 1780 u32 reg = (msr - APIC_BASE_MSR) << 4; 1781 1782 if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) --- 107 unchanged lines hidden --- | 1765} 1766 1767int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1768{ 1769 struct kvm_lapic *apic = vcpu->arch.apic; 1770 u32 reg = (msr - APIC_BASE_MSR) << 4; 1771 1772 if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) --- 107 unchanged lines hidden --- |