Commit ffc29649 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kvm-3.6-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull KVM updates from Avi Kivity:
 "A trio of KVM fixes: incorrect lookup of guest cpuid, an uninitialized
  variable fix, and error path cleanup fix."

* tag 'kvm-3.6-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: fix error paths for failed gfn_to_page() calls
  KVM: x86: Check INVPCID feature bit in EBX of leaf 7
  KVM: PIC: fix use of uninitialised variable.
parents 44346cfe 4484141a
...@@ -318,7 +318,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) ...@@ -318,7 +318,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
if (val & 0x10) { if (val & 0x10) {
u8 edge_irr = s->irr & ~s->elcr; u8 edge_irr = s->irr & ~s->elcr;
int i; int i;
bool found; bool found = false;
struct kvm_vcpu *vcpu; struct kvm_vcpu *vcpu;
s->init4 = val & 1; s->init4 = val & 1;
......
...@@ -3619,6 +3619,7 @@ static void seg_setup(int seg) ...@@ -3619,6 +3619,7 @@ static void seg_setup(int seg)
static int alloc_apic_access_page(struct kvm *kvm) static int alloc_apic_access_page(struct kvm *kvm)
{ {
struct page *page;
struct kvm_userspace_memory_region kvm_userspace_mem; struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0; int r = 0;
...@@ -3633,7 +3634,13 @@ static int alloc_apic_access_page(struct kvm *kvm) ...@@ -3633,7 +3634,13 @@ static int alloc_apic_access_page(struct kvm *kvm)
if (r) if (r)
goto out; goto out;
kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); page = gfn_to_page(kvm, 0xfee00);
if (is_error_page(page)) {
r = -EFAULT;
goto out;
}
kvm->arch.apic_access_page = page;
out: out:
mutex_unlock(&kvm->slots_lock); mutex_unlock(&kvm->slots_lock);
return r; return r;
...@@ -3641,6 +3648,7 @@ static int alloc_apic_access_page(struct kvm *kvm) ...@@ -3641,6 +3648,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
static int alloc_identity_pagetable(struct kvm *kvm) static int alloc_identity_pagetable(struct kvm *kvm)
{ {
struct page *page;
struct kvm_userspace_memory_region kvm_userspace_mem; struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0; int r = 0;
...@@ -3656,8 +3664,13 @@ static int alloc_identity_pagetable(struct kvm *kvm) ...@@ -3656,8 +3664,13 @@ static int alloc_identity_pagetable(struct kvm *kvm)
if (r) if (r)
goto out; goto out;
kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, page = gfn_to_page(kvm, kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); if (is_error_page(page)) {
r = -EFAULT;
goto out;
}
kvm->arch.ept_identity_pagetable = page;
out: out:
mutex_unlock(&kvm->slots_lock); mutex_unlock(&kvm->slots_lock);
return r; return r;
...@@ -6575,7 +6588,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) ...@@ -6575,7 +6588,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
/* Exposing INVPCID only when PCID is exposed */ /* Exposing INVPCID only when PCID is exposed */
best = kvm_find_cpuid_entry(vcpu, 0x7, 0); best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
if (vmx_invpcid_supported() && if (vmx_invpcid_supported() &&
best && (best->ecx & bit(X86_FEATURE_INVPCID)) && best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&
guest_cpuid_has_pcid(vcpu)) { guest_cpuid_has_pcid(vcpu)) {
exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
...@@ -6585,7 +6598,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) ...@@ -6585,7 +6598,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
vmcs_write32(SECONDARY_VM_EXEC_CONTROL, vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
exec_control); exec_control);
if (best) if (best)
best->ecx &= ~bit(X86_FEATURE_INVPCID); best->ebx &= ~bit(X86_FEATURE_INVPCID);
} }
} }
......
...@@ -5113,17 +5113,20 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu) ...@@ -5113,17 +5113,20 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
!kvm_event_needs_reinjection(vcpu); !kvm_event_needs_reinjection(vcpu);
} }
static void vapic_enter(struct kvm_vcpu *vcpu) static int vapic_enter(struct kvm_vcpu *vcpu)
{ {
struct kvm_lapic *apic = vcpu->arch.apic; struct kvm_lapic *apic = vcpu->arch.apic;
struct page *page; struct page *page;
if (!apic || !apic->vapic_addr) if (!apic || !apic->vapic_addr)
return; return 0;
page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
if (is_error_page(page))
return -EFAULT;
vcpu->arch.apic->vapic_page = page; vcpu->arch.apic->vapic_page = page;
return 0;
} }
static void vapic_exit(struct kvm_vcpu *vcpu) static void vapic_exit(struct kvm_vcpu *vcpu)
...@@ -5430,7 +5433,11 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) ...@@ -5430,7 +5433,11 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
} }
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
vapic_enter(vcpu); r = vapic_enter(vcpu);
if (r) {
srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
return r;
}
r = 1; r = 1;
while (r > 0) { while (r > 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment