[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] x86/time: switch platform timer hooks to altcall



commit bed9ae54df44b9f6914eae4c6d231be41d859ecd
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Feb 25 10:48:20 2022 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Feb 25 10:48:20 2022 +0100

    x86/time: switch platform timer hooks to altcall
    
    Except in the "clocksource=tsc" case we can replace the indirect calls
    involved in accessing the platform timers by direct ones, as they get
    established once and never changed. To also cover the "tsc" case, invoke
    what read_tsc() resolves to directly. In turn read_tsc() then becomes
    unreachable and hence can move to .init.*.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/arch/x86/time.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index c005388e32..c05d3ca98b 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -66,6 +66,7 @@ struct platform_timesource {
     char *id;
     char *name;
     u64 frequency;
+    /* Post-init this hook may only be invoked via the read_counter() wrapper! 
*/
     u64 (*read_counter)(void);
     s64 (*init)(struct platform_timesource *);
     void (*resume)(struct platform_timesource *);
@@ -584,7 +585,7 @@ static s64 __init cf_check init_tsc(struct 
platform_timesource *pts)
     return ret;
 }
 
-static u64 cf_check read_tsc(void)
+static uint64_t __init cf_check read_tsc(void)
 {
     return rdtsc_ordered();
 }
@@ -816,6 +817,18 @@ static s_time_t __read_platform_stime(u64 platform_time)
     return (stime_platform_stamp + scale_delta(diff, &plt_scale));
 }
 
+static uint64_t read_counter(void)
+{
+    /*
+     * plt_tsc is put in use only after alternatives patching has occurred,
+     * hence we can't invoke read_tsc() that way. Special case it here, open-
+     * coding the function call at the same time.
+     */
+    return plt_src.read_counter != read_tsc
+           ? alternative_call(plt_src.read_counter)
+           : rdtsc_ordered();
+}
+
 static void cf_check plt_overflow(void *unused)
 {
     int i;
@@ -824,7 +837,7 @@ static void cf_check plt_overflow(void *unused)
 
     spin_lock_irq(&platform_timer_lock);
 
-    count = plt_src.read_counter();
+    count = read_counter();
     plt_stamp64 += (count - plt_stamp) & plt_mask;
     plt_stamp = count;
 
@@ -860,7 +873,7 @@ static s_time_t read_platform_stime(u64 *stamp)
     ASSERT(!local_irq_is_enabled());
 
     spin_lock(&platform_timer_lock);
-    plt_counter = plt_src.read_counter();
+    plt_counter = read_counter();
     count = plt_stamp64 + ((plt_counter - plt_stamp) & plt_mask);
     stime = __read_platform_stime(count);
     spin_unlock(&platform_timer_lock);
@@ -878,7 +891,7 @@ static void platform_time_calibration(void)
     unsigned long flags;
 
     spin_lock_irqsave(&platform_timer_lock, flags);
-    count = plt_stamp64 + ((plt_src.read_counter() - plt_stamp) & plt_mask);
+    count = plt_stamp64 + ((read_counter() - plt_stamp) & plt_mask);
     stamp = __read_platform_stime(count);
     stime_platform_stamp = stamp;
     platform_timer_stamp = count;
@@ -889,10 +902,10 @@ static void resume_platform_timer(void)
 {
     /* Timer source can be reset when backing from S3 to S0 */
     if ( plt_src.resume )
-        plt_src.resume(&plt_src);
+        alternative_vcall(plt_src.resume, &plt_src);
 
     plt_stamp64 = platform_timer_stamp;
-    plt_stamp = plt_src.read_counter();
+    plt_stamp = read_counter();
 }
 
 static void __init reset_platform_timer(void)
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.