Index: kvm/drivers/kvm/vmx.c =================================================================== --- kvm.orig/drivers/kvm/vmx.c 2007-08-13 14:11:38.000000000 +0200 +++ kvm/drivers/kvm/vmx.c 2007-08-13 14:29:44.000000000 +0200 @@ -2052,6 +2052,7 @@ struct vcpu_vmx *vmx = to_vmx(vcpu); u8 fail; int r; + ktime_t now, delta; preempted: if (vcpu->guest_debug.enabled) @@ -2078,6 +2079,7 @@ local_irq_disable(); vcpu->guest_mode = 1; + now = ktime_get(); if (vcpu->requests) if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests)) vmx_flush_tlb(vcpu); @@ -2198,6 +2200,8 @@ [cr2]"i"(offsetof(struct kvm_vcpu, cr2)) : "cc", "memory" ); + delta = ktime_sub(ktime_get(), now); + current->vtime = ktime_add(current->vtime, delta); vcpu->guest_mode = 0; local_irq_enable(); Index: kvm/include/linux/sched.h =================================================================== --- kvm.orig/include/linux/sched.h 2007-08-13 14:25:58.000000000 +0200 +++ kvm/include/linux/sched.h 2007-08-13 14:29:44.000000000 +0200 @@ -1192,6 +1192,9 @@ #ifdef CONFIG_FAULT_INJECTION int make_it_fail; #endif +#ifdef CONFIG_VIRTUALIZATION + ktime_t vtime; +#endif }; /* Index: kvm/kernel/sched.c =================================================================== --- kvm.orig/kernel/sched.c 2007-08-13 14:11:38.000000000 +0200 +++ kvm/kernel/sched.c 2007-08-13 14:34:47.000000000 +0200 @@ -3212,6 +3212,29 @@ return ns; } +#ifdef CONFIG_VIRTUALIZATION +static cputime_t account_guest_time(struct task_struct *p, cputime_t cputime) +{ + struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; + ktime_t kmsec = ktime_set(0, NSEC_PER_MSEC); + cputime_t cmsec = msecs_to_cputime(1); + + while ((ktime_to_ns(p->vtime) >= NSEC_PER_MSEC) && + (cputime_to_msecs(cputime) >= 1)) { + p->vtime = ktime_sub(p->vtime, kmsec); + p->utime = cputime_add(p->utime, cmsec); + + cputime = cputime_sub(cputime, cmsec); + + cpustat->guest = cputime64_add(cpustat->guest, + cputime_to_cputime64(cmsec)); + cpustat->user = cputime64_add(cpustat->user, + cputime_to_cputime64(cmsec)); + } + return cputime; +} +#endif + /* * Account user cpu time to a process. * @p: the process that the cpu time gets accounted to @@ -3246,6 +3269,10 @@ struct rq *rq = this_rq(); cputime64_t tmp; +#ifdef CONFIG_VIRTUALIZATION + cputime = account_guest_time(p, cputime); +#endif + p->stime = cputime_add(p->stime, cputime); /* Add system time to cpustat. */ Index: kvm/drivers/kvm/svm.c =================================================================== --- kvm.orig/drivers/kvm/svm.c 2007-08-13 14:31:16.000000000 +0200 +++ kvm/drivers/kvm/svm.c 2007-08-13 14:33:10.000000000 +0200 @@ -1392,6 +1392,7 @@ u16 gs_selector; u16 ldt_selector; int r; + ktime_t now, delta; again: r = kvm_mmu_reload(vcpu); @@ -1404,6 +1405,7 @@ clgi(); vcpu->guest_mode = 1; + now = ktime_get(); if (vcpu->requests) if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests)) svm_flush_tlb(vcpu); @@ -1536,6 +1538,8 @@ #endif : "cc", "memory" ); + delta = ktime_sub(ktime_get(), now); + current->vtime = ktime_add(current->vtime, delta); vcpu->guest_mode = 0; if (vcpu->fpu_active) {