criu/dump: gcs: save GCS state during dump

Add debug and info messages to log Guarded Control Stack state when
dumping AArch64 threads. This includes the following values:
  - gcspr_el0
  - features_enabled

Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
[ alex: cleanup fixes ]
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Acked-by: Mike Rapoport <rppt@kernel.org>
This commit is contained in:
Igor Svilenkov Bozic 2025-08-12 18:56:41 +02:00 committed by Alexander Mikhalitsyn
parent 41ecb7ac71
commit 2429d49e67

View file

@ -12,6 +12,7 @@
#include "common/compiler.h"
#include <compel/ptrace.h>
#include "asm/dump.h"
#include "asm/gcs-types.h"
#include "protobuf.h"
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
@ -22,6 +23,7 @@
#include "restorer.h"
#include "compel/infect.h"
#include "pstree.h"
#include <stdbool.h>
/*
* cr_user_pac_* are a copy of the corresponding uapi structs
@ -146,6 +148,11 @@ static int save_pac_keys(int pid, CoreEntry *core)
int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
{
int i;
struct user_gcs gcs_live;
struct iovec gcs_iov = {
.iov_base = &gcs_live,
.iov_len = sizeof(gcs_live),
};
CoreEntry *core = x;
// Save the Aarch64 CPU state
@ -165,6 +172,17 @@ int save_task_regs(pid_t pid, void *x, user_regs_struct_t *regs, user_fpregs_str
if (save_pac_keys(pid, core))
return -1;
/* Save the GCS state */
if (compel_host_supports_gcs()) {
if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_GCS, &gcs_iov) < 0) {
pr_perror("Failed to get GCS for %d", pid);
return -1;
}
core->ti_aarch64->gcs->gcspr_el0 = gcs_live.gcspr_el0;
core->ti_aarch64->gcs->features_enabled = gcs_live.features_enabled;
}
return 0;
}
@ -173,6 +191,7 @@ int arch_alloc_thread_info(CoreEntry *core)
ThreadInfoAarch64 *ti_aarch64;
UserAarch64RegsEntry *gpregs;
UserAarch64FpsimdContextEntry *fpsimd;
UserAarch64GcsEntry *gcs;
ti_aarch64 = xmalloc(sizeof(*ti_aarch64));
if (!ti_aarch64)
@ -202,6 +221,15 @@ int arch_alloc_thread_info(CoreEntry *core)
if (!fpsimd->vregs)
goto err;
/* Allocate & init GCS */
if (compel_host_supports_gcs()) {
gcs = xmalloc(sizeof(*gcs));
if (!gcs)
goto err;
user_aarch64_gcs_entry__init(gcs);
ti_aarch64->gcs = gcs;
}
return 0;
err:
return -1;
@ -231,6 +259,7 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
{
int i;
struct fpsimd_context *fpsimd = RT_SIGFRAME_FPU(sigframe);
struct gcs_context *gcs;
if (core->ti_aarch64->fpsimd->n_vregs != 64)
return 1;
@ -244,6 +273,18 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
fpsimd->head.magic = FPSIMD_MAGIC;
fpsimd->head.size = sizeof(*fpsimd);
if (compel_host_supports_gcs()) {
gcs = RT_SIGFRAME_GCS(sigframe);
pr_debug("sigframe gcspr %llx enabled %llx\n", gcs->gcspr, gcs->features_enabled);
gcs->head.magic = GCS_MAGIC;
gcs->head.size = sizeof(*gcs);
gcs->reserved = 0;
gcs->gcspr = core->ti_aarch64->gcs->gcspr_el0 - 8;
gcs->features_enabled = core->ti_aarch64->gcs->features_enabled;
}
return 0;
}