diff mbox

[2/6] kvm: x86: drop read_tsc_offset()

Message ID 1474036056-21270-3-git-send-email-lcapitulino@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Luiz Capitulino Sept. 16, 2016, 2:27 p.m. UTC
The TSC offset can now be read directly from struct kvm_arch_vcpu.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 arch/x86/include/asm/kvm_host.h | 1 -
 arch/x86/kvm/svm.c              | 8 --------
 arch/x86/kvm/vmx.c              | 6 ------
 arch/x86/kvm/x86.c              | 2 +-
 4 files changed, 1 insertion(+), 16 deletions(-)

Comments

Jim Mattson Sept. 19, 2016, 3:30 p.m. UTC | #1
vmx_read_tsc_offset has a bug when running nested VMs.  It should really be:

       if (is_guest_mode(vcpu))
               return to_vmx(vcpu)->nested.vmcs01_tsc_offset;
       else
               return vmcs_read64(TSC_OFFSET);

Perhaps a better name woulf be "vmx_get_l1_tsc_offset."

In any case, this does not seem consistent with vcpu->arch.tsc_offset.

On Fri, Sep 16, 2016 at 7:27 AM, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> The TSC offset can now be read directly from struct kvm_arch_vcpu.
>
> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> ---
>  arch/x86/include/asm/kvm_host.h | 1 -
>  arch/x86/kvm/svm.c              | 8 --------
>  arch/x86/kvm/vmx.c              | 6 ------
>  arch/x86/kvm/x86.c              | 2 +-
>  4 files changed, 1 insertion(+), 16 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 9b36a31..c4c5ac5 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -954,7 +954,6 @@ struct kvm_x86_ops {
>
>         bool (*has_wbinvd_exit)(void);
>
> -       u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
>         void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
>
>         u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu, u64 host_tsc);
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index db77c1c..8023d53 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -1119,13 +1119,6 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
>         seg->base = 0;
>  }
>
> -static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
> -{
> -       struct vcpu_svm *svm = to_svm(vcpu);
> -
> -       return svm->vmcb->control.tsc_offset;
> -}
> -
>  static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
>  {
>         struct vcpu_svm *svm = to_svm(vcpu);
> @@ -5427,7 +5420,6 @@ static struct kvm_x86_ops svm_x86_ops = {
>
>         .has_wbinvd_exit = svm_has_wbinvd_exit,
>
> -       .read_tsc_offset = svm_read_tsc_offset,
>         .write_tsc_offset = svm_write_tsc_offset,
>         .adjust_tsc_offset_guest = svm_adjust_tsc_offset_guest,
>         .read_l1_tsc = svm_read_l1_tsc,
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 5cede40..29cbd4b 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2603,11 +2603,6 @@ static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
>         return host_tsc + tsc_offset;
>  }
>
> -static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
> -{
> -       return vmcs_read64(TSC_OFFSET);
> -}
> -
>  /*
>   * writes 'offset' into guest's timestamp counter offset register
>   */
> @@ -11274,7 +11269,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
>
>         .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
>
> -       .read_tsc_offset = vmx_read_tsc_offset,
>         .write_tsc_offset = vmx_write_tsc_offset,
>         .adjust_tsc_offset_guest = vmx_adjust_tsc_offset_guest,
>         .read_l1_tsc = vmx_read_l1_tsc,
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index cda4ca5..1651668 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -1367,7 +1367,7 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
>
>  static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
>  {
> -       u64 curr_offset = kvm_x86_ops->read_tsc_offset(vcpu);
> +       u64 curr_offset = vcpu->arch.tsc_offset;
>         vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
>  }
>
> --
> 2.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 19, 2016, 3:34 p.m. UTC | #2
On 19/09/2016 17:30, Jim Mattson wrote:
> vmx_read_tsc_offset has a bug when running nested VMs.  It should really be:
> 
>        if (is_guest_mode(vcpu))
>                return to_vmx(vcpu)->nested.vmcs01_tsc_offset;
>        else
>                return vmcs_read64(TSC_OFFSET);
> 
> Perhaps a better name woulf be "vmx_get_l1_tsc_offset."

I agree, but doesn't this patch fix the bug too?

Paolo

> In any case, this does not seem consistent with vcpu->arch.tsc_offset.
Jim Mattson Sept. 19, 2016, 10:18 p.m. UTC | #3
Hmmm. Yes, I think it does. With this patch series,
vcpu->arch.tsc_offset appears to contain L1's TSC offset (perhaps
making vmx->nested.vmcs01_tsc_offset redundant).

However, this unfortunately limits the newly added functionality to
merging host and *L1* guest traces. It doesn't work with L2 (or
deeper) guests. Or perhaps I'm missing something?

On Mon, Sep 19, 2016 at 8:34 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 19/09/2016 17:30, Jim Mattson wrote:
>> vmx_read_tsc_offset has a bug when running nested VMs.  It should really be:
>>
>>        if (is_guest_mode(vcpu))
>>                return to_vmx(vcpu)->nested.vmcs01_tsc_offset;
>>        else
>>                return vmcs_read64(TSC_OFFSET);
>>
>> Perhaps a better name woulf be "vmx_get_l1_tsc_offset."
>
> I agree, but doesn't this patch fix the bug too?
>
> Paolo
>
>> In any case, this does not seem consistent with vcpu->arch.tsc_offset.
>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 20, 2016, 5:37 a.m. UTC | #4
On 20/09/2016 00:18, Jim Mattson wrote:
> Hmmm. Yes, I think it does. With this patch series,
> vcpu->arch.tsc_offset appears to contain L1's TSC offset (perhaps
> making vmx->nested.vmcs01_tsc_offset redundant).
> 
> However, this unfortunately limits the newly added functionality to
> merging host and *L1* guest traces. It doesn't work with L2 (or
> deeper) guests. Or perhaps I'm missing something?

You can merge L1/L2 first and then host/L1.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jim Mattson Sept. 21, 2016, 3:19 p.m. UTC | #5
Doesn't that assume you can run the merge program in L1?

On Mon, Sep 19, 2016 at 10:37 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 20/09/2016 00:18, Jim Mattson wrote:
>> Hmmm. Yes, I think it does. With this patch series,
>> vcpu->arch.tsc_offset appears to contain L1's TSC offset (perhaps
>> making vmx->nested.vmcs01_tsc_offset redundant).
>>
>> However, this unfortunately limits the newly added functionality to
>> merging host and *L1* guest traces. It doesn't work with L2 (or
>> deeper) guests. Or perhaps I'm missing something?
>
> You can merge L1/L2 first and then host/L1.
>
> Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 21, 2016, 3:22 p.m. UTC | #6
On 21/09/2016 17:19, Jim Mattson wrote:
> Doesn't that assume you can run the merge program in L1?

You only need the TSC offset, but we should make sure that L0
tracepoints contain enough information to figure out the L0->L2 TSC
offsets (they are the values in VMCS02).

That said, how would you get the trace from L1 if you don't have access
to it?

Paolo

> On Mon, Sep 19, 2016 at 10:37 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>>
>> On 20/09/2016 00:18, Jim Mattson wrote:
>>> Hmmm. Yes, I think it does. With this patch series,
>>> vcpu->arch.tsc_offset appears to contain L1's TSC offset (perhaps
>>> making vmx->nested.vmcs01_tsc_offset redundant).
>>>
>>> However, this unfortunately limits the newly added functionality to
>>> merging host and *L1* guest traces. It doesn't work with L2 (or
>>> deeper) guests. Or perhaps I'm missing something?
>>
>> You can merge L1/L2 first and then host/L1.
>>
>> Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jim Mattson Sept. 21, 2016, 3:31 p.m. UTC | #7
I'm thinking about the case where you want to merge traces from L0 and
L2. If the user code in L0 always knew the TSC offset of the current
VMCS, rather than the TSC offset of the L1 VMCS, this would be
trivial, regardless of the nature of L1.

On Wed, Sep 21, 2016 at 8:22 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 21/09/2016 17:19, Jim Mattson wrote:
>> Doesn't that assume you can run the merge program in L1?
>
> You only need the TSC offset, but we should make sure that L0
> tracepoints contain enough information to figure out the L0->L2 TSC
> offsets (they are the values in VMCS02).
>
> That said, how would you get the trace from L1 if you don't have access
> to it?
>
> Paolo
>
>> On Mon, Sep 19, 2016 at 10:37 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>>
>>>
>>> On 20/09/2016 00:18, Jim Mattson wrote:
>>>> Hmmm. Yes, I think it does. With this patch series,
>>>> vcpu->arch.tsc_offset appears to contain L1's TSC offset (perhaps
>>>> making vmx->nested.vmcs01_tsc_offset redundant).
>>>>
>>>> However, this unfortunately limits the newly added functionality to
>>>> merging host and *L1* guest traces. It doesn't work with L2 (or
>>>> deeper) guests. Or perhaps I'm missing something?
>>>
>>> You can merge L1/L2 first and then host/L1.
>>>
>>> Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9b36a31..c4c5ac5 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -954,7 +954,6 @@  struct kvm_x86_ops {
 
 	bool (*has_wbinvd_exit)(void);
 
-	u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
 	void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
 	u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu, u64 host_tsc);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index db77c1c..8023d53 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1119,13 +1119,6 @@  static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
 	seg->base = 0;
 }
 
-static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
-{
-	struct vcpu_svm *svm = to_svm(vcpu);
-
-	return svm->vmcb->control.tsc_offset;
-}
-
 static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -5427,7 +5420,6 @@  static struct kvm_x86_ops svm_x86_ops = {
 
 	.has_wbinvd_exit = svm_has_wbinvd_exit,
 
-	.read_tsc_offset = svm_read_tsc_offset,
 	.write_tsc_offset = svm_write_tsc_offset,
 	.adjust_tsc_offset_guest = svm_adjust_tsc_offset_guest,
 	.read_l1_tsc = svm_read_l1_tsc,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 5cede40..29cbd4b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2603,11 +2603,6 @@  static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
 	return host_tsc + tsc_offset;
 }
 
-static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
-{
-	return vmcs_read64(TSC_OFFSET);
-}
-
 /*
  * writes 'offset' into guest's timestamp counter offset register
  */
@@ -11274,7 +11269,6 @@  static struct kvm_x86_ops vmx_x86_ops = {
 
 	.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
-	.read_tsc_offset = vmx_read_tsc_offset,
 	.write_tsc_offset = vmx_write_tsc_offset,
 	.adjust_tsc_offset_guest = vmx_adjust_tsc_offset_guest,
 	.read_l1_tsc = vmx_read_l1_tsc,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cda4ca5..1651668 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1367,7 +1367,7 @@  static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
 
 static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
 {
-	u64 curr_offset = kvm_x86_ops->read_tsc_offset(vcpu);
+	u64 curr_offset = vcpu->arch.tsc_offset;
 	vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
 }