]> xenbits.xensource.com Git - people/andrewcoop/xen.git/commitdiff
x86/HVM: improve CET-IBT pruning of ENDBR
authorJan Beulich <jbeulich@suse.com>
Thu, 6 Mar 2025 12:56:21 +0000 (13:56 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 6 Mar 2025 12:56:21 +0000 (13:56 +0100)
__init{const,data}_cf_clobber can have an effect only for pointers
actually populated in the respective tables. While not the case for SVM
right now, VMX installs a number of pointers only under certain
conditions. Hence the respective functions would have their ENDBR purged
only when those conditions are met. Invoke "pruning" functions after
having copied the respective tables, for them to install any "missing"
pointers.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/include/asm/hvm/hvm.h

index 969e43c2f216f8a9da74a2385007019148303bd7..2f31180b6fcaeab61cdc1f730903de220300090e 100644 (file)
@@ -160,10 +160,17 @@ static int __init cf_check hvm_enable(void)
     else if ( using_svm() )
         fns = start_svm();
 
+    if ( fns )
+        hvm_funcs = *fns;
+
+    if ( IS_ENABLED(CONFIG_INTEL_VMX) )
+        vmx_fill_funcs();
+    if ( IS_ENABLED(CONFIG_AMD_SVM) )
+        svm_fill_funcs();
+
     if ( fns == NULL )
         return 0;
 
-    hvm_funcs = *fns;
     hvm_enabled = 1;
 
     printk("HVM: %s enabled\n", fns->name);
index ea78da4f42105a5b3fba8e8cf7e493752408db7b..42128e33ceb351733ea3373ddee1c21e90b16920 100644 (file)
@@ -2531,6 +2531,19 @@ const struct hvm_function_table * __init start_svm(void)
     return &svm_function_table;
 }
 
+void __init svm_fill_funcs(void)
+{
+    /*
+     * Now that svm_function_table was copied, populate all function pointers
+     * which may have been left at NULL, for __initdata_cf_clobber to have as
+     * much of an effect as possible.
+     */
+    if ( !cpu_has_xen_ibt )
+        return;
+
+    /* Nothing at present. */
+}
+
 void asmlinkage svm_vmexit_handler(void)
 {
     struct cpu_user_regs *regs = guest_cpu_user_regs();
index d87da427ade17ba1ee3639a51f162c10cb2b351f..1911e79517a8f44418b843991a9fc74e6b8f52d1 100644 (file)
@@ -3064,6 +3064,30 @@ const struct hvm_function_table * __init start_vmx(void)
     return &vmx_function_table;
 }
 
+void __init vmx_fill_funcs(void)
+{
+    /*
+     * Now that vmx_function_table was copied, populate all function pointers
+     * which may have been left at NULL, for __initdata_cf_clobber to have as
+     * much of an effect as possible.
+     */
+    if ( !cpu_has_xen_ibt )
+        return;
+
+    vmx_function_table.set_descriptor_access_exiting =
+        vmx_set_descriptor_access_exiting;
+
+    vmx_function_table.update_eoi_exit_bitmap = vmx_update_eoi_exit_bitmap;
+    vmx_function_table.process_isr            = vmx_process_isr;
+    vmx_function_table.handle_eoi             = vmx_handle_eoi;
+
+    vmx_function_table.pi_update_irte = vmx_pi_update_irte;
+
+    vmx_function_table.deliver_posted_intr = vmx_deliver_posted_intr;
+    vmx_function_table.sync_pir_to_irr     = vmx_sync_pir_to_irr;
+    vmx_function_table.test_pir            = vmx_test_pir;
+}
+
 /*
  * Not all cases receive valid value in the VM-exit instruction length field.
  * Callers must know what they're doing!
index cad3a9427801a292b4eb8f6317ad7122563be1d2..963e8201130a9c822299d1762916e4b7d414d6b4 100644 (file)
@@ -260,6 +260,9 @@ extern int8_t hvm_port80_allowed;
 extern const struct hvm_function_table *start_svm(void);
 extern const struct hvm_function_table *start_vmx(void);
 
+void svm_fill_funcs(void);
+void vmx_fill_funcs(void);
+
 int hvm_domain_initialise(struct domain *d,
                           const struct xen_domctl_createdomain *config);
 void hvm_domain_relinquish_resources(struct domain *d);