Subject: platform-op/XSM: move resource-{,un}plug-core checks
From: Jan Beulich <[email-masked]>

Integrate the checking with flask_platform_op(); there never really was a
need to defer these checks, as the sub-op has always been known to the
function. As a positive side effect, permissions are then checked at the
same early point with and without Flask.

This is CVE-2026-62427 / part of XSA-499.

Signed-off-by: Jan Beulich <[email-masked]>
Reviewed-by: Roger Pau Monné <[email-masked]>
Reviewed-by: Andrew Cooper <[email-masked]>
Acked-By: Daniel P. Smith <[email-masked]>

--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -682,10 +682,6 @@ ret_t do_platform_op(
     {
         int cpu = op->u.cpu_ol.cpuid;
 
-        ret = xsm_resource_plug_core(XSM_HOOK);
-        if ( ret )
-            break;
-
         if ( cpu >= nr_cpu_ids || !cpu_present(cpu) ||
              clocksource_is_tsc() )
         {
@@ -708,10 +704,6 @@ ret_t do_platform_op(
     {
         int cpu = op->u.cpu_ol.cpuid;
 
-        ret = xsm_resource_unplug_core(XSM_HOOK);
-        if ( ret )
-            break;
-
         if ( cpu == 0 )
         {
             ret = -EOPNOTSUPP;
@@ -736,20 +728,12 @@ ret_t do_platform_op(
     }
 
     case XENPF_cpu_hotadd:
-        ret = xsm_resource_plug_core(XSM_HOOK);
-        if ( ret )
-            break;
-
         ret = cpu_add(op->u.cpu_add.apic_id,
                       op->u.cpu_add.acpi_id,
                       op->u.cpu_add.pxm);
         break;
 
     case XENPF_mem_hotadd:
-        ret = xsm_resource_plug_core(XSM_HOOK);
-        if ( ret )
-            break;
-
         ret = memory_add(op->u.mem_add.spfn,
                       op->u.mem_add.epfn,
                       op->u.mem_add.pxm);
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1564,12 +1564,13 @@ static int cf_check flask_platform_op(ui
     switch ( op )
     {
 #ifdef CONFIG_X86
-    /* These operations have their own XSM hooks */
     case XENPF_cpu_online:
-    case XENPF_cpu_offline:
     case XENPF_cpu_hotadd:
     case XENPF_mem_hotadd:
-        return 0;
+        return flask_resource_plug_core();
+
+    case XENPF_cpu_offline:
+        return flask_resource_unplug_core();
 #endif
 
     case XENPF_settime32: