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

[xen staging] xen/version: Calculate xen_capabilities_info once at boot



commit 7cf44c61c531274185966a89684ab822c8d6f555
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Jan 13 17:20:41 2023 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Dec 20 22:44:42 2024 +0000

    xen/version: Calculate xen_capabilities_info once at boot
    
    The arch_get_xen_caps() infrastructure is horribly inefficient for something
    that is constant after features have been resolved on boot.
    
    Every instance used snprintf() to format constants into a string (which gets
    shorter when %d gets resolved!), and which get double buffered on the stack.
    
    Switch to using string literals with the "3.0" inserted - these numbers
    haven't changed in 19 years; the Xen 3.0 release was Dec 5th 2005.
    
    Use initcalls to format the data into xen_cap_info, which is deliberately 
not
    of type xen_capabilities_info_t because a 1k array is a silly overhead for
    storing a maximum of 77 chars (the x86 version) and isn't liable to need any
    more space in the forseeable future.  RISC-V and PPC have their stub 
dropped,
    with the expectation that they won't carry this legacy interface forward.
    
    This speeds up the the XENVER_capabilities hypercall, but the purpose of the
    change is to allow us to introduce a better XENVER_* API that doesn't force
    the use of a 1k buffer on the stack.
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/arm/setup.c        | 18 +++++++-----------
 xen/arch/ppc/setup.c        |  5 -----
 xen/arch/riscv/setup.c      |  5 -----
 xen/arch/x86/setup.c        | 29 ++++++++++-------------------
 xen/common/kernel.c         |  3 ++-
 xen/include/xen/hypercall.h |  2 --
 xen/include/xen/version.h   |  2 ++
 7 files changed, 21 insertions(+), 43 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 68c1f30920..c1f2d1b89d 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -28,6 +28,7 @@
 #include <xen/cpu.h>
 #include <xen/pfn.h>
 #include <xen/virtual_region.h>
+#include <xen/version.h>
 #include <xen/vmap.h>
 #include <xen/trace.h>
 #include <xen/libfdt/libfdt-xen.h>
@@ -513,24 +514,19 @@ void asmlinkage __init start_xen(unsigned long fdt_paddr)
     switch_stack_and_jump(idle_vcpu[0]->arch.cpu_info, init_done);
 }
 
-void arch_get_xen_caps(xen_capabilities_info_t *info)
+static int __init init_xen_cap_info(void)
 {
     /* Interface name is always xen-3.0-* for Xen-3.x. */
-    int major = 3, minor = 0;
-    char s[32];
-
-    (*info)[0] = '\0';
 
 #ifdef CONFIG_ARM_64
-    snprintf(s, sizeof(s), "xen-%d.%d-aarch64 ", major, minor);
-    safe_strcat(*info, s);
+    safe_strcat(xen_cap_info, "xen-3.0-aarch64 ");
 #endif
     if ( cpu_has_aarch32 )
-    {
-        snprintf(s, sizeof(s), "xen-%d.%d-armv7l ", major, minor);
-        safe_strcat(*info, s);
-    }
+        safe_strcat(xen_cap_info, "xen-3.0-armv7l ");
+
+    return 0;
 }
+__initcall(init_xen_cap_info);
 
 /*
  * Local variables:
diff --git a/xen/arch/ppc/setup.c b/xen/arch/ppc/setup.c
index 5fb5ab64e3..9c1e4791af 100644
--- a/xen/arch/ppc/setup.c
+++ b/xen/arch/ppc/setup.c
@@ -47,8 +47,3 @@ void __init noreturn start_xen(unsigned long r3, unsigned 
long r4,
 
     machine_halt();
 }
-
-void arch_get_xen_caps(xen_capabilities_info_t *info)
-{
-    BUG_ON("unimplemented");
-}
diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index fb6bbba684..38ca4f3baa 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -20,11 +20,6 @@
 #include <asm/smp.h>
 #include <asm/traps.h>
 
-void arch_get_xen_caps(xen_capabilities_info_t *info)
-{
-    BUG_ON("unimplemented");
-}
-
 /* Xen stack for bringing up the first CPU. */
 unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
     __aligned(STACK_SIZE);
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 397347bea4..8ebe5a9443 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -2165,35 +2165,26 @@ void asmlinkage __init noreturn __start_xen(void)
     unreachable();
 }
 
-void arch_get_xen_caps(xen_capabilities_info_t *info)
+static int __init cf_check init_xen_cap_info(void)
 {
     /* Interface name is always xen-3.0-* for Xen-3.x. */
-    int major = 3, minor = 0;
-    char s[32];
-
-    (*info)[0] = '\0';
 
     if ( IS_ENABLED(CONFIG_PV) )
     {
-        snprintf(s, sizeof(s), "xen-%d.%d-x86_64 ", major, minor);
-        safe_strcat(*info, s);
+        safe_strcat(xen_cap_info, "xen-3.0-x86_64 ");
 
         if ( opt_pv32 )
-        {
-            snprintf(s, sizeof(s), "xen-%d.%d-x86_32p ", major, minor);
-            safe_strcat(*info, s);
-        }
+            safe_strcat(xen_cap_info, "xen-3.0-x86_32p ");
     }
     if ( hvm_enabled )
-    {
-        snprintf(s, sizeof(s), "hvm-%d.%d-x86_32 ", major, minor);
-        safe_strcat(*info, s);
-        snprintf(s, sizeof(s), "hvm-%d.%d-x86_32p ", major, minor);
-        safe_strcat(*info, s);
-        snprintf(s, sizeof(s), "hvm-%d.%d-x86_64 ", major, minor);
-        safe_strcat(*info, s);
-    }
+        safe_strcat(xen_cap_info,
+                    "hvm-3.0-x86_32 "
+                    "hvm-3.0-x86_32p "
+                    "hvm-3.0-x86_64 ");
+
+    return 0;
 }
+__initcall(init_xen_cap_info);
 
 int __hwdom_init remove_xen_ranges(struct rangeset *r)
 {
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index b44b2439ca..d30ab56f57 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -35,6 +35,7 @@ boolean_param("dit", opt_dit);
 
 static xen_commandline_t saved_cmdline;
 static const char __initconst opt_builtin_cmdline[] = CONFIG_CMDLINE;
+char __ro_after_init xen_cap_info[128];
 
 static int assign_integer_param(const struct kernel_param *param, uint64_t val)
 {
@@ -542,7 +543,7 @@ long do_xen_version(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
 
         memset(info, 0, sizeof(info));
         if ( !deny )
-            arch_get_xen_caps(&info);
+            safe_strcpy(info, xen_cap_info);
 
         if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
             return -EFAULT;
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index f307dfb597..15b6be6ec8 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -56,6 +56,4 @@ common_vcpu_op(int cmd,
     struct vcpu *v,
     XEN_GUEST_HANDLE_PARAM(void) arg);
 
-void arch_get_xen_caps(xen_capabilities_info_t *info);
-
 #endif /* __XEN_HYPERCALL_H__ */
diff --git a/xen/include/xen/version.h b/xen/include/xen/version.h
index 93c5877363..4856ad1b44 100644
--- a/xen/include/xen/version.h
+++ b/xen/include/xen/version.h
@@ -19,6 +19,8 @@ const char *xen_deny(void);
 const char *xen_build_info(void);
 int xen_build_id(const void **p, unsigned int *len);
 
+extern char xen_cap_info[128];
+
 #ifdef BUILD_ID
 void xen_build_init(void);
 int xen_build_id_check(const Elf_Note *n, unsigned int n_sz,
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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