mirror of https://gitlab.com/qemu-project/qemu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.9 KiB
C
81 lines
2.9 KiB
C
/*
|
|
* Linux kernel fallback API definitions for GCS and test helpers.
|
|
*
|
|
* Copyright (c) 2025 Linaro Ltd
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/prctl.h>
|
|
#include <sys/syscall.h>
|
|
|
|
#ifndef PR_GET_SHADOW_STACK_STATUS
|
|
#define PR_GET_SHADOW_STACK_STATUS 74
|
|
#endif
|
|
#ifndef PR_SET_SHADOW_STACK_STATUS
|
|
#define PR_SET_SHADOW_STACK_STATUS 75
|
|
#endif
|
|
#ifndef PR_LOCK_SHADOW_STACK_STATUS
|
|
#define PR_LOCK_SHADOW_STACK_STATUS 76
|
|
#endif
|
|
#ifndef PR_SHADOW_STACK_ENABLE
|
|
# define PR_SHADOW_STACK_ENABLE (1 << 0)
|
|
# define PR_SHADOW_STACK_WRITE (1 << 1)
|
|
# define PR_SHADOW_STACK_PUSH (1 << 2)
|
|
#endif
|
|
#ifndef SHADOW_STACK_SET_TOKEN
|
|
#define SHADOW_STACK_SET_TOKEN (1 << 0)
|
|
#endif
|
|
#ifndef SHADOW_STACK_SET_MARKER
|
|
#define SHADOW_STACK_SET_MARKER (1 << 1)
|
|
#endif
|
|
#ifndef SEGV_CPERR
|
|
#define SEGV_CPERR 10
|
|
#endif
|
|
#ifndef __NR_map_shadow_stack
|
|
#define __NR_map_shadow_stack 453
|
|
#endif
|
|
|
|
/*
|
|
* Macros, and implement the syscall inline, lest we fail
|
|
* the checked return from any function call.
|
|
*/
|
|
#define enable_gcs(flags) \
|
|
do { \
|
|
register long num __asm__ ("x8") = __NR_prctl; \
|
|
register long arg1 __asm__ ("x0") = PR_SET_SHADOW_STACK_STATUS; \
|
|
register long arg2 __asm__ ("x1") = PR_SHADOW_STACK_ENABLE | flags; \
|
|
register long arg3 __asm__ ("x2") = 0; \
|
|
register long arg4 __asm__ ("x3") = 0; \
|
|
register long arg5 __asm__ ("x4") = 0; \
|
|
asm volatile("svc #0" \
|
|
: "+r"(arg1) \
|
|
: "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5), "r"(num) \
|
|
: "memory", "cc"); \
|
|
if (arg1) { \
|
|
errno = -arg1; \
|
|
perror("PR_SET_SHADOW_STACK_STATUS"); \
|
|
exit(2); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define gcspr() \
|
|
({ uint64_t *r; asm volatile("mrs %0, s3_3_c2_c5_1" : "=r"(r)); r; })
|
|
|
|
#define gcsss1(val) \
|
|
do { \
|
|
asm volatile("sys #3, c7, c7, #2, %0" : : "r"(val) : "memory"); \
|
|
} while (0)
|
|
|
|
#define gcsss2() \
|
|
({ uint64_t *r; \
|
|
asm volatile("sysl %0, #3, c7, c7, #3" : "=r"(r) : : "memory"); r; })
|