cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commpage.c (2265B)


      1/*
      2 * Verify the COMMPAGE emulation
      3 *
      4 * The ARM commpage is a set of user space helper functions provided
      5 * by the kernel in an effort to ease portability of user space code
      6 * between different CPUs with potentially different capabilities. It
      7 * is a 32 bit invention and similar to the vdso segment in many ways.
      8 *
      9 * The ABI is documented in the Linux kernel:
     10 *     Documentation/arm/kernel_userspace_helpers.rst
     11 *
     12 * Copyright (c) 2020 Linaro Ltd
     13 *
     14 * SPDX-License-Identifier: GPL-2.0-or-later
     15 */
     16
     17#include <stdlib.h>
     18#include <stdio.h>
     19#include <stdint.h>
     20
     21#define ARM_COMMPAGE      (0xffff0f00u)
     22#define ARM_KUSER_VERSION (*(int32_t *)(ARM_COMMPAGE + 0xfc))
     23typedef void * (get_tls_fn)(void);
     24#define ARM_KUSER_GET_TLS (*(get_tls_fn *)(ARM_COMMPAGE + 0xe0))
     25typedef int (cmpxchg_fn)(int oldval, int newval, volatile int *ptr);
     26#define ARM_KUSER_CMPXCHG (*(cmpxchg_fn *)(ARM_COMMPAGE + 0xc0))
     27typedef void (dmb_fn)(void);
     28#define ARM_KUSER_DMB (*(dmb_fn *)(ARM_COMMPAGE + 0xa0))
     29typedef int (cmpxchg64_fn)(const int64_t *oldval,
     30                           const int64_t *newval,
     31                           volatile int64_t *ptr);
     32#define ARM_KUSER_CMPXCHG64 (*(cmpxchg64_fn *)(ARM_COMMPAGE + 0x60))
     33
     34#define fail_unless(x)                                                  \
     35    do {                                                                \
     36        if (!(x)) {                                                     \
     37            fprintf(stderr, "FAILED at %s:%d\n", __FILE__, __LINE__);   \
     38            exit(EXIT_FAILURE);                                         \
     39        }                                                               \
     40    } while (0)
     41
     42
     43int main(int argc, char *argv[argc])
     44{
     45    void *kuser_tls;
     46    int val = 1;
     47    const int64_t oldval = 1, newval = 2;
     48    int64_t val64 = 1;
     49
     50    fail_unless(ARM_KUSER_VERSION == 0x5);
     51    kuser_tls = ARM_KUSER_GET_TLS();
     52    printf("TLS = %p\n", kuser_tls);
     53    fail_unless(kuser_tls != 0);
     54    fail_unless(ARM_KUSER_CMPXCHG(1, 2, &val) == 0);
     55    printf("val = %d\n", val);
     56    /* this is a crash test, not checking an actual barrier occurs */
     57    ARM_KUSER_DMB();
     58    fail_unless(ARM_KUSER_CMPXCHG64(&oldval, &newval, &val64) == 0);
     59    printf("val64 = %lld\n", val64);
     60    return 0;
     61}