RE: KVM: emulate lapic tsc deadline timer for guest

Liu, Jinsong
2011-10-05T17:07:52Z

[-- Attachment #1: Type: text/plain, Size: 2994 bytes --]

Yes, Avi has noticed this issue and fix the bug as attached.

Thanks,
Jinsong

Dan Carpenter wrote:
> This patch causes a NULL dereference for me when I start qemu.
>
> [ 136.130978] BUG: unable to handle kernel NULL pointer dereference
> at 0000000000000078 [ 136.131032] IP: [<ffffffffa015a3d3>]
> update_cpuid+0x63/0x90 [kvm] [ 136.131076] PGD 3fcac4067 PUD
> 3fc91a067 PMD 0 [ 136.131108] Oops: 0002 [#1] SMP
> [ 136.131132] CPU 0
> [ 136.131145] Modules linked in: e1000e fuse kvm_intel kvm radeon
> ttm [last unloaded: e1000e] [ 136.131208]
> [ 136.131219] Pid: 2678, comm: qemu-system-x86 Not tainted
> 3.1.0-rc8-next-20110930+ #92 System manufacturer System Product
> Name/P8Z68-V PRO [ 136.131289] RIP: 0010:[<ffffffffa015a3d3>]
> [<ffffffffa015a3d3>] update_cpuid+0x63/0x90 [kvm] [ 136.131341] RSP:
> 0018:ffff880404761d20 EFLAGS: 00010282 [ 136.131370] RAX:
> 0000000000000000 RBX: ffff8803fc408000 RCX: ffff8803fc408b18 [
> 136.131408] RDX: 0000000080802001 RSI: 0000000000000001 RDI:
> ffff8803fc408000 [ 136.131445] RBP: ffff880404761d28 R08:
> 0000000000000015 R09: 0000000000000003 [ 136.131483] R10:
> 0000000000000003 R11: 0000000000000000 R12: ffff8803fc408000 [
> 136.131520] R13: 00007fffb5e8d870 R14: 0000000000000015 R15:
> 0000000000000000 [ 136.131559] FS: 00007f96c6324760(0000)
> GS:ffff88042f400000(0000) knlGS:0000000000000000 [ 136.131602] CS:
> 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 136.131632] CR2:
> 0000000000000078 CR3: 00000003fcac5000 CR4: 00000000000426f0 [
> 136.131670] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
> 0000000000000000 [ 136.131707] DR3: 0000000000000000 DR6:
> 00000000ffff0ff0 DR7: 0000000000000400 [ 136.131745] Process
> qemu-system-x86 (pid: 2678, threadinfo ffff880404760000, task
> ffff880404618000) [ 136.131792] Stack: [ 136.131804]
> 0000000000000000 ffff880404761df8 ffffffffa016635f 00000000ffffffff [
> 136.131851] 0000000000000015 0000000000000000 0200000000000000
> 0000000000000000 [ 136.131897] ffff88042f7ee000 ffff880404761da8
> ffffffffa01beba9 ffffc90006722000 [ 136.131944] Call Trace: [
> 136.131966] [<ffffffffa016635f>] kvm_arch_vcpu_ioctl+0xd5f/0x15d0
> [kvm] [ 136.132005] [<ffffffffa01beba9>] ? vmx_vcpu_load+0x39/0x1b0
> [kvm_intel] [ 136.132046] [<ffffffffa01654fb>] ?
> kvm_arch_vcpu_load+0x6b/0x170 [kvm]
>
> Here is the code listing from gdb:
>
> (gdb) list *(update_cpuid+0x63)
> 0xc3d3 is in update_cpuid (arch/x86/kvm/x86.c:618).
> 613 }
> 614
> 615 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
> 616 best->function == 0x1) {
> 617 best->ecx |= bit(X86_FEATURE_TSC_DEADLINE_TIMER);
> 618 vcpu->arch.apic->lapic_timer.timer_mode_mask = (3 << 17);
> 619 } else
> 620 vcpu->arch.apic->lapic_timer.timer_mode_mask = (1 << 17);
> 621 }
> 622
> (gdb)
>
> Reverting the patch fixes things for me. I'm using linux-next from
> Friday.
>
> regards,
> dan carpenter

[-- Attachment #2: Type: message/rfc822, Size: 3584 bytes --]

From: Avi Kivity <avi@redhat.com>
To: "kvm@vger.kernel.org" <kvm@vger.kernel.org>, Marcelo Tosatti <mtosatti@redhat.com>
Cc: "Liu, Jinsong" <jinsong.liu@intel.com>
Subject: [PATCH] KVM: Fix tsc deadline timer without irqchip_in_kernel()
Date: Sun, 2 Oct 2011 17:51:06 +0800
Message-ID: <1317549066-10582-1-git-send-email-avi@redhat.com>

vcpu->arch.apic may be NULL.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/x86.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 83b839f..aa11707 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -600,6 +600,8 @@ static bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
static void update_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best;
+ struct kvm_lapic *apic = vcpu->arch.apic;
+ u32 timer_mode_mask;

best = kvm_find_cpuid_entry(vcpu, 1, 0);
if (!best)
@@ -615,9 +617,12 @@ static void update_cpuid(struct kvm_vcpu *vcpu)
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
best->function == 0x1) {
best->ecx |= bit(X86_FEATURE_TSC_DEADLINE_TIMER);
- vcpu->arch.apic->lapic_timer.timer_mode_mask = (3 << 17);
+ timer_mode_mask = 3 << 17;
} else
- vcpu->arch.apic->lapic_timer.timer_mode_mask = (1 << 17);
+ timer_mode_mask = 1 << 17;
+
+ if (apic)
+ apic->lapic_timer.timer_mode_mask = timer_mode_mask;
}

int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
--
1.7.6.3