From: Maxim Levitsky <mlevitsk@redhat.com>
To: isaku.yamahata@intel.com, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: isaku.yamahata@gmail.com, Paolo Bonzini <pbonzini@redhat.com>,
erdemaktas@google.com, Sean Christopherson <seanjc@google.com>,
Vishal Annapurve <vannapurve@google.com>,
Jim Mattson <jmattson@google.com>
Subject: Re: [PATCH v2 3/3] KVM: selftests: Add test case for x86 apic_bus_clock_frequency
Date: Thu, 14 Dec 2023 00:41:13 +0200 [thread overview]
Message-ID: <e837b1964e5615e5a1e5a0113889b507a3d4970d.camel@redhat.com> (raw)
In-Reply-To: <232d64219c6df684f99f9072d41e8783f1a4fe46.1699936040.git.isaku.yamahata@intel.com>
On Mon, 2023-11-13 at 20:35 -0800, isaku.yamahata@intel.com wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
>
> Test if the apic bus clock frequency is exptected to the configured value.
> Set APIC TMICT to the maximum value and busy wait for 100 msec (any value
> is okay) with tsc value, and read TMCCT. Calculate apic bus clock frequency
> based on TSC frequency.
>
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> ---
> Changes v2:
> - Newly added
> ---
> tools/testing/selftests/kvm/Makefile | 1 +
> .../selftests/kvm/include/x86_64/apic.h | 7 +
> .../kvm/x86_64/apic_bus_clock_test.c | 132 ++++++++++++++++++
> 3 files changed, 140 insertions(+)
> create mode 100644 tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c
>
> diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
> index a5963ab9215b..74ed3f71b6e8 100644
> --- a/tools/testing/selftests/kvm/Makefile
> +++ b/tools/testing/selftests/kvm/Makefile
> @@ -115,6 +115,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_invalid_nested_guest_state
> TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test
> TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test
> TEST_GEN_PROGS_x86_64 += x86_64/vmx_nested_tsc_scaling_test
> +TEST_GEN_PROGS_x86_64 += x86_64/apic_bus_clock_test
> TEST_GEN_PROGS_x86_64 += x86_64/xapic_ipi_test
> TEST_GEN_PROGS_x86_64 += x86_64/xapic_state_test
> TEST_GEN_PROGS_x86_64 += x86_64/xcr0_cpuid_test
> diff --git a/tools/testing/selftests/kvm/include/x86_64/apic.h b/tools/testing/selftests/kvm/include/x86_64/apic.h
> index bed316fdecd5..866a58d5fa11 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/apic.h
> +++ b/tools/testing/selftests/kvm/include/x86_64/apic.h
> @@ -60,6 +60,13 @@
> #define APIC_VECTOR_MASK 0x000FF
> #define APIC_ICR2 0x310
> #define SET_APIC_DEST_FIELD(x) ((x) << 24)
> +#define APIC_LVT0 0x350
> +#define APIC_LVT_TIMER_ONESHOT (0 << 17)
> +#define APIC_LVT_TIMER_PERIODIC (1 << 17)
> +#define APIC_LVT_TIMER_TSCDEADLINE (2 << 17)
> +#define APIC_TMICT 0x380
> +#define APIC_TMCCT 0x390
> +#define APIC_TDCR 0x3E0
>
> void apic_disable(void);
> void xapic_enable(void);
> diff --git a/tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c b/tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c
> new file mode 100644
> index 000000000000..91f558d7c624
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/x86_64/apic_bus_clock_test.c
> @@ -0,0 +1,132 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#define _GNU_SOURCE /* for program_invocation_short_name */
> +
> +#include "apic.h"
> +#include "test_util.h"
> +
> +/* Pick one convenient value, 1Ghz. No special meaning. */
Tiny nitpick: to be 100% honest, 1Ghz does have a special meaning, it's the default APIC bus frequency.
It might be slightly better to use say 1.5Ghz or something like that.
> +#define TSC_HZ (1 * 1000 * 1000 * 1000ULL)
> +
> +/* Wait for 100 msec, not too long, not too short value. */
> +#define LOOP_MSEC 100ULL
> +#define TSC_WAIT_DELTA (TSC_HZ / 1000 * LOOP_MSEC)
> +
> +/* Pick up typical value. Different enough from the default value, 1GHz. */
> +#define APIC_BUS_CLOCK_FREQ (25 * 1000 * 1000ULL)
> +
> +static void guest_code(void)
> +{
> + /* Possible tdcr values and its divide count. */
> + struct {
> + u32 tdcr;
> + u32 divide_count;
> + } tdcrs[] = {
> + {0x0, 2},
> + {0x1, 4},
> + {0x2, 8},
> + {0x3, 16},
> + {0x8, 32},
> + {0x9, 64},
> + {0xa, 128},
> + {0xb, 1},
> + };
> +
> + u32 tmict, tmcct;
> + u64 tsc0, tsc1;
> + int i;
> +
> + asm volatile("cli");
> +
> + xapic_enable();
> +
> + /*
> + * Setup one-shot timer. Because we don't fire the interrupt, the
> + * vector doesn't matter.
> + */
> + xapic_write_reg(APIC_LVT0, APIC_LVT_TIMER_ONESHOT);
> +
> + for (i = 0; i < ARRAY_SIZE(tdcrs); i++) {
> + xapic_write_reg(APIC_TDCR, tdcrs[i].tdcr);
> +
> + /* Set the largest value to not trigger the interrupt. */
> + tmict = ~0;
> + xapic_write_reg(APIC_TMICT, tmict);
> +
> + /* Busy wait for LOOP_MSEC */
> + tsc0 = rdtsc();
> + tsc1 = tsc0;
> + while (tsc1 - tsc0 < TSC_WAIT_DELTA)
> + tsc1 = rdtsc();
> +
> + /* Read apic timer and tsc */
> + tmcct = xapic_read_reg(APIC_TMCCT);
> + tsc1 = rdtsc();
> +
> + /* Stop timer */
> + xapic_write_reg(APIC_TMICT, 0);
> +
> + /* Report it. */
> + GUEST_SYNC_ARGS(tdcrs[i].divide_count, tmict - tmcct,
> + tsc1 - tsc0, 0, 0);
> + }
> +
> + GUEST_DONE();
> +}
> +
> +void test_apic_bus_clock(struct kvm_vcpu *vcpu)
> +{
> + bool done = false;
> + struct ucall uc;
> +
> + while (!done) {
> + vcpu_run(vcpu);
> + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
> +
> + switch (get_ucall(vcpu, &uc)) {
> + case UCALL_DONE:
> + done = true;
> + break;
> + case UCALL_ABORT:
> + REPORT_GUEST_ASSERT(uc);
> + break;
> + case UCALL_SYNC: {
> + u32 divide_counter = uc.args[1];
> + u32 apic_cycles = uc.args[2];
> + u64 tsc_cycles = uc.args[3];
> + u64 freq;
> +
> + TEST_ASSERT(tsc_cycles > 0,
> + "tsc cycles must not be zero.");
> +
> + /* Allow 1% slack. */
> + freq = apic_cycles * divide_counter * TSC_HZ / tsc_cycles;
> + TEST_ASSERT(freq < APIC_BUS_CLOCK_FREQ * 101 / 100,
> + "APIC bus clock frequency is too large");
> + TEST_ASSERT(freq > APIC_BUS_CLOCK_FREQ * 99 / 100,
> + "APIC bus clock frequency is too small");
> + break;
> + }
> + default:
> + TEST_FAIL("Unknown ucall %lu", uc.cmd);
> + break;
> + }
> + }
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + struct kvm_vm *vm;
> + struct kvm_vcpu *vcpu;
> +
> + vm = __vm_create(VM_MODE_DEFAULT, 1, 0);
> + vm_ioctl(vm, KVM_SET_TSC_KHZ, (void *) (TSC_HZ / 1000));
> + /* KVM_CAP_X86_BUS_FREQUENCY_CONTROL requires that no vcpu is created. */
> + vm_enable_cap(vm, KVM_CAP_X86_BUS_FREQUENCY_CONTROL,
> + APIC_BUS_CLOCK_FREQ);
> + vcpu = vm_vcpu_add(vm, 0, guest_code);
> +
> + virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA);
> +
> + test_apic_bus_clock(vcpu);
> + kvm_vm_free(vm);
> +}
Looks good overall.
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Best regards,
Maxim Levitsky
prev parent reply other threads:[~2023-12-13 22:41 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-14 4:35 [PATCH v2 0/3] KVM: X86: Make bus clock frequency for vapic timer configurable isaku.yamahata
2023-11-14 4:35 ` [PATCH v2 1/3] KVM: x86: Make the hardcoded APIC bus frequency vm variable isaku.yamahata
2023-12-13 22:39 ` Maxim Levitsky
2023-12-13 23:10 ` Sean Christopherson
2023-12-13 23:18 ` Jim Mattson
2023-12-14 9:31 ` Maxim Levitsky
2023-12-14 16:41 ` Sean Christopherson
2023-12-19 1:40 ` Isaku Yamahata
2023-12-19 3:53 ` Jim Mattson
2023-12-19 7:56 ` Xiaoyao Li
2023-12-19 8:11 ` Isaku Yamahata
2023-12-20 22:07 ` Sean Christopherson
2023-12-20 22:22 ` Jim Mattson
2023-12-21 5:44 ` Xiaoyao Li
2023-12-21 14:39 ` Jim Mattson
2023-12-21 17:01 ` Maxim Levitsky
2023-11-14 4:35 ` [PATCH v2 2/3] KVM: X86: Add a capability to configure bus frequency for APIC timer isaku.yamahata
2023-12-13 22:40 ` Maxim Levitsky
2023-11-14 4:35 ` [PATCH v2 3/3] KVM: selftests: Add test case for x86 apic_bus_clock_frequency isaku.yamahata
2023-12-13 22:41 ` Maxim Levitsky [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e837b1964e5615e5a1e5a0113889b507a3d4970d.camel@redhat.com \
--to=mlevitsk@redhat.com \
--cc=erdemaktas@google.com \
--cc=isaku.yamahata@gmail.com \
--cc=isaku.yamahata@intel.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=vannapurve@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®