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

[PATCH v2] x86/time: switch platform timer hooks to altcall


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 13 Jan 2022 14:17:18 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2/d3CTDxLjqoZ84Ou2Bee03DcAeFqL7eJTl+639eoTc=; b=bLt55/7rFIO2WpS44+JDeQC0TBki+ptYgixONOtPhLcvwd+IRF/yxuwkTmG1yDbRzYqsDc4/u9SIF8xMunJRwlSk3BSMOyTvKCnuy0QTwwjabiKdp1AGSiUDf7X/mzrh8L4M+A/wZLXfMwA5CT91ga87zPtgOc7IgZrTEjgBXt6rUDVFiI0SI9oafuu0IcwekYz0QSK3gzrUd8zrsX77XVdT4lw5JmGOTKlkC+uDwHL4LqbuVGbI4Qd9iEObH3JaWdD3SPAI0GQoHsxdS/RMPq7TRmSofv5bJyTvxNp8CmAhjfhBM5I8VR2+6wQj73BnJ1TOWUoDP2U1hJpInhMUmQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UaE+KpXWpw10Y1I1hHcYqdfrql0Aao0kWgZXqV8gz1Oe3GEaYogDqYaSgJWgU0zrtNnIgIFNioiDI55FqwOR/AanMCJutu856Mh+zd95KIMG8Wpxf00sOEMi1y3p/y5oz56qeCr3ta9xStJX+Q0gfxcbRgHLJFRNAr+vrZUI9L5BrHPFSQteAaOqtUwuRmDipbeZlJjocPUDKLTsnWpE5/rDE1UAcWmwgJoixECVAOYlszp/eC/uWhMM4nQ690R44gy+rrPdH9rbQYleFzrG9UhHtlv3BKEnFdMKkI8FswL2TEd+vWPoRw8yTFVIZ3PQaowm59t2tulvflPboYm6jQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Thu, 13 Jan 2022 13:17:43 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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>
---
TBD: Instead of adding __init to read_tsc() we could also ditch the
     function altogether, using a dedicated (non-canonical) pointer
     constant instead for the .read_counter initializer and the two
     comparisons done on plt_src.read_counter.
---
v2: Avoid altcall patching becoming conditional.

--- 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;
+    /* 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 *);
@@ -578,7 +579,7 @@ static s64 __init init_tsc(struct platfo
     return ret;
 }
 
-static u64 read_tsc(void)
+static uint64_t __init read_tsc(void)
 {
     return rdtsc_ordered();
 }
@@ -810,6 +811,18 @@ static s_time_t __read_platform_stime(u6
     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 plt_overflow(void *unused)
 {
     int i;
@@ -818,7 +831,7 @@ static void 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;
 
@@ -854,7 +867,7 @@ static s_time_t read_platform_stime(u64
     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);
@@ -872,7 +885,7 @@ static void platform_time_calibration(vo
     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;
@@ -883,10 +896,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)




 


Rackspace

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