Updated from Linux LTS 3.10.24 to 3.10.25
This commit is contained in:
@@ -153,6 +153,8 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
|
||||
return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
|
||||
}
|
||||
|
||||
#define KVM_X2APIC_CID_BITS 0
|
||||
|
||||
static void recalculate_apic_map(struct kvm *kvm)
|
||||
{
|
||||
struct kvm_apic_map *new, *old = NULL;
|
||||
@@ -190,7 +192,8 @@ static void recalculate_apic_map(struct kvm *kvm)
|
||||
if (apic_x2apic_mode(apic)) {
|
||||
new->ldr_bits = 32;
|
||||
new->cid_shift = 16;
|
||||
new->cid_mask = new->lid_mask = 0xffff;
|
||||
new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1;
|
||||
new->lid_mask = 0xffff;
|
||||
} else if (kvm_apic_sw_enabled(apic) &&
|
||||
!new->cid_mask /* flat mode */ &&
|
||||
kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
|
||||
@@ -855,7 +858,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
|
||||
ASSERT(apic != NULL);
|
||||
|
||||
/* if initial count is 0, current count should also be 0 */
|
||||
if (kvm_apic_get_reg(apic, APIC_TMICT) == 0)
|
||||
if (kvm_apic_get_reg(apic, APIC_TMICT) == 0 ||
|
||||
apic->lapic_timer.period == 0)
|
||||
return 0;
|
||||
|
||||
remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
|
||||
@@ -1705,7 +1709,6 @@ static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu,
|
||||
void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 data;
|
||||
void *vapic;
|
||||
|
||||
if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention))
|
||||
apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic);
|
||||
@@ -1713,9 +1716,8 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
|
||||
if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
|
||||
return;
|
||||
|
||||
vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
|
||||
data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
|
||||
kunmap_atomic(vapic);
|
||||
kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
|
||||
sizeof(u32));
|
||||
|
||||
apic_set_tpr(vcpu->arch.apic, data & 0xff);
|
||||
}
|
||||
@@ -1751,7 +1753,6 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
|
||||
u32 data, tpr;
|
||||
int max_irr, max_isr;
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
void *vapic;
|
||||
|
||||
apic_sync_pv_eoi_to_guest(vcpu, apic);
|
||||
|
||||
@@ -1767,18 +1768,24 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
|
||||
max_isr = 0;
|
||||
data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
|
||||
|
||||
vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
|
||||
*(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data;
|
||||
kunmap_atomic(vapic);
|
||||
kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
|
||||
int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
|
||||
{
|
||||
vcpu->arch.apic->vapic_addr = vapic_addr;
|
||||
if (vapic_addr)
|
||||
if (vapic_addr) {
|
||||
if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
|
||||
&vcpu->arch.apic->vapic_cache,
|
||||
vapic_addr, sizeof(u32)))
|
||||
return -EINVAL;
|
||||
__set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
|
||||
else
|
||||
} else {
|
||||
__clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
|
||||
}
|
||||
|
||||
vcpu->arch.apic->vapic_addr = vapic_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
||||
|
||||
@@ -34,7 +34,7 @@ struct kvm_lapic {
|
||||
*/
|
||||
void *regs;
|
||||
gpa_t vapic_addr;
|
||||
struct page *vapic_page;
|
||||
struct gfn_to_hva_cache vapic_cache;
|
||||
unsigned long pending_events;
|
||||
unsigned int sipi_vector;
|
||||
};
|
||||
@@ -76,7 +76,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data);
|
||||
void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset);
|
||||
void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector);
|
||||
|
||||
void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
|
||||
int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
|
||||
void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
|
||||
void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
||||
@@ -3138,8 +3138,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
|
||||
r = -EFAULT;
|
||||
if (copy_from_user(&va, argp, sizeof va))
|
||||
goto out;
|
||||
r = 0;
|
||||
kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
|
||||
r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
|
||||
break;
|
||||
}
|
||||
case KVM_X86_SETUP_MCE: {
|
||||
@@ -5539,36 +5538,6 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
|
||||
!kvm_event_needs_reinjection(vcpu);
|
||||
}
|
||||
|
||||
static int vapic_enter(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
struct page *page;
|
||||
|
||||
if (!apic || !apic->vapic_addr)
|
||||
return 0;
|
||||
|
||||
page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
|
||||
if (is_error_page(page))
|
||||
return -EFAULT;
|
||||
|
||||
vcpu->arch.apic->vapic_page = page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vapic_exit(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
int idx;
|
||||
|
||||
if (!apic || !apic->vapic_addr)
|
||||
return;
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
kvm_release_page_dirty(apic->vapic_page);
|
||||
mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
}
|
||||
|
||||
static void update_cr8_intercept(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int max_irr, tpr;
|
||||
@@ -5889,11 +5858,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
|
||||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
|
||||
r = vapic_enter(vcpu);
|
||||
if (r) {
|
||||
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
while (r > 0) {
|
||||
@@ -5951,8 +5915,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
|
||||
|
||||
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
|
||||
|
||||
vapic_exit(vcpu);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user