kvm/x86: Hyper-V HV_X64_MSR_VP_RUNTIME support
[deliverable/linux.git] / arch / x86 / kvm / hyperv.c
index 0ad11a2324749ce44563da44bae9f72b0daee9a0..62cf8c915e95df1577d1d226bae9dc04f51b52e3 100644 (file)
@@ -178,7 +178,16 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
        return 0;
 }
 
-static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+/* Calculate cpu time spent by current task in 100ns units */
+static u64 current_task_runtime_100ns(void)
+{
+       cputime_t utime, stime;
+
+       task_cputime_adjusted(current, &utime, &stime);
+       return div_u64(cputime_to_nsecs(utime + stime), 100);
+}
+
+static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
 {
        struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
 
@@ -212,6 +221,11 @@ static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
        case HV_X64_MSR_TPR:
                return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
+       case HV_X64_MSR_VP_RUNTIME:
+               if (!host)
+                       return 1;
+               hv->runtime_offset = data - current_task_runtime_100ns();
+               break;
        default:
                vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
                            msr, data);
@@ -287,6 +301,9 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
        case HV_X64_MSR_APIC_ASSIST_PAGE:
                data = hv->hv_vapic;
                break;
+       case HV_X64_MSR_VP_RUNTIME:
+               data = current_task_runtime_100ns() + hv->runtime_offset;
+               break;
        default:
                vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
                return 1;
@@ -305,7 +322,7 @@ int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
                mutex_unlock(&vcpu->kvm->lock);
                return r;
        } else
-               return kvm_hv_set_msr(vcpu, msr, data);
+               return kvm_hv_set_msr(vcpu, msr, data, host);
 }
 
 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
This page took 0.028356 seconds and 5 git commands to generate.