All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: Metin Kaya <metikaya@amazon.com>
Subject: [PATCH kvm-unit-tests 12/13] x86: hyperv_stimer: add direct mode tests
Date: Wed,  6 Mar 2024 18:18:22 +0100	[thread overview]
Message-ID: <20240306171823.761647-13-vkuznets@redhat.com> (raw)
In-Reply-To: <20240306171823.761647-1-vkuznets@redhat.com>

All tests but stimer_test_one_shot_busy() are applicable, make them run in
both 'message' and 'direct' modes.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 x86/hyperv.h        |   7 +++
 x86/hyperv_stimer.c | 123 ++++++++++++++++++++++++++++++++++++++------
 x86/unittests.cfg   |   6 +++
 3 files changed, 121 insertions(+), 15 deletions(-)

diff --git a/x86/hyperv.h b/x86/hyperv.h
index 2fc70e561ef2..a1443842ed0b 100644
--- a/x86/hyperv.h
+++ b/x86/hyperv.h
@@ -10,6 +10,8 @@
 #define HV_X64_MSR_SYNIC_AVAILABLE              (1 << 2)
 #define HV_X64_MSR_SYNTIMER_AVAILABLE           (1 << 3)
 
+#define HV_STIMER_DIRECT_MODE_AVAILABLE		(1 << 19)
+
 #define HV_X64_MSR_GUEST_OS_ID                  0x40000000
 #define HV_X64_MSR_HYPERCALL                    0x40000001
 
@@ -205,6 +207,11 @@ static inline bool hv_stimer_supported(void)
     return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_SYNTIMER_AVAILABLE;
 }
 
+static inline bool stimer_direct_supported(void)
+{
+    return cpuid(HYPERV_CPUID_FEATURES).d & HV_STIMER_DIRECT_MODE_AVAILABLE;
+}
+
 static inline bool hv_time_ref_counter_supported(void)
 {
     return cpuid(HYPERV_CPUID_FEATURES).a & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
diff --git a/x86/hyperv_stimer.c b/x86/hyperv_stimer.c
index 0b9ec7a5b1b4..e50903b24820 100644
--- a/x86/hyperv_stimer.c
+++ b/x86/hyperv_stimer.c
@@ -16,6 +16,9 @@
 #define SINT1_VEC 0xF1
 #define SINT2_VEC 0xF2
 
+#define APIC_VEC1 0xF3
+#define APIC_VEC2 0xF4
+
 #define SINT1_NUM 2
 #define SINT2_NUM 3
 #define ONE_MS_IN_100NS 10000
@@ -25,6 +28,8 @@ static struct spinlock g_synic_alloc_lock;
 struct stimer {
     int sint;
     int index;
+    bool direct;
+    int apic_vec;
     atomic_t fire_count;
 };
 
@@ -81,8 +86,7 @@ static void stimer_shutdown(struct stimer *timer)
     wrmsr(HV_X64_MSR_STIMER0_CONFIG + 2*timer->index, 0);
 }
 
-static void process_stimer_expired(struct svcpu *svcpu, struct stimer *timer,
-                                   u64 expiration_time, u64 delivery_time)
+static void process_stimer_expired(struct stimer *timer)
 {
     atomic_inc(&timer->fire_count);
 }
@@ -119,8 +123,14 @@ static void process_stimer_msg(struct svcpu *svcpu,
         abort();
     }
     timer = &svcpu->timer[payload->timer_index];
-    process_stimer_expired(svcpu, timer, payload->expiration_time,
-                          payload->delivery_time);
+
+    if (timer->direct) {
+        report(false, "VMBus message in direct mode received");
+        report_summary();
+        abort();
+    }
+
+    process_stimer_expired(timer);
 
     msg->header.message_type = HVMSG_NONE;
     mb();
@@ -159,6 +169,32 @@ static void stimer_isr_auto_eoi(isr_regs_t *regs)
     __stimer_isr(vcpu);
 }
 
+static void __stimer_isr_direct(int vcpu, int timer_index)
+{
+    struct svcpu *svcpu = &g_synic_vcpu[vcpu];
+    struct stimer *timer = &svcpu->timer[timer_index];
+
+    process_stimer_expired(timer);
+}
+
+static void stimer_isr_direct1(isr_regs_t *regs)
+{
+    int vcpu = smp_id();
+
+    __stimer_isr_direct(vcpu, 0);
+
+    eoi();
+}
+
+static void stimer_isr_direct2(isr_regs_t *regs)
+{
+    int vcpu = smp_id();
+
+    __stimer_isr_direct(vcpu, 1);
+
+    eoi();
+}
+
 static void stimer_start(struct stimer *timer,
                          bool auto_enable, bool periodic,
                          u64 tick_100ns)
@@ -171,7 +207,12 @@ static void stimer_start(struct stimer *timer,
     config.periodic = periodic;
     config.enable = 1;
     config.auto_enable = auto_enable;
-    config.sintx = timer->sint;
+    if (!timer->direct) {
+        config.sintx = timer->sint;
+    } else {
+        config.direct_mode = 1;
+        config.apic_vector = timer->apic_vec;
+    }
 
     if (periodic) {
         count = tick_100ns;
@@ -229,6 +270,28 @@ static void stimer_test_prepare(void *ctx)
     timer2->sint = SINT2_NUM;
 }
 
+static void stimer_test_prepare_direct(void *ctx)
+{
+    int vcpu = smp_id();
+    struct svcpu *svcpu = &g_synic_vcpu[vcpu];
+    struct stimer *timer1, *timer2;
+
+    write_cr3((ulong)ctx);
+
+    timer1 = &svcpu->timer[0];
+    timer2 = &svcpu->timer[1];
+
+    stimer_init(timer1, 0);
+    stimer_init(timer2, 1);
+
+    timer1->apic_vec = APIC_VEC1;
+    timer2->apic_vec = APIC_VEC2;
+
+    timer1->direct = true;
+    timer2->direct = true;
+}
+
+
 static void stimer_test_periodic(int vcpu, struct stimer *timer1,
                                  struct stimer *timer2)
 {
@@ -279,8 +342,15 @@ static void stimer_test_auto_enable_periodic(int vcpu, struct stimer *timer)
 
 static void stimer_test_one_shot_busy(int vcpu, struct stimer *timer)
 {
-    struct hv_message_page *msg_page = g_synic_vcpu[vcpu].msg_page;
-    struct hv_message *msg = &msg_page->sint_message[timer->sint];
+    struct hv_message_page *msg_page;
+    struct hv_message *msg;
+
+    /* Skipping msg slot busy test in direct mode */
+    if (timer->direct)
+        return;
+
+    msg_page = g_synic_vcpu[vcpu].msg_page;
+    msg = &msg_page->sint_message[timer->sint];
 
     msg->header.message_type = HVMSG_TIMER_EXPIRED;
     wmb();
@@ -334,7 +404,12 @@ static void stimer_test_cleanup(void *ctx)
     synic_disable();
 }
 
-static void stimer_test_all(void)
+static void stimer_test_cleanup_direct(void *ctx)
+{
+    stimers_shutdown();
+}
+
+static void stimer_test_all(bool direct)
 {
     int ncpus;
 
@@ -346,16 +421,30 @@ static void stimer_test_all(void)
         report_abort("number cpus exceeds %d", MAX_CPUS);
     printf("cpus = %d\n", ncpus);
 
-    handle_irq(SINT1_VEC, stimer_isr);
-    handle_irq(SINT2_VEC, stimer_isr_auto_eoi);
+    if (!direct) {
+        printf("Starting Hyper-V SynIC timers tests: message mode\n");
 
-    on_cpus(stimer_test_prepare, (void *)read_cr3());
-    on_cpus(stimer_test, NULL);
-    on_cpus(stimer_test_cleanup, NULL);
+        handle_irq(SINT1_VEC, stimer_isr);
+        handle_irq(SINT2_VEC, stimer_isr_auto_eoi);
+
+	on_cpus(stimer_test_prepare, (void *)read_cr3());
+	on_cpus(stimer_test, NULL);
+	on_cpus(stimer_test_cleanup, NULL);
+    } else {
+        printf("Starting Hyper-V SynIC timers tests: direct mode\n");
+
+        handle_irq(APIC_VEC1, stimer_isr_direct1);
+        handle_irq(APIC_VEC2, stimer_isr_direct2);
+
+        on_cpus(stimer_test_prepare_direct, (void *)read_cr3());
+        on_cpus(stimer_test, NULL);
+        on_cpus(stimer_test_cleanup_direct, NULL);
+    }
 }
 
-int main(int ac, char **av)
+int main(int argc, char **argv)
 {
+    bool direct = argc >= 2 && !strcmp(argv[1], "direct");
 
     if (!hv_synic_supported()) {
         report_skip("Hyper-V SynIC is not supported");
@@ -372,7 +461,11 @@ int main(int ac, char **av)
         goto done;
     }
 
-    stimer_test_all();
+    if (direct && !stimer_direct_supported()) {
+	report_skip("Hyper-V SinIC timer direct mode is not supported");
+    }
+
+    stimer_test_all(direct);
 done:
     return report_summary();
 }
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index 06164ae22aa7..124be7a1f208 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -466,6 +466,12 @@ smp = 2
 extra_params = -cpu host,hv_passthrough
 groups = hyperv
 
+[hyperv_stimer_direct]
+file = hyperv_stimer.flat
+smp = 2
+extra_params = -cpu host,hv_passthrough -append direct
+groups = hyperv
+
 [hyperv_clock]
 file = hyperv_clock.flat
 smp = 2
-- 
2.44.0


  parent reply	other threads:[~2024-03-06 17:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-06 17:18 [PATCH kvm-unit-tests 00/13] x86: hyperv-v: Various unmerged patches Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 01/13] x86: hyperv: Use correct macro in checking SynIC timer support Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 02/13] x86: hyperv: improve naming of stimer functions Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 03/13] x86: hyperv_clock: handle non-consecutive APIC IDs Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 04/13] x86: hyperv_clock: print sequence field of reference TSC page Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 05/13] x86: hyper-v: Use '-cpu host,hv_passhtrough' for Hyper-V tests Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 06/13] x86: hyper-v: Use report_skip() in hyperv_stimer when pre-requisites are not met Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 07/13] x86: hyper-v: Use 'goto' instead of putting the whole test in an 'if' branch in hyperv_synic Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 08/13] x86: hyper-v: Unify hyperv_clock with other Hyper-V tests Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 09/13] x86: hyperv_stimer: keep SINT number parameter in 'struct stimer' Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 10/13] x86: hyperv_stimer: define union hv_stimer_config Vitaly Kuznetsov
2024-03-06 17:18 ` [PATCH kvm-unit-tests 11/13] x86: hyperv_stimer: don't require hyperv-testdev Vitaly Kuznetsov
2024-03-06 17:18 ` Vitaly Kuznetsov [this message]
2024-03-06 17:18 ` [PATCH kvm-unit-tests 13/13] x86: hyperv-v: Rewrite flaky hv_clock_test() Vitaly Kuznetsov

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=20240306171823.761647-13-vkuznets@redhat.com \
    --to=vkuznets@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=metikaya@amazon.com \
    --cc=pbonzini@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.