// https://syzkaller.appspot.com/bug?id=4d7de0e6a195b6a5ffef01d2776e737a52c7de60
// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE

#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <linux/futex.h>
#include <linux/kvm.h>

static __thread int skip_segv;
static __thread jmp_buf segv_env;

static void segv_handler(int sig, siginfo_t* info, void* ctx)
{
  uintptr_t addr = (uintptr_t)info->si_addr;
  const uintptr_t prog_start = 1 << 20;
  const uintptr_t prog_end = 100 << 20;
  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
      (addr < prog_start || addr > prog_end)) {
    _longjmp(segv_env, 1);
  }
  exit(sig);
}

static void install_segv_handler(void)
{
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = SIG_IGN;
  syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
  syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
  memset(&sa, 0, sizeof(sa));
  sa.sa_sigaction = segv_handler;
  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
  sigaction(SIGSEGV, &sa, NULL);
  sigaction(SIGBUS, &sa, NULL);
}

#define NONFAILING(...)                                                        \
  {                                                                            \
    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
    if (_setjmp(segv_env) == 0) {                                              \
      __VA_ARGS__;                                                             \
    }                                                                          \
    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
  }

static void sleep_ms(uint64_t ms)
{
  usleep(ms * 1000);
}

static uint64_t current_time_ms(void)
{
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts))
    exit(1);
  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
}

static void thread_start(void* (*fn)(void*), void* arg)
{
  pthread_t th;
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr, 128 << 10);
  int i;
  for (i = 0; i < 100; i++) {
    if (pthread_create(&th, &attr, fn, arg) == 0) {
      pthread_attr_destroy(&attr);
      return;
    }
    if (errno == EAGAIN) {
      usleep(50);
      continue;
    }
    break;
  }
  exit(1);
}

#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
  *(type*)(addr) =                                                             \
      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))

typedef struct {
  int state;
} event_t;

static void event_init(event_t* ev)
{
  ev->state = 0;
}

static void event_reset(event_t* ev)
{
  ev->state = 0;
}

static void event_set(event_t* ev)
{
  if (ev->state)
    exit(1);
  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
}

static void event_wait(event_t* ev)
{
  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
}

static int event_isset(event_t* ev)
{
  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
}

static int event_timedwait(event_t* ev, uint64_t timeout)
{
  uint64_t start = current_time_ms();
  uint64_t now = start;
  for (;;) {
    uint64_t remain = timeout - (now - start);
    struct timespec ts;
    ts.tv_sec = remain / 1000;
    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
    if (__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
      return 1;
    now = current_time_ms();
    if (now - start > timeout)
      return 0;
  }
}

const char kvm_asm16_cpl3[] = "\x0f\x20\xc0\x66\x83\xc8\x01\x0f\x22\xc0\xb8\xa0"
                              "\x00\x0f\x00\xd8\xb8\x2b\x00\x8e\xd8\x8e\xc0\x8e"
                              "\xe0\x8e\xe8\xbc\x00\x01\xc7\x06\x00\x01\x1d\xba"
                              "\xc7\x06\x02\x01\x23\x00\xc7\x06\x04\x01\x00\x01"
                              "\xc7\x06\x06\x01\x2b\x00\xcb";
const char kvm_asm32_paged[] = "\x0f\x20\xc0\x0d\x00\x00\x00\x80\x0f\x22\xc0";
const char kvm_asm32_vm86[] =
    "\x66\xb8\xb8\x00\x0f\x00\xd8\xea\x00\x00\x00\x00\xd0\x00";
const char kvm_asm32_paged_vm86[] = "\x0f\x20\xc0\x0d\x00\x00\x00\x80\x0f\x22"
                                    "\xc0\x66\xb8\xb8\x00\x0f\x00\xd8\xea\x00"
                                    "\x00\x00\x00\xd0\x00";
const char kvm_asm64_enable_long[] = "\x0f\x20\xc0\x0d\x00\x00\x00\x80\x0f\x22"
                                     "\xc0\xea\xde\xc0\xad\x0b\x50\x00\x48\xc7"
                                     "\xc0\xd8\x00\x00\x00\x0f\x00\xd8";
const char kvm_asm64_init_vm[] =
    "\x0f\x20\xc0\x0d\x00\x00\x00\x80\x0f\x22\xc0\xea\xde\xc0\xad\x0b\x50\x00"
    "\x48\xc7\xc0\xd8\x00\x00\x00\x0f\x00\xd8\x48\xc7\xc1\x3a\x00\x00\x00\x0f"
    "\x32\x48\x83\xc8\x05\x0f\x30\x0f\x20\xe0\x48\x0d\x00\x20\x00\x00\x0f\x22"
    "\xe0\x48\xc7\xc1\x80\x04\x00\x00\x0f\x32\x48\xc7\xc2\x00\x60\x00\x00\x89"
    "\x02\x48\xc7\xc2\x00\x70\x00\x00\x89\x02\x48\xc7\xc0\x00\x5f\x00\x00\xf3"
    "\x0f\xc7\x30\x48\xc7\xc0\x08\x5f\x00\x00\x66\x0f\xc7\x30\x0f\xc7\x30\x48"
    "\xc7\xc1\x81\x04\x00\x00\x0f\x32\x48\x83\xc8\x3f\x48\x21\xd0\x48\xc7\xc2"
    "\x00\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x02\x40\x00\x00\x48\xb8\x84\x9e"
    "\x99\xf3\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1e\x40\x00\x00\x48\xc7"
    "\xc0\x81\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc1\x83\x04\x00\x00\x0f\x32\x48"
    "\x0d\xff\x6f\x03\x00\x48\x21\xd0\x48\xc7\xc2\x0c\x40\x00\x00\x0f\x79\xd0"
    "\x48\xc7\xc1\x84\x04\x00\x00\x0f\x32\x48\x0d\xff\x17\x00\x00\x48\x21\xd0"
    "\x48\xc7\xc2\x12\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x04\x2c\x00\x00\x48"
    "\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x28\x00\x00\x48\xc7"
    "\xc0\xff\xff\xff\xff\x0f\x79\xd0\x48\xc7\xc2\x02\x0c\x00\x00\x48\xc7\xc0"
    "\x50\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc0\x58\x00\x00\x00\x48\xc7\xc2\x00"
    "\x0c\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x04\x0c\x00\x00\x0f\x79\xd0\x48\xc7"
    "\xc2\x06\x0c\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x08\x0c\x00\x00\x0f\x79\xd0"
    "\x48\xc7\xc2\x0a\x0c\x00\x00\x0f\x79\xd0\x48\xc7\xc0\xd8\x00\x00\x00\x48"
    "\xc7\xc2\x0c\x0c\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x02\x2c\x00\x00\x48\xc7"
    "\xc0\x00\x05\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x4c\x00\x00\x48\xc7\xc0"
    "\x50\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x10\x6c\x00\x00\x48\xc7\xc0\x00"
    "\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x12\x6c\x00\x00\x48\xc7\xc0\x00\x00"
    "\x00\x00\x0f\x79\xd0\x0f\x20\xc0\x48\xc7\xc2\x00\x6c\x00\x00\x48\x89\xc0"
    "\x0f\x79\xd0\x0f\x20\xd8\x48\xc7\xc2\x02\x6c\x00\x00\x48\x89\xc0\x0f\x79"
    "\xd0\x0f\x20\xe0\x48\xc7\xc2\x04\x6c\x00\x00\x48\x89\xc0\x0f\x79\xd0\x48"
    "\xc7\xc2\x06\x6c\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7"
    "\xc2\x08\x6c\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2"
    "\x0a\x6c\x00\x00\x48\xc7\xc0\x00\x3a\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x0c"
    "\x6c\x00\x00\x48\xc7\xc0\x00\x10\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x0e\x6c"
    "\x00\x00\x48\xc7\xc0\x00\x38\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x14\x6c\x00"
    "\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x16\x6c\x00\x00"
    "\x48\x8b\x04\x25\x10\x5f\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x00\x00\x00"
    "\x48\xc7\xc0\x01\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x02\x00\x00\x00\x48"
    "\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x20\x00\x00\x48\xc7"
    "\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x02\x20\x00\x00\x48\xc7\xc0"
    "\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x04\x20\x00\x00\x48\xc7\xc0\x00"
    "\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x06\x20\x00\x00\x48\xc7\xc0\x00\x00"
    "\x00\x00\x0f\x79\xd0\x48\xc7\xc1\x77\x02\x00\x00\x0f\x32\x48\xc1\xe2\x20"
    "\x48\x09\xd0\x48\xc7\xc2\x00\x2c\x00\x00\x48\x89\xc0\x0f\x79\xd0\x48\xc7"
    "\xc2\x04\x40\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2"
    "\x0a\x40\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x0e"
    "\x40\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x10\x40"
    "\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x16\x40\x00"
    "\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x14\x40\x00\x00"
    "\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x60\x00\x00\x48"
    "\xc7\xc0\xff\xff\xff\xff\x0f\x79\xd0\x48\xc7\xc2\x02\x60\x00\x00\x48\xc7"
    "\xc0\xff\xff\xff\xff\x0f\x79\xd0\x48\xc7\xc2\x1c\x20\x00\x00\x48\xc7\xc0"
    "\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1e\x20\x00\x00\x48\xc7\xc0\x00"
    "\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x20\x20\x00\x00\x48\xc7\xc0\x00\x00"
    "\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x22\x20\x00\x00\x48\xc7\xc0\x00\x00\x00"
    "\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x08\x00\x00\x48\xc7\xc0\x58\x00\x00\x00"
    "\x0f\x79\xd0\x48\xc7\xc2\x02\x08\x00\x00\x48\xc7\xc0\x50\x00\x00\x00\x0f"
    "\x79\xd0\x48\xc7\xc2\x04\x08\x00\x00\x48\xc7\xc0\x58\x00\x00\x00\x0f\x79"
    "\xd0\x48\xc7\xc2\x06\x08\x00\x00\x48\xc7\xc0\x58\x00\x00\x00\x0f\x79\xd0"
    "\x48\xc7\xc2\x08\x08\x00\x00\x48\xc7\xc0\x58\x00\x00\x00\x0f\x79\xd0\x48"
    "\xc7\xc2\x0a\x08\x00\x00\x48\xc7\xc0\x58\x00\x00\x00\x0f\x79\xd0\x48\xc7"
    "\xc2\x0c\x08\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2"
    "\x0e\x08\x00\x00\x48\xc7\xc0\xd8\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x12"
    "\x68\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x14\x68"
    "\x00\x00\x48\xc7\xc0\x00\x3a\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x16\x68\x00"
    "\x00\x48\xc7\xc0\x00\x10\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x18\x68\x00\x00"
    "\x48\xc7\xc0\x00\x38\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x00\x48\x00\x00\x48"
    "\xc7\xc0\xff\xff\x0f\x00\x0f\x79\xd0\x48\xc7\xc2\x02\x48\x00\x00\x48\xc7"
    "\xc0\xff\xff\x0f\x00\x0f\x79\xd0\x48\xc7\xc2\x04\x48\x00\x00\x48\xc7\xc0"
    "\xff\xff\x0f\x00\x0f\x79\xd0\x48\xc7\xc2\x06\x48\x00\x00\x48\xc7\xc0\xff"
    "\xff\x0f\x00\x0f\x79\xd0\x48\xc7\xc2\x08\x48\x00\x00\x48\xc7\xc0\xff\xff"
    "\x0f\x00\x0f\x79\xd0\x48\xc7\xc2\x0a\x48\x00\x00\x48\xc7\xc0\xff\xff\x0f"
    "\x00\x0f\x79\xd0\x48\xc7\xc2\x0c\x48\x00\x00\x48\xc7\xc0\x00\x00\x00\x00"
    "\x0f\x79\xd0\x48\xc7\xc2\x0e\x48\x00\x00\x48\xc7\xc0\xff\x1f\x00\x00\x0f"
    "\x79\xd0\x48\xc7\xc2\x10\x48\x00\x00\x48\xc7\xc0\xff\x1f\x00\x00\x0f\x79"
    "\xd0\x48\xc7\xc2\x12\x48\x00\x00\x48\xc7\xc0\xff\x1f\x00\x00\x0f\x79\xd0"
    "\x48\xc7\xc2\x14\x48\x00\x00\x48\xc7\xc0\x93\x40\x00\x00\x0f\x79\xd0\x48"
    "\xc7\xc2\x16\x48\x00\x00\x48\xc7\xc0\x9b\x20\x00\x00\x0f\x79\xd0\x48\xc7"
    "\xc2\x18\x48\x00\x00\x48\xc7\xc0\x93\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2"
    "\x1a\x48\x00\x00\x48\xc7\xc0\x93\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1c"
    "\x48\x00\x00\x48\xc7\xc0\x93\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1e\x48"
    "\x00\x00\x48\xc7\xc0\x93\x40\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x20\x48\x00"
    "\x00\x48\xc7\xc0\x82\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x22\x48\x00\x00"
    "\x48\xc7\xc0\x8b\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1c\x68\x00\x00\x48"
    "\xc7\xc0\x00\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x1e\x68\x00\x00\x48\xc7"
    "\xc0\x00\x91\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x20\x68\x00\x00\x48\xc7\xc0"
    "\x02\x00\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x06\x28\x00\x00\x48\xc7\xc0\x00"
    "\x05\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x0a\x28\x00\x00\x48\xc7\xc0\x00\x00"
    "\x00\x00\x0f\x79\xd0\x48\xc7\xc2\x0c\x28\x00\x00\x48\xc7\xc0\x00\x00\x00"
    "\x00\x0f\x79\xd0\x48\xc7\xc2\x0e\x28\x00\x00\x48\xc7\xc0\x00\x00\x00\x00"
    "\x0f\x79\xd0\x48\xc7\xc2\x10\x28\x00\x00\x48\xc7\xc0\x00\x00\x00\x00\x0f"
    "\x79\xd0\x0f\x20\xc0\x48\xc7\xc2\x00\x68\x00\x00\x48\x89\xc0\x0f\x79\xd0"
    "\x0f\x20\xd8\x48\xc7\xc2\x02\x68\x00\x00\x48\x89\xc0\x0f\x79\xd0\x0f\x20"
    "\xe0\x48\xc7\xc2\x04\x68\x00\x00\x48\x89\xc0\x0f\x79\xd0\x48\xc7\xc0\x18"
    "\x5f\x00\x00\x48\x8b\x10\x48\xc7\xc0\x20\x5f\x00\x00\x48\x8b\x08\x48\x31"
    "\xc0\x0f\x78\xd0\x48\x31\xc8\x0f\x79\xd0\x0f\x01\xc2\x48\xc7\xc2\x00\x44"
    "\x00\x00\x0f\x78\xd0\xf4";
const char kvm_asm64_vm_exit[] = "\x48\xc7\xc3\x00\x44\x00\x00\x0f\x78\xda\x48"
                                 "\xc7\xc3\x02\x44\x00\x00\x0f\x78\xd9\x48\xc7"
                                 "\xc0\x00\x64\x00\x00\x0f\x78\xc0\x48\xc7\xc3"
                                 "\x1e\x68\x00\x00\x0f\x78\xdb\xf4";
const char kvm_asm64_cpl3[] =
    "\x0f\x20\xc0\x0d\x00\x00\x00\x80\x0f\x22\xc0\xea\xde\xc0\xad\x0b\x50\x00"
    "\x48\xc7\xc0\xd8\x00\x00\x00\x0f\x00\xd8\x48\xc7\xc0\x6b\x00\x00\x00\x8e"
    "\xd8\x8e\xc0\x8e\xe0\x8e\xe8\x48\xc7\xc4\x80\x0f\x00\x00\x48\xc7\x04\x24"
    "\x1d\xba\x00\x00\x48\xc7\x44\x24\x04\x63\x00\x00\x00\x48\xc7\x44\x24\x08"
    "\x80\x0f\x00\x00\x48\xc7\x44\x24\x0c\x6b\x00\x00\x00\xcb";

#define ADDR_TEXT 0x0000
#define ADDR_GDT 0x1000
#define ADDR_LDT 0x1800
#define ADDR_PML4 0x2000
#define ADDR_PDP 0x3000
#define ADDR_PD 0x4000
#define ADDR_STACK0 0x0f80
#define ADDR_VAR_HLT 0x2800
#define ADDR_VAR_SYSRET 0x2808
#define ADDR_VAR_SYSEXIT 0x2810
#define ADDR_VAR_IDT 0x3800
#define ADDR_VAR_TSS64 0x3a00
#define ADDR_VAR_TSS64_CPL3 0x3c00
#define ADDR_VAR_TSS16 0x3d00
#define ADDR_VAR_TSS16_2 0x3e00
#define ADDR_VAR_TSS16_CPL3 0x3f00
#define ADDR_VAR_TSS32 0x4800
#define ADDR_VAR_TSS32_2 0x4a00
#define ADDR_VAR_TSS32_CPL3 0x4c00
#define ADDR_VAR_TSS32_VM86 0x4e00
#define ADDR_VAR_VMXON_PTR 0x5f00
#define ADDR_VAR_VMCS_PTR 0x5f08
#define ADDR_VAR_VMEXIT_PTR 0x5f10
#define ADDR_VAR_VMWRITE_FLD 0x5f18
#define ADDR_VAR_VMWRITE_VAL 0x5f20
#define ADDR_VAR_VMXON 0x6000
#define ADDR_VAR_VMCS 0x7000
#define ADDR_VAR_VMEXIT_CODE 0x9000
#define ADDR_VAR_USER_CODE 0x9100
#define ADDR_VAR_USER_CODE2 0x9120

#define SEL_LDT (1 << 3)
#define SEL_CS16 (2 << 3)
#define SEL_DS16 (3 << 3)
#define SEL_CS16_CPL3 ((4 << 3) + 3)
#define SEL_DS16_CPL3 ((5 << 3) + 3)
#define SEL_CS32 (6 << 3)
#define SEL_DS32 (7 << 3)
#define SEL_CS32_CPL3 ((8 << 3) + 3)
#define SEL_DS32_CPL3 ((9 << 3) + 3)
#define SEL_CS64 (10 << 3)
#define SEL_DS64 (11 << 3)
#define SEL_CS64_CPL3 ((12 << 3) + 3)
#define SEL_DS64_CPL3 ((13 << 3) + 3)
#define SEL_CGATE16 (14 << 3)
#define SEL_TGATE16 (15 << 3)
#define SEL_CGATE32 (16 << 3)
#define SEL_TGATE32 (17 << 3)
#define SEL_CGATE64 (18 << 3)
#define SEL_CGATE64_HI (19 << 3)
#define SEL_TSS16 (20 << 3)
#define SEL_TSS16_2 (21 << 3)
#define SEL_TSS16_CPL3 ((22 << 3) + 3)
#define SEL_TSS32 (23 << 3)
#define SEL_TSS32_2 (24 << 3)
#define SEL_TSS32_CPL3 ((25 << 3) + 3)
#define SEL_TSS32_VM86 (26 << 3)
#define SEL_TSS64 (27 << 3)
#define SEL_TSS64_HI (28 << 3)
#define SEL_TSS64_CPL3 ((29 << 3) + 3)
#define SEL_TSS64_CPL3_HI (30 << 3)

#define MSR_IA32_FEATURE_CONTROL 0x3a
#define MSR_IA32_VMX_BASIC 0x480
#define MSR_IA32_SMBASE 0x9e
#define MSR_IA32_SYSENTER_CS 0x174
#define MSR_IA32_SYSENTER_ESP 0x175
#define MSR_IA32_SYSENTER_EIP 0x176
#define MSR_IA32_STAR 0xC0000081
#define MSR_IA32_LSTAR 0xC0000082
#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B

#define NEXT_INSN $0xbadc0de
#define PREFIX_SIZE 0xba1d

#define KVM_SMI _IO(KVMIO, 0xb7)

#define CR0_PE 1
#define CR0_MP (1 << 1)
#define CR0_EM (1 << 2)
#define CR0_TS (1 << 3)
#define CR0_ET (1 << 4)
#define CR0_NE (1 << 5)
#define CR0_WP (1 << 16)
#define CR0_AM (1 << 18)
#define CR0_NW (1 << 29)
#define CR0_CD (1 << 30)
#define CR0_PG (1 << 31)

#define CR4_VME 1
#define CR4_PVI (1 << 1)
#define CR4_TSD (1 << 2)
#define CR4_DE (1 << 3)
#define CR4_PSE (1 << 4)
#define CR4_PAE (1 << 5)
#define CR4_MCE (1 << 6)
#define CR4_PGE (1 << 7)
#define CR4_PCE (1 << 8)
#define CR4_OSFXSR (1 << 8)
#define CR4_OSXMMEXCPT (1 << 10)
#define CR4_UMIP (1 << 11)
#define CR4_VMXE (1 << 13)
#define CR4_SMXE (1 << 14)
#define CR4_FSGSBASE (1 << 16)
#define CR4_PCIDE (1 << 17)
#define CR4_OSXSAVE (1 << 18)
#define CR4_SMEP (1 << 20)
#define CR4_SMAP (1 << 21)
#define CR4_PKE (1 << 22)

#define EFER_SCE 1
#define EFER_LME (1 << 8)
#define EFER_LMA (1 << 10)
#define EFER_NXE (1 << 11)
#define EFER_SVME (1 << 12)
#define EFER_LMSLE (1 << 13)
#define EFER_FFXSR (1 << 14)
#define EFER_TCE (1 << 15)
#define PDE32_PRESENT 1
#define PDE32_RW (1 << 1)
#define PDE32_USER (1 << 2)
#define PDE32_PS (1 << 7)
#define PDE64_PRESENT 1
#define PDE64_RW (1 << 1)
#define PDE64_USER (1 << 2)
#define PDE64_ACCESSED (1 << 5)
#define PDE64_DIRTY (1 << 6)
#define PDE64_PS (1 << 7)
#define PDE64_G (1 << 8)

struct tss16 {
  uint16_t prev;
  uint16_t sp0;
  uint16_t ss0;
  uint16_t sp1;
  uint16_t ss1;
  uint16_t sp2;
  uint16_t ss2;
  uint16_t ip;
  uint16_t flags;
  uint16_t ax;
  uint16_t cx;
  uint16_t dx;
  uint16_t bx;
  uint16_t sp;
  uint16_t bp;
  uint16_t si;
  uint16_t di;
  uint16_t es;
  uint16_t cs;
  uint16_t ss;
  uint16_t ds;
  uint16_t ldt;
} __attribute__((packed));

struct tss32 {
  uint16_t prev, prevh;
  uint32_t sp0;
  uint16_t ss0, ss0h;
  uint32_t sp1;
  uint16_t ss1, ss1h;
  uint32_t sp2;
  uint16_t ss2, ss2h;
  uint32_t cr3;
  uint32_t ip;
  uint32_t flags;
  uint32_t ax;
  uint32_t cx;
  uint32_t dx;
  uint32_t bx;
  uint32_t sp;
  uint32_t bp;
  uint32_t si;
  uint32_t di;
  uint16_t es, esh;
  uint16_t cs, csh;
  uint16_t ss, ssh;
  uint16_t ds, dsh;
  uint16_t fs, fsh;
  uint16_t gs, gsh;
  uint16_t ldt, ldth;
  uint16_t trace;
  uint16_t io_bitmap;
} __attribute__((packed));

struct tss64 {
  uint32_t reserved0;
  uint64_t rsp[3];
  uint64_t reserved1;
  uint64_t ist[7];
  uint64_t reserved2;
  uint32_t reserved3;
  uint32_t io_bitmap;
} __attribute__((packed));

static void fill_segment_descriptor(uint64_t* dt, uint64_t* lt,
                                    struct kvm_segment* seg)
{
  uint16_t index = seg->selector >> 3;
  uint64_t limit = seg->g ? seg->limit >> 12 : seg->limit;
  uint64_t sd = (limit & 0xffff) | (seg->base & 0xffffff) << 16 |
                (uint64_t)seg->type << 40 | (uint64_t)seg->s << 44 |
                (uint64_t)seg->dpl << 45 | (uint64_t)seg->present << 47 |
                (limit & 0xf0000ULL) << 48 | (uint64_t)seg->avl << 52 |
                (uint64_t)seg->l << 53 | (uint64_t)seg->db << 54 |
                (uint64_t)seg->g << 55 | (seg->base & 0xff000000ULL) << 56;
  NONFAILING(dt[index] = sd);
  NONFAILING(lt[index] = sd);
}

static void fill_segment_descriptor_dword(uint64_t* dt, uint64_t* lt,
                                          struct kvm_segment* seg)
{
  fill_segment_descriptor(dt, lt, seg);
  uint16_t index = seg->selector >> 3;
  NONFAILING(dt[index + 1] = 0);
  NONFAILING(lt[index + 1] = 0);
}

static void setup_syscall_msrs(int cpufd, uint16_t sel_cs, uint16_t sel_cs_cpl3)
{
  char buf[sizeof(struct kvm_msrs) + 5 * sizeof(struct kvm_msr_entry)];
  memset(buf, 0, sizeof(buf));
  struct kvm_msrs* msrs = (struct kvm_msrs*)buf;
  struct kvm_msr_entry* entries = msrs->entries;
  msrs->nmsrs = 5;
  entries[0].index = MSR_IA32_SYSENTER_CS;
  entries[0].data = sel_cs;
  entries[1].index = MSR_IA32_SYSENTER_ESP;
  entries[1].data = ADDR_STACK0;
  entries[2].index = MSR_IA32_SYSENTER_EIP;
  entries[2].data = ADDR_VAR_SYSEXIT;
  entries[3].index = MSR_IA32_STAR;
  entries[3].data = ((uint64_t)sel_cs << 32) | ((uint64_t)sel_cs_cpl3 << 48);
  entries[4].index = MSR_IA32_LSTAR;
  entries[4].data = ADDR_VAR_SYSRET;
  ioctl(cpufd, KVM_SET_MSRS, msrs);
}

static void setup_32bit_idt(struct kvm_sregs* sregs, char* host_mem,
                            uintptr_t guest_mem)
{
  sregs->idt.base = guest_mem + ADDR_VAR_IDT;
  sregs->idt.limit = 0x1ff;
  uint64_t* idt = (uint64_t*)(host_mem + sregs->idt.base);
  int i;
  for (i = 0; i < 32; i++) {
    struct kvm_segment gate;
    gate.selector = i << 3;
    switch (i % 6) {
    case 0:
      gate.type = 6;
      gate.base = SEL_CS16;
      break;
    case 1:
      gate.type = 7;
      gate.base = SEL_CS16;
      break;
    case 2:
      gate.type = 3;
      gate.base = SEL_TGATE16;
      break;
    case 3:
      gate.type = 14;
      gate.base = SEL_CS32;
      break;
    case 4:
      gate.type = 15;
      gate.base = SEL_CS32;
      break;
    case 6:
      gate.type = 11;
      gate.base = SEL_TGATE32;
      break;
    }
    gate.limit = guest_mem + ADDR_VAR_USER_CODE2;
    gate.present = 1;
    gate.dpl = 0;
    gate.s = 0;
    gate.g = 0;
    gate.db = 0;
    gate.l = 0;
    gate.avl = 0;
    fill_segment_descriptor(idt, idt, &gate);
  }
}

static void setup_64bit_idt(struct kvm_sregs* sregs, char* host_mem,
                            uintptr_t guest_mem)
{
  sregs->idt.base = guest_mem + ADDR_VAR_IDT;
  sregs->idt.limit = 0x1ff;
  uint64_t* idt = (uint64_t*)(host_mem + sregs->idt.base);
  int i;
  for (i = 0; i < 32; i++) {
    struct kvm_segment gate;
    gate.selector = (i * 2) << 3;
    gate.type = (i & 1) ? 14 : 15;
    gate.base = SEL_CS64;
    gate.limit = guest_mem + ADDR_VAR_USER_CODE2;
    gate.present = 1;
    gate.dpl = 0;
    gate.s = 0;
    gate.g = 0;
    gate.db = 0;
    gate.l = 0;
    gate.avl = 0;
    fill_segment_descriptor_dword(idt, idt, &gate);
  }
}

struct kvm_text {
  uintptr_t typ;
  const void* text;
  uintptr_t size;
};

struct kvm_opt {
  uint64_t typ;
  uint64_t val;
};

#define KVM_SETUP_PAGING (1 << 0)
#define KVM_SETUP_PAE (1 << 1)
#define KVM_SETUP_PROTECTED (1 << 2)
#define KVM_SETUP_CPL3 (1 << 3)
#define KVM_SETUP_VIRT86 (1 << 4)
#define KVM_SETUP_SMM (1 << 5)
#define KVM_SETUP_VM (1 << 6)
static long syz_kvm_setup_cpu(volatile long a0, volatile long a1,
                              volatile long a2, volatile long a3,
                              volatile long a4, volatile long a5,
                              volatile long a6, volatile long a7)
{
  const int vmfd = a0;
  const int cpufd = a1;
  char* const host_mem = (char*)a2;
  const struct kvm_text* const text_array_ptr = (struct kvm_text*)a3;
  const uintptr_t text_count = a4;
  const uintptr_t flags = a5;
  const struct kvm_opt* const opt_array_ptr = (struct kvm_opt*)a6;
  uintptr_t opt_count = a7;
  const uintptr_t page_size = 4 << 10;
  const uintptr_t ioapic_page = 10;
  const uintptr_t guest_mem_size = 24 * page_size;
  const uintptr_t guest_mem = 0;
  (void)text_count;
  int text_type = 0;
  const void* text = 0;
  uintptr_t text_size = 0;
  NONFAILING(text_type = text_array_ptr[0].typ);
  NONFAILING(text = text_array_ptr[0].text);
  NONFAILING(text_size = text_array_ptr[0].size);
  uintptr_t i;
  for (i = 0; i < guest_mem_size / page_size; i++) {
    struct kvm_userspace_memory_region memreg;
    memreg.slot = i;
    memreg.flags = 0;
    memreg.guest_phys_addr = guest_mem + i * page_size;
    if (i == ioapic_page)
      memreg.guest_phys_addr = 0xfec00000;
    memreg.memory_size = page_size;
    memreg.userspace_addr = (uintptr_t)host_mem + i * page_size;
    ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg);
  }
  struct kvm_userspace_memory_region memreg;
  memreg.slot = 1 + (1 << 16);
  memreg.flags = 0;
  memreg.guest_phys_addr = 0x30000;
  memreg.memory_size = 64 << 10;
  memreg.userspace_addr = (uintptr_t)host_mem;
  ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg);
  struct kvm_sregs sregs;
  if (ioctl(cpufd, KVM_GET_SREGS, &sregs))
    return -1;
  struct kvm_regs regs;
  memset(&regs, 0, sizeof(regs));
  regs.rip = guest_mem + ADDR_TEXT;
  regs.rsp = ADDR_STACK0;
  sregs.gdt.base = guest_mem + ADDR_GDT;
  sregs.gdt.limit = 256 * sizeof(uint64_t) - 1;
  uint64_t* gdt = (uint64_t*)(host_mem + sregs.gdt.base);
  struct kvm_segment seg_ldt;
  seg_ldt.selector = SEL_LDT;
  seg_ldt.type = 2;
  seg_ldt.base = guest_mem + ADDR_LDT;
  seg_ldt.limit = 256 * sizeof(uint64_t) - 1;
  seg_ldt.present = 1;
  seg_ldt.dpl = 0;
  seg_ldt.s = 0;
  seg_ldt.g = 0;
  seg_ldt.db = 1;
  seg_ldt.l = 0;
  sregs.ldt = seg_ldt;
  uint64_t* ldt = (uint64_t*)(host_mem + sregs.ldt.base);
  struct kvm_segment seg_cs16;
  seg_cs16.selector = SEL_CS16;
  seg_cs16.type = 11;
  seg_cs16.base = 0;
  seg_cs16.limit = 0xfffff;
  seg_cs16.present = 1;
  seg_cs16.dpl = 0;
  seg_cs16.s = 1;
  seg_cs16.g = 0;
  seg_cs16.db = 0;
  seg_cs16.l = 0;
  struct kvm_segment seg_ds16 = seg_cs16;
  seg_ds16.selector = SEL_DS16;
  seg_ds16.type = 3;
  struct kvm_segment seg_cs16_cpl3 = seg_cs16;
  seg_cs16_cpl3.selector = SEL_CS16_CPL3;
  seg_cs16_cpl3.dpl = 3;
  struct kvm_segment seg_ds16_cpl3 = seg_ds16;
  seg_ds16_cpl3.selector = SEL_DS16_CPL3;
  seg_ds16_cpl3.dpl = 3;
  struct kvm_segment seg_cs32 = seg_cs16;
  seg_cs32.selector = SEL_CS32;
  seg_cs32.db = 1;
  struct kvm_segment seg_ds32 = seg_ds16;
  seg_ds32.selector = SEL_DS32;
  seg_ds32.db = 1;
  struct kvm_segment seg_cs32_cpl3 = seg_cs32;
  seg_cs32_cpl3.selector = SEL_CS32_CPL3;
  seg_cs32_cpl3.dpl = 3;
  struct kvm_segment seg_ds32_cpl3 = seg_ds32;
  seg_ds32_cpl3.selector = SEL_DS32_CPL3;
  seg_ds32_cpl3.dpl = 3;
  struct kvm_segment seg_cs64 = seg_cs16;
  seg_cs64.selector = SEL_CS64;
  seg_cs64.l = 1;
  struct kvm_segment seg_ds64 = seg_ds32;
  seg_ds64.selector = SEL_DS64;
  struct kvm_segment seg_cs64_cpl3 = seg_cs64;
  seg_cs64_cpl3.selector = SEL_CS64_CPL3;
  seg_cs64_cpl3.dpl = 3;
  struct kvm_segment seg_ds64_cpl3 = seg_ds64;
  seg_ds64_cpl3.selector = SEL_DS64_CPL3;
  seg_ds64_cpl3.dpl = 3;
  struct kvm_segment seg_tss32;
  seg_tss32.selector = SEL_TSS32;
  seg_tss32.type = 9;
  seg_tss32.base = ADDR_VAR_TSS32;
  seg_tss32.limit = 0x1ff;
  seg_tss32.present = 1;
  seg_tss32.dpl = 0;
  seg_tss32.s = 0;
  seg_tss32.g = 0;
  seg_tss32.db = 0;
  seg_tss32.l = 0;
  struct kvm_segment seg_tss32_2 = seg_tss32;
  seg_tss32_2.selector = SEL_TSS32_2;
  seg_tss32_2.base = ADDR_VAR_TSS32_2;
  struct kvm_segment seg_tss32_cpl3 = seg_tss32;
  seg_tss32_cpl3.selector = SEL_TSS32_CPL3;
  seg_tss32_cpl3.base = ADDR_VAR_TSS32_CPL3;
  struct kvm_segment seg_tss32_vm86 = seg_tss32;
  seg_tss32_vm86.selector = SEL_TSS32_VM86;
  seg_tss32_vm86.base = ADDR_VAR_TSS32_VM86;
  struct kvm_segment seg_tss16 = seg_tss32;
  seg_tss16.selector = SEL_TSS16;
  seg_tss16.base = ADDR_VAR_TSS16;
  seg_tss16.limit = 0xff;
  seg_tss16.type = 1;
  struct kvm_segment seg_tss16_2 = seg_tss16;
  seg_tss16_2.selector = SEL_TSS16_2;
  seg_tss16_2.base = ADDR_VAR_TSS16_2;
  seg_tss16_2.dpl = 0;
  struct kvm_segment seg_tss16_cpl3 = seg_tss16;
  seg_tss16_cpl3.selector = SEL_TSS16_CPL3;
  seg_tss16_cpl3.base = ADDR_VAR_TSS16_CPL3;
  seg_tss16_cpl3.dpl = 3;
  struct kvm_segment seg_tss64 = seg_tss32;
  seg_tss64.selector = SEL_TSS64;
  seg_tss64.base = ADDR_VAR_TSS64;
  seg_tss64.limit = 0x1ff;
  struct kvm_segment seg_tss64_cpl3 = seg_tss64;
  seg_tss64_cpl3.selector = SEL_TSS64_CPL3;
  seg_tss64_cpl3.base = ADDR_VAR_TSS64_CPL3;
  seg_tss64_cpl3.dpl = 3;
  struct kvm_segment seg_cgate16;
  seg_cgate16.selector = SEL_CGATE16;
  seg_cgate16.type = 4;
  seg_cgate16.base = SEL_CS16 | (2 << 16);
  seg_cgate16.limit = ADDR_VAR_USER_CODE2;
  seg_cgate16.present = 1;
  seg_cgate16.dpl = 0;
  seg_cgate16.s = 0;
  seg_cgate16.g = 0;
  seg_cgate16.db = 0;
  seg_cgate16.l = 0;
  seg_cgate16.avl = 0;
  struct kvm_segment seg_tgate16 = seg_cgate16;
  seg_tgate16.selector = SEL_TGATE16;
  seg_tgate16.type = 3;
  seg_cgate16.base = SEL_TSS16_2;
  seg_tgate16.limit = 0;
  struct kvm_segment seg_cgate32 = seg_cgate16;
  seg_cgate32.selector = SEL_CGATE32;
  seg_cgate32.type = 12;
  seg_cgate32.base = SEL_CS32 | (2 << 16);
  struct kvm_segment seg_tgate32 = seg_cgate32;
  seg_tgate32.selector = SEL_TGATE32;
  seg_tgate32.type = 11;
  seg_tgate32.base = SEL_TSS32_2;
  seg_tgate32.limit = 0;
  struct kvm_segment seg_cgate64 = seg_cgate16;
  seg_cgate64.selector = SEL_CGATE64;
  seg_cgate64.type = 12;
  seg_cgate64.base = SEL_CS64;
  int kvmfd = open("/dev/kvm", O_RDWR);
  char buf[sizeof(struct kvm_cpuid2) + 128 * sizeof(struct kvm_cpuid_entry2)];
  memset(buf, 0, sizeof(buf));
  struct kvm_cpuid2* cpuid = (struct kvm_cpuid2*)buf;
  cpuid->nent = 128;
  ioctl(kvmfd, KVM_GET_SUPPORTED_CPUID, cpuid);
  ioctl(cpufd, KVM_SET_CPUID2, cpuid);
  close(kvmfd);
  const char* text_prefix = 0;
  int text_prefix_size = 0;
  char* host_text = host_mem + ADDR_TEXT;
  if (text_type == 8) {
    if (flags & KVM_SETUP_SMM) {
      if (flags & KVM_SETUP_PROTECTED) {
        sregs.cs = seg_cs16;
        sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds16;
        sregs.cr0 |= CR0_PE;
      } else {
        sregs.cs.selector = 0;
        sregs.cs.base = 0;
      }
      NONFAILING(*(host_mem + ADDR_TEXT) = 0xf4);
      host_text = host_mem + 0x8000;
      ioctl(cpufd, KVM_SMI, 0);
    } else if (flags & KVM_SETUP_VIRT86) {
      sregs.cs = seg_cs32;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32;
      sregs.cr0 |= CR0_PE;
      sregs.efer |= EFER_SCE;
      setup_syscall_msrs(cpufd, SEL_CS32, SEL_CS32_CPL3);
      setup_32bit_idt(&sregs, host_mem, guest_mem);
      if (flags & KVM_SETUP_PAGING) {
        uint64_t pd_addr = guest_mem + ADDR_PD;
        uint64_t* pd = (uint64_t*)(host_mem + ADDR_PD);
        NONFAILING(pd[0] = PDE32_PRESENT | PDE32_RW | PDE32_USER | PDE32_PS);
        sregs.cr3 = pd_addr;
        sregs.cr4 |= CR4_PSE;
        text_prefix = kvm_asm32_paged_vm86;
        text_prefix_size = sizeof(kvm_asm32_paged_vm86) - 1;
      } else {
        text_prefix = kvm_asm32_vm86;
        text_prefix_size = sizeof(kvm_asm32_vm86) - 1;
      }
    } else {
      sregs.cs.selector = 0;
      sregs.cs.base = 0;
    }
  } else if (text_type == 16) {
    if (flags & KVM_SETUP_CPL3) {
      sregs.cs = seg_cs16;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds16;
      text_prefix = kvm_asm16_cpl3;
      text_prefix_size = sizeof(kvm_asm16_cpl3) - 1;
    } else {
      sregs.cr0 |= CR0_PE;
      sregs.cs = seg_cs16;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds16;
    }
  } else if (text_type == 32) {
    sregs.cr0 |= CR0_PE;
    sregs.efer |= EFER_SCE;
    setup_syscall_msrs(cpufd, SEL_CS32, SEL_CS32_CPL3);
    setup_32bit_idt(&sregs, host_mem, guest_mem);
    if (flags & KVM_SETUP_SMM) {
      sregs.cs = seg_cs32;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32;
      NONFAILING(*(host_mem + ADDR_TEXT) = 0xf4);
      host_text = host_mem + 0x8000;
      ioctl(cpufd, KVM_SMI, 0);
    } else if (flags & KVM_SETUP_PAGING) {
      sregs.cs = seg_cs32;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32;
      uint64_t pd_addr = guest_mem + ADDR_PD;
      uint64_t* pd = (uint64_t*)(host_mem + ADDR_PD);
      NONFAILING(pd[0] = PDE32_PRESENT | PDE32_RW | PDE32_USER | PDE32_PS);
      sregs.cr3 = pd_addr;
      sregs.cr4 |= CR4_PSE;
      text_prefix = kvm_asm32_paged;
      text_prefix_size = sizeof(kvm_asm32_paged) - 1;
    } else if (flags & KVM_SETUP_CPL3) {
      sregs.cs = seg_cs32_cpl3;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32_cpl3;
    } else {
      sregs.cs = seg_cs32;
      sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32;
    }
  } else {
    sregs.efer |= EFER_LME | EFER_SCE;
    sregs.cr0 |= CR0_PE;
    setup_syscall_msrs(cpufd, SEL_CS64, SEL_CS64_CPL3);
    setup_64bit_idt(&sregs, host_mem, guest_mem);
    sregs.cs = seg_cs32;
    sregs.ds = sregs.es = sregs.fs = sregs.gs = sregs.ss = seg_ds32;
    uint64_t pml4_addr = guest_mem + ADDR_PML4;
    uint64_t* pml4 = (uint64_t*)(host_mem + ADDR_PML4);
    uint64_t pdpt_addr = guest_mem + ADDR_PDP;
    uint64_t* pdpt = (uint64_t*)(host_mem + ADDR_PDP);
    uint64_t pd_addr = guest_mem + ADDR_PD;
    uint64_t* pd = (uint64_t*)(host_mem + ADDR_PD);
    NONFAILING(pml4[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | pdpt_addr);
    NONFAILING(pdpt[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | pd_addr);
    NONFAILING(pd[0] = PDE64_PRESENT | PDE64_RW | PDE64_USER | PDE64_PS);
    sregs.cr3 = pml4_addr;
    sregs.cr4 |= CR4_PAE;
    if (flags & KVM_SETUP_VM) {
      sregs.cr0 |= CR0_NE;
      NONFAILING(*((uint64_t*)(host_mem + ADDR_VAR_VMXON_PTR)) =
                     ADDR_VAR_VMXON);
      NONFAILING(*((uint64_t*)(host_mem + ADDR_VAR_VMCS_PTR)) = ADDR_VAR_VMCS);
      NONFAILING(memcpy(host_mem + ADDR_VAR_VMEXIT_CODE, kvm_asm64_vm_exit,
                        sizeof(kvm_asm64_vm_exit) - 1));
      NONFAILING(*((uint64_t*)(host_mem + ADDR_VAR_VMEXIT_PTR)) =
                     ADDR_VAR_VMEXIT_CODE);
      text_prefix = kvm_asm64_init_vm;
      text_prefix_size = sizeof(kvm_asm64_init_vm) - 1;
    } else if (flags & KVM_SETUP_CPL3) {
      text_prefix = kvm_asm64_cpl3;
      text_prefix_size = sizeof(kvm_asm64_cpl3) - 1;
    } else {
      text_prefix = kvm_asm64_enable_long;
      text_prefix_size = sizeof(kvm_asm64_enable_long) - 1;
    }
  }
  struct tss16 tss16;
  memset(&tss16, 0, sizeof(tss16));
  tss16.ss0 = tss16.ss1 = tss16.ss2 = SEL_DS16;
  tss16.sp0 = tss16.sp1 = tss16.sp2 = ADDR_STACK0;
  tss16.ip = ADDR_VAR_USER_CODE2;
  tss16.flags = (1 << 1);
  tss16.cs = SEL_CS16;
  tss16.es = tss16.ds = tss16.ss = SEL_DS16;
  tss16.ldt = SEL_LDT;
  struct tss16* tss16_addr = (struct tss16*)(host_mem + seg_tss16_2.base);
  NONFAILING(memcpy(tss16_addr, &tss16, sizeof(tss16)));
  memset(&tss16, 0, sizeof(tss16));
  tss16.ss0 = tss16.ss1 = tss16.ss2 = SEL_DS16;
  tss16.sp0 = tss16.sp1 = tss16.sp2 = ADDR_STACK0;
  tss16.ip = ADDR_VAR_USER_CODE2;
  tss16.flags = (1 << 1);
  tss16.cs = SEL_CS16_CPL3;
  tss16.es = tss16.ds = tss16.ss = SEL_DS16_CPL3;
  tss16.ldt = SEL_LDT;
  struct tss16* tss16_cpl3_addr =
      (struct tss16*)(host_mem + seg_tss16_cpl3.base);
  NONFAILING(memcpy(tss16_cpl3_addr, &tss16, sizeof(tss16)));
  struct tss32 tss32;
  memset(&tss32, 0, sizeof(tss32));
  tss32.ss0 = tss32.ss1 = tss32.ss2 = SEL_DS32;
  tss32.sp0 = tss32.sp1 = tss32.sp2 = ADDR_STACK0;
  tss32.ip = ADDR_VAR_USER_CODE;
  tss32.flags = (1 << 1) | (1 << 17);
  tss32.ldt = SEL_LDT;
  tss32.cr3 = sregs.cr3;
  tss32.io_bitmap = offsetof(struct tss32, io_bitmap);
  struct tss32* tss32_addr = (struct tss32*)(host_mem + seg_tss32_vm86.base);
  NONFAILING(memcpy(tss32_addr, &tss32, sizeof(tss32)));
  memset(&tss32, 0, sizeof(tss32));
  tss32.ss0 = tss32.ss1 = tss32.ss2 = SEL_DS32;
  tss32.sp0 = tss32.sp1 = tss32.sp2 = ADDR_STACK0;
  tss32.ip = ADDR_VAR_USER_CODE;
  tss32.flags = (1 << 1);
  tss32.cr3 = sregs.cr3;
  tss32.es = tss32.ds = tss32.ss = tss32.gs = tss32.fs = SEL_DS32;
  tss32.cs = SEL_CS32;
  tss32.ldt = SEL_LDT;
  tss32.cr3 = sregs.cr3;
  tss32.io_bitmap = offsetof(struct tss32, io_bitmap);
  struct tss32* tss32_cpl3_addr = (struct tss32*)(host_mem + seg_tss32_2.base);
  NONFAILING(memcpy(tss32_cpl3_addr, &tss32, sizeof(tss32)));
  struct tss64 tss64;
  memset(&tss64, 0, sizeof(tss64));
  tss64.rsp[0] = ADDR_STACK0;
  tss64.rsp[1] = ADDR_STACK0;
  tss64.rsp[2] = ADDR_STACK0;
  tss64.io_bitmap = offsetof(struct tss64, io_bitmap);
  struct tss64* tss64_addr = (struct tss64*)(host_mem + seg_tss64.base);
  NONFAILING(memcpy(tss64_addr, &tss64, sizeof(tss64)));
  memset(&tss64, 0, sizeof(tss64));
  tss64.rsp[0] = ADDR_STACK0;
  tss64.rsp[1] = ADDR_STACK0;
  tss64.rsp[2] = ADDR_STACK0;
  tss64.io_bitmap = offsetof(struct tss64, io_bitmap);
  struct tss64* tss64_cpl3_addr =
      (struct tss64*)(host_mem + seg_tss64_cpl3.base);
  NONFAILING(memcpy(tss64_cpl3_addr, &tss64, sizeof(tss64)));
  if (text_size > 1000)
    text_size = 1000;
  if (text_prefix) {
    NONFAILING(memcpy(host_text, text_prefix, text_prefix_size));
    void* patch = 0;
    NONFAILING(patch =
                   memmem(host_text, text_prefix_size, "\xde\xc0\xad\x0b", 4));
    if (patch)
      NONFAILING(*((uint32_t*)patch) =
                     guest_mem + ADDR_TEXT + ((char*)patch - host_text) + 6);
    uint16_t magic = PREFIX_SIZE;
    patch = 0;
    NONFAILING(patch =
                   memmem(host_text, text_prefix_size, &magic, sizeof(magic)));
    if (patch)
      NONFAILING(*((uint16_t*)patch) =
                     guest_mem + ADDR_TEXT + text_prefix_size);
  }
  NONFAILING(memcpy((void*)(host_text + text_prefix_size), text, text_size));
  NONFAILING(*(host_text + text_prefix_size + text_size) = 0xf4);
  NONFAILING(memcpy(host_mem + ADDR_VAR_USER_CODE, text, text_size));
  NONFAILING(*(host_mem + ADDR_VAR_USER_CODE + text_size) = 0xf4);
  NONFAILING(*(host_mem + ADDR_VAR_HLT) = 0xf4);
  NONFAILING(memcpy(host_mem + ADDR_VAR_SYSRET, "\x0f\x07\xf4", 3));
  NONFAILING(memcpy(host_mem + ADDR_VAR_SYSEXIT, "\x0f\x35\xf4", 3));
  NONFAILING(*(uint64_t*)(host_mem + ADDR_VAR_VMWRITE_FLD) = 0);
  NONFAILING(*(uint64_t*)(host_mem + ADDR_VAR_VMWRITE_VAL) = 0);
  if (opt_count > 2)
    opt_count = 2;
  for (i = 0; i < opt_count; i++) {
    uint64_t typ = 0;
    uint64_t val = 0;
    NONFAILING(typ = opt_array_ptr[i].typ);
    NONFAILING(val = opt_array_ptr[i].val);
    switch (typ % 9) {
    case 0:
      sregs.cr0 ^= val & (CR0_MP | CR0_EM | CR0_ET | CR0_NE | CR0_WP | CR0_AM |
                          CR0_NW | CR0_CD);
      break;
    case 1:
      sregs.cr4 ^=
          val & (CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PGE |
                 CR4_PCE | CR4_OSFXSR | CR4_OSXMMEXCPT | CR4_UMIP | CR4_VMXE |
                 CR4_SMXE | CR4_FSGSBASE | CR4_PCIDE | CR4_OSXSAVE | CR4_SMEP |
                 CR4_SMAP | CR4_PKE);
      break;
    case 2:
      sregs.efer ^= val & (EFER_SCE | EFER_NXE | EFER_SVME | EFER_LMSLE |
                           EFER_FFXSR | EFER_TCE);
      break;
    case 3:
      val &=
          ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 12) | (1 << 13) | (1 << 14) |
           (1 << 15) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21));
      regs.rflags ^= val;
      NONFAILING(tss16_addr->flags ^= val);
      NONFAILING(tss16_cpl3_addr->flags ^= val);
      NONFAILING(tss32_addr->flags ^= val);
      NONFAILING(tss32_cpl3_addr->flags ^= val);
      break;
    case 4:
      seg_cs16.type = val & 0xf;
      seg_cs32.type = val & 0xf;
      seg_cs64.type = val & 0xf;
      break;
    case 5:
      seg_cs16_cpl3.type = val & 0xf;
      seg_cs32_cpl3.type = val & 0xf;
      seg_cs64_cpl3.type = val & 0xf;
      break;
    case 6:
      seg_ds16.type = val & 0xf;
      seg_ds32.type = val & 0xf;
      seg_ds64.type = val & 0xf;
      break;
    case 7:
      seg_ds16_cpl3.type = val & 0xf;
      seg_ds32_cpl3.type = val & 0xf;
      seg_ds64_cpl3.type = val & 0xf;
      break;
    case 8:
      NONFAILING(*(uint64_t*)(host_mem + ADDR_VAR_VMWRITE_FLD) =
                     (val & 0xffff));
      NONFAILING(*(uint64_t*)(host_mem + ADDR_VAR_VMWRITE_VAL) = (val >> 16));
      break;
    default:
      exit(1);
    }
  }
  regs.rflags |= 2;
  fill_segment_descriptor(gdt, ldt, &seg_ldt);
  fill_segment_descriptor(gdt, ldt, &seg_cs16);
  fill_segment_descriptor(gdt, ldt, &seg_ds16);
  fill_segment_descriptor(gdt, ldt, &seg_cs16_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_ds16_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_cs32);
  fill_segment_descriptor(gdt, ldt, &seg_ds32);
  fill_segment_descriptor(gdt, ldt, &seg_cs32_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_ds32_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_cs64);
  fill_segment_descriptor(gdt, ldt, &seg_ds64);
  fill_segment_descriptor(gdt, ldt, &seg_cs64_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_ds64_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_tss32);
  fill_segment_descriptor(gdt, ldt, &seg_tss32_2);
  fill_segment_descriptor(gdt, ldt, &seg_tss32_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_tss32_vm86);
  fill_segment_descriptor(gdt, ldt, &seg_tss16);
  fill_segment_descriptor(gdt, ldt, &seg_tss16_2);
  fill_segment_descriptor(gdt, ldt, &seg_tss16_cpl3);
  fill_segment_descriptor_dword(gdt, ldt, &seg_tss64);
  fill_segment_descriptor_dword(gdt, ldt, &seg_tss64_cpl3);
  fill_segment_descriptor(gdt, ldt, &seg_cgate16);
  fill_segment_descriptor(gdt, ldt, &seg_tgate16);
  fill_segment_descriptor(gdt, ldt, &seg_cgate32);
  fill_segment_descriptor(gdt, ldt, &seg_tgate32);
  fill_segment_descriptor_dword(gdt, ldt, &seg_cgate64);
  if (ioctl(cpufd, KVM_SET_SREGS, &sregs))
    return -1;
  if (ioctl(cpufd, KVM_SET_REGS, &regs))
    return -1;
  return 0;
}

struct thread_t {
  int created, call;
  event_t ready, done;
};

static struct thread_t threads[16];
static void execute_call(int call);
static int running;

static void* thr(void* arg)
{
  struct thread_t* th = (struct thread_t*)arg;
  for (;;) {
    event_wait(&th->ready);
    event_reset(&th->ready);
    execute_call(th->call);
    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
    event_set(&th->done);
  }
  return 0;
}

static void loop(void)
{
  int i, call, thread;
  for (call = 0; call < 13; call++) {
    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
         thread++) {
      struct thread_t* th = &threads[thread];
      if (!th->created) {
        th->created = 1;
        event_init(&th->ready);
        event_init(&th->done);
        event_set(&th->done);
        thread_start(thr, th);
      }
      if (!event_isset(&th->done))
        continue;
      event_reset(&th->done);
      th->call = call;
      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
      event_set(&th->ready);
      event_timedwait(&th->done, 45);
      break;
    }
  }
  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
    sleep_ms(1);
}

uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};

void execute_call(int call)
{
  intptr_t res = 0;
  switch (call) {
  case 0:
    NONFAILING(memcpy((void*)0x20000040, "/dev/kvm\000", 9));
    res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000040ul, 0ul, 0ul);
    if (res != -1)
      r[0] = res;
    break;
  case 1:
    res = syscall(__NR_ioctl, r[0], 0xae01, 0ul);
    if (res != -1)
      r[1] = res;
    break;
  case 2:
    NONFAILING(*(uint32_t*)0x20000280 = 5);
    syscall(__NR_getsockopt, -1, 1, 0x11, 0x20000240ul, 0x20000280ul);
    break;
  case 3:
    NONFAILING(*(uint64_t*)0x20000000 = 0x20000440);
    NONFAILING(memcpy(
        (void*)0x20000440,
        "\xbe\xbc\x37\x57\x34\x17\x94\x4e\x7c\x2e\x03\xcd\x77\xc1\x19\x78\x9d"
        "\x8a\x3b\xd3\x7e\xd0\x60\xd2\xa2\x7a\x9d\x86\x58\x60\x11\x24\xae\xf9"
        "\x30\x66\x01\xe9\xd9\xe9\x10\xd8\x70\x2b\x49\x88\x5e\xea\xe2\xe2\xc7"
        "\x9a\xdb\xe7\xb9\xc6\x9d\x19\x11\x79\xdc\x90\x71\x0a\x5b\x96\x1a\xb5"
        "\x69\x18\xe7\x40\xd6\x48\x4b\xcc\x8e\x02\xdf\xd8\x51\x65\xc2\x05\x5e"
        "\xe6\xca\x47\x38\x0c\x12\x3f\x6a\xfa\x4b\x64\xb1\xbe\x4e\x45\x30\xcb"
        "\xcd\xd8\x0b\x7a\x3b\x36\xed\xea\x7d\xee\x95\x2a\xad\x83\xd7\x14\x12"
        "\xf2\xce\x05\x62\xd7\x5c\xe8\xe7\x8e\x07\xb7\x91\x93\x75\xb7\x38\xda"
        "\xd3\xcd\xad\xfa\x44\x53\x79\x67\x49\xd0\x43\xdc\x48\x8d\xcd\x8b\x99"
        "\x0b\x0a\x2e\x25\xd5\xcc\xcf\xea\x2a\x80\x99\x13\x21\xa4\xc8\x5f\xaa"
        "\x66\x69\x3b\xd9\xe4\x53\x20\x12\xce\x66\xcd\x46\xf6\xdd\x81\x1d\xda"
        "\x1e\x3b\xc4\x0b\x8c\xfe\xbc\x90\x12\xad\x33\x24\xac\x9a\x6e\x40\xc8"
        "\x74\xe1\x66\x53\x6b\x0d\x97\x89\x05\x3e\xf0\x29\xfe\x53\x12\xa3\xfd"
        "\x1d\x05\x47\x88\x10\xb0\x25\xa1\x82\x8a\xa8\xf9\x7e\x8a\x05\xcd\xe7"
        "\x0c\x0b\x0b\x6d\x29\xfa\xfd\xc0\x90\x6e\x31\x15\x84\xac\xb3\x0f\x7f"
        "\x14\x88\x09\xfd\x56\xe0\x45\x5f\xb6\x3c\x99\x71\x5e\xa6\xb5\xbb\x10"
        "\xdf\x74\x1e\x63\xe6\xbe\x60\xdd\x7b\xfd\x7a\x2d\x42\x3f\x17\x61\xa8"
        "\x4d\x33\xaf\x84\xec\x9f\x51\xf9\x41\x4d\xd1\x4f\x7a\x78\x25\x22\x2f"
        "\xaa\xf0\x74\x1d\x47\x26\xb7\x46\x59\xd3\x18\x17\x72\x37\x3e\xac\x23"
        "\x47\x3a\xc2\x28\x85\x9a\x0a\xb8\xf1\xb6\x81\x46\x37\xdc\x7f\x88\xb9"
        "\x01\x50\x58\xa8\x7a\x0a\xa1\xce\x52\xf1\x74\xb9\x40\xae\xed\x39\xb8"
        "\x42\xfe\x52\x81\x3d\x1d\xff\x14\x93\x37\x9e\x14\xb2\xd1\x88\xcf\xb1"
        "\x9c\xe1\x41\xfa\xaf\x36\x1e\x08\xc4\x1a\xfe\xd6\xae\xb6\x86\x94\x72"
        "\x5e\x4a\x7d\xa9\x44\x4d\x94\xdd\xf8\xa0\xa9\x00\x66\x02\x44\x47\xab"
        "\x1d\x3a\xc4\xa4\xd2\x15\x90\x47\x39\x1e\xe9\xd1\xed\xb2\x51\x6d\x40"
        "\xfb\xc9\x27\x69\x57\x80\x45\x63\xea\x7f\x1a\xcc\x92\x85\x4b\x12\xbb"
        "\x8b\xa2\x4c\xda\x6f\x11\x33\x5e\xa7\xb8\x84\x91\x88\x38\x20\xe6\x37"
        "\xaf\xcf\x7d\xf7\xbc\xec\x46\x11\xb4\xa5\x32\x12\x35\x33\xb5\x9f\xd6"
        "\xe6\x75\x8b\x02\x26\x5d\x51\xc4\xb6\xe9\xf3\x5a\x07\x9f\xe9\x3d\x73"
        "\x88\x99\x10\xe6\x06\xf5\x49\x9f\x6b\x0e\x2c\x69\xf0\xad\x2d\x53\x30"
        "\x25\x4e\x9f\xc0\x1e\x1c\xf6\x07\x8e\x49\x92\x08\xa4\x4a\x7f\x9d\xec"
        "\x43\xb1\xd1\x9a\xd6\x2b\x11\xbf\x0d\xdd\xf8\xc0\x8b\x02\xae\x24\xb7"
        "\x71\xf3\x0b\xf2\x80\x90\x3e\x9d\xf9\xb9\x76\x27\xf3\x0e\x81\xe0\x85"
        "\xf7\xce\x8f\x0e\x54\x05\x00\xee\xaf\x2a\xf1\x3b\x94\x5f\xf7\x92\xfb"
        "\x0f\x73\x30\xc1\x3e\x5d\x39\x93\x05\xd1\x92\x54\x88\x1a\xd5\xde\xe5"
        "\x92\x32\xc1\xc5\x4e\x7d\x06\x8f\xdd\xfa\xc6\x91\x05\xf3\x14\xd6\xbc"
        "\xd1\x95\x9f\xd5\xd6\x7d\xd7\x19\x8f\x6b\x69\x12\x44\x7b\x81\x6b\x09"
        "\x18\x15\xa1\xcd\x1f\xc4\x76\x5f\x25\xb8\xe6\x97\x44\x19\xd2\x72\xa9"
        "\x9b\xad\xb9\xb2\x26\xf8\xbf\x7c\xf3\xa7\xfd\xc6\x70\x89\x9d\x3f\x5a"
        "\x0f\x78\x5c\xf6\x86\xd5\xbf\x9f\x38\x8e\xbb\x5f\x69\x7f\xea\x84\x1e"
        "\xf3\x69\x06\x52\xa6\xb2\xed\xe1\xad\xfc\x23\x47\xb8\xb7\xf9\x89\x7a"
        "\x52\x3a\x34\x22\xb5\xbb\x32\x03\xb2\x2f\xaf\xe5\x99\x6b\x91\xc6\x4d"
        "\xf2\x78\x8d\xc9\xc9\x05\x3c\xe0\xe2\x7f\xcc\x96\x83\x56\x3e\x82\xbd"
        "\x94\x97\xb7\x0c\xfe\x74\x7e\xda\x86\x6b\xde\x0c\xe5\x03\xe1\xaf\xe3"
        "\x29\x60\xdd\xd5\xd2\x6a\x39\x99\x52\x84\x75\x8d\x65\x12\xce\x0e\x12"
        "\x40\x57\x83\x3a\x67\xa0\x09\x6a\x43\x33\x6e\xd6\xcf\x5a\xe9\x06\x37"
        "\x83\x46\x60\x6e\x27\xeb\x63\xed\xe5\x0f\x66\x6c\x27\xe0\x0f\x8a\x2a"
        "\xea\x00\x42\xe3\x48\x09\x4f\xbd\x59\x7b\x1e\xc1\x35\x6d\x68\x02\x90"
        "\xc4\x09\x7c\x10\x30\x70\xba\x3d\xf1\x0c\x5c\x74\x45\xf8\x55\x0a\xf1"
        "\x36\x1d\x70\x11\x99\xfc\xfe\x7f\x79\xb4\xf7\xd9\x47\xa0\x6b\x64\xbb"
        "\xf6\x0d\x33\xc0\x30\x6f\x73\xbd\x3f\xb9\xe0\x12\x68\x10\x23\xd2\x34"
        "\xc5\xd8\x92\x77\x02\xe8\xef\x64\x36\x93\xb6\xd6\x70\x79\x11\x77\xbd"
        "\x7b\x31\x73\x1b\xd3\x51\xaa\x1a\x59\xa7\xcd\x11\x60\x77\x2b\x05\x58"
        "\xa9\x6a\x0e\xe2\x1a\xf0\x13\xf0\xd8\x4b\xda\x15\x42\x35\x8e\xf0\xba"
        "\xd0\x52\xf3\x13\x85\x3e\x0f\x32\xb4\x31\x53\x20\x0d\xaa\x4b\xc5\xc4"
        "\xf5\x1a\x31\x4e\xad\x07\x1c\xf6\x7b\xb8\x17\x75\x60\xba\xd8\x93\xff"
        "\x28\x95\x37\x58\x44\x1b\x6b\x2d\x90\x9a\x35\xdb\x8a\xb6\x0a\x7b\xc7"
        "\x98\x52\x4e\xc7\x5a\x53\xd0\xe5\xd4\x3a\xff\x61\x82\x7a\xad\x8b\x75"
        "\x84\x11\x81\x52\xe3\xc7\xdb\xea\x96\x68\x13\x3f\xf5\xce\xd4\xe8\xc7"
        "\x0b\x29\x74\xaf\xac\xa7\x74\xe5\xdc\xcb\xb3\x89\x2a\x20\xc7\x86\x82"
        "\xf8\xb9\xa7\x16\xf3\xbc\x3c\x26\x4b\xa3\xf1\xb5\x88\x2f\x3a\x38\x66"
        "\x93\x85\xba\x6d\xb9\x81\x6c\x9c\xf0\x8f\x46\x2a\x62\x72\xa6\xc3\x76"
        "\x49\xb6\xa4\x08\x26\xab\x7c\xeb\x26\x05\xf6\x9e\x1b\xf6\x5d\x07\x47"
        "\x16\x31\x11\xf6\x89\x7a\x1c\x85\xf1\x0f\x1b\xf4\xa8\xaa\xf9\x6b\x29"
        "\xed\x15\xcd\x32\xfa\x24\xca\xc2\xdd\xda\x49\xd0\xfc\xde\x09\x3c\x10"
        "\xe7\x7f\xbc\xdc\x20\xc5\x65\xef\x2d\xa6\x08\x28\xff\x95\x3f\x2b\x82"
        "\xd7\xed\x15\xc2\x0a\xc2\x78\x17\x08\xbf\x56\xcc\x55\x1a\xe1\xbe\xa9"
        "\x60\xd7\x97\x9f\x55\xfb\xa8\x7b\x67\xe5\xb7\x6e\x48\x64\x85\x03\xf8"
        "\x4d\xb9\xcf\x6d\xd4\x4a\x79\x9e\x28\xda\x88\x52\x08\x2f\x06\x39\x5a"
        "\x5d\xa9\x58\xbe\x0d\x0c\x2b\xa7\x4f\xcf\xdd\xd5\x25\xb5\x65\x50\x2f"
        "\x17\x09\xe5\xf9\xe5\x18\x93\x97\x4c\x89\x0f\x39\xb2\x40\x6c\x11\x14"
        "\x42\xfb\xa9\x0f\x48\x73\x98\x21\xe9\x90\x8f\xd4\x46\xf5\x5a\xae\x6a"
        "\x7c\x00\xae\xc7\xc4\xad\x2d\xaf\xa9\x11\x05\x3f\xf4\x9f\x57\xd7\x9a"
        "\x8b\x0e\xb1\x74\x7f\x40\xeb\x15\xff\xa7\xac\xa8\xfc\x30\x34\x60\xb1"
        "\x6d\x44\x8e\x74\xfa\xe0\x8d\x4b\x74\x34\xa8\x6d\x4f\x6e\x2a\xcb\x6e"
        "\x9c\xca\xc8\xad\x3e\x67\x06\xde\x64\xc7\x50\xd1\x7d\x93\x26\x1a\x2c"
        "\x34\xe6\x9b\x55\x13\x16\x04\xf4\xde\x45\x2c\x6c\x08\xc2\x63\x5d\xee"
        "\x21\xc6\x89\x6c\x9d\x69\x67\x06\x08\x81\x55\x94\x1d\xdb\x00\x6f\x8d"
        "\x7b\x85\x97\x87\x87\xf3\x42\x00\x42\x64\x88\xb4\x33\xb3\xad\x69\x06"
        "\xbb\x95\x0b\x98\x62\x67\x87\x02\x89\xd2\xbf\xfe\x1e\x08\x87\xce\x3d"
        "\x93\x26\xaf\x20\xb6\x6f\xb2\x30\xd4\xac\xe9\x5c\x11\x53\x62\x43\xa3"
        "\xb1\xf1\xea\x00\x10\x8f\x9c\x35\x4a\x16\xad\x3f\xab\x45\xf6\xae\x53"
        "\x6d\x3b\xda\xfa\xd2\x71\x2e\x9f\xf7\x18\x4a\x80\xb7\x55\x5c\xc5\x06"
        "\xb2\xb0\x94\xf0\x1b\x73\xbc\xde\xe9\xcf\xe7\x48\x33\x52\xe1\x96\x34"
        "\x69\x07\xf7\xc0\x79\x31\xbe\xbf\x96\x7e\xe4\x79\x88\x25\xa0\x18\xd3"
        "\x56\x5c\x29\xd2\x72\x05\xe5\x73\x47\xba\x34\x98\xcb\x33\xe9\x26\x80"
        "\x9e\x8a\xc6\x25\xb2\xc5\x2a\xfc\xa8\x70\x5c\x44\xff\x8b\xd3\xe4\x13"
        "\xfc\x32\x60\xdf\xa2\xff\x4a\x09\x9b\xfb\x07\x4c\x4f\x77\x69\x75\x81"
        "\xbb\x27\x1a\x07\x6e\x92\xbf\x8e\x26\xd4\x17\x5e\xe9\x5e\xae\x3a\xf2"
        "\x8a\x9f\xfe\x8a\xbf\x59\x56\x2d\x4a\x8d\x97\x66\x79\x4e\x23\x47\xe6"
        "\xf0\x7d\x76\x42\xa6\x4d\x01\x9b\xf6\xc0\xf9\x6c\x62\x69\xa0\x78\x79"
        "\x76\xb8\xc1\x44\x65\x55\xdc\x66\x98\x3d\x5a\x4f\xfa\x13\xcb\x7f\x5e"
        "\x47\xa0\x14\x2c\xef\x49\xf2\x8e\xab\xe8\xc1\xf3\x04\x5a\x11\x2b\xb8"
        "\x41\xf2\xac\x5e\xa7\x9c\xca\xea\x80\xb6\x0d\xcb\x18\x2e\x5c\x52\x53"
        "\x55\x56\x70\x2e\xef\x9a\x33\x38\xce\x16\x4d\x4f\xbf\x5c\x28\x5d\x15"
        "\xad\x30\x7a\xe8\x63\x15\xf1\xb1\x22\x50\x58\x41\xf7\xd8\xb0\x9e\xc2"
        "\xfa\xcf\x4d\xfb\xc3\xa8\x25\x3b\x5f\x0f\xe4\x4f\xef\x96\x0e\xcf\xfd"
        "\x25\x1e\x8d\xdb\x8f\x56\xb9\xff\xa8\xf1\xda\x23\x89\x61\xea\xfe\xd5"
        "\xfe\xea\x26\x00\x00\xc8\x10\x4a\x96\x54\x1f\x91\x97\xe8\x67\x53\x4e"
        "\x81\xcf\x36\x85\x00\x36\x67\x65\x88\xe2\x3a\x10\x35\x48\x20\x14\x90"
        "\x59\x34\xc9\xd4\x9b\xc3\x02\xbb\x9e\x9f\xba\xf5\x60\x08\xe2\x7c\x38"
        "\x99\xbc\x4c\x56\x79\x7a\x2d\xe5\x08\x87\xe6\xb7\x70\xb8\x48\xac\x30"
        "\x43\x17\xa1\xcf\xe4\x08\x92\x80\x16\x89\x2e\x06\xa5\xd6\x22\x72\x39"
        "\x0f\xa5\xae\xc7\xc4\x5a\x6e\x93\x6d\x20\xff\x00\x9a\x09\x46\xd6\x4a"
        "\xcc\x35\xc5\x42\xe2\xf6\xe4\xc7\xbd\x2c\x0e\x71\xbc\x93\xb7\x6c\x47"
        "\xfe\xb6\x47\x4e\x5a\x9d\x2f\x7b\xe3\xb0\xdd\xc6\x7e\x82\x34\x1d\x2c"
        "\xfe\x83\x14\xc2\xcc\xb5\x87\xb4\xdc\x63\xd1\x0e\xaf\x5e\x13\xaf\xc1"
        "\xed\x0f\xd9\xab\xd4\xf5\x2a\x22\x5c\xf2\xeb\xc5\xcb\xfa\xc1\x92\x44"
        "\x0c\x75\x4f\xbd\x3d\xf5\x89\xe7\x2e\x03\xc0\x5b\x7f\x12\x0c\x85\xaa"
        "\xf8\x2c\x07\xab\x05\x53\x45\xc6\x1a\xb4\x16\xbf\x38\x5d\xbc\xd1\x4c"
        "\x34\xe2\xa2\xe5\x62\x97\x08\x82\xa6\xf8\xe2\xbc\xeb\x8a\x24\xd5\x9c"
        "\x7d\xb4\x0e\xdf\xaf\xb3\xe6\x6f\x44\x49\x6b\x85\x75\xde\x74\x05\xb2"
        "\xd9\xfe\xc4\x2b\x40\xef\x14\x2e\xfe\xc3\x6c\xd2\x71\xb6\x20\x7b\x6c"
        "\x66\x8d\x24\x96\x5d\xe5\xea\xd6\xda\xa8\x61\x67\x9e\x0f\xf9\x71\x85"
        "\xc8\x41\xea\x68\x65\x88\x7c\x43\xfe\x44\xbe\x25\x4d\x2c\xf3\x00\xb5"
        "\xb6\x08\xd1\xbf\x58\xbf\x35\x86\x6e\x10\xb1\x78\xa3\x5c\xf7\x40\xcb"
        "\xff\x0c\x64\x9e\x80\x85\x1f\x13\x0e\x00\xe3\x5e\xa7\x51\xf3\xe2\x8d"
        "\xc8\x35\xf1\x96\x6d\x26\xba\xd8\x2a\xff\x36\x39\x25\xab\x93\x43\x7e"
        "\xa1\x72\xb6\x99\xe7\x2e\x89\x49\xd6\x73\x4f\x35\xb8\x55\x6b\x13\x8d"
        "\xad\xcc\x83\x97\x97\xac\xa2\xa1\xe6\x4f\xb6\x33\x69\xa2\x00\x07\x50"
        "\x7b\x8a\xf4\x5c\xc0\xc6\x6f\x6d\xed\x5d\x45\xe1\xc8\x18\xbc\x89\xde"
        "\x4c\xe4\x29\x8f\x09\x8e\x35\xfb\xae\xcc\xd6\x5e\x65\x08\x49\x5a\xcf"
        "\xf2\x29\x80\xbc\x32\x29\xfa\x86\x3f\xaf\x48\xe5\x0b\xe1\xbe\xf3\x52"
        "\xc0\x37\x18\x74\xa6\xdc\x41\x79\x9a\xc6\x68\x6d\x80\xf2\x14\xc9\x00"
        "\xd6\xcb\x03\x76\x92\x55\x53\x72\x46\xdc\x3d\xb2\xe6\x1e\x11\x97\x45"
        "\x04\x4f\x5a\x52\x38\x9d\xba\xbe\x15\x3e\xfc\xfc\xb0\xb6\xd3\xff\x77"
        "\x9a\x36\x7e\x99\xa5\x5b\x04\x6a\xec\x47\x71\x5b\x32\xa3\x4b\x69\x3b"
        "\xf2\x59\x1b\xa7\x1c\x0a\x03\xe1\x82\x0f\xc9\xca\xcd\x15\xf2\xa0\xf5"
        "\xfb\xcb\x8d\x6f\x14\x01\xe3\x19\x89\x10\xee\x24\x14\x63\x62\x7e\x22"
        "\x09\x31\x78\xa4\x4c\x6a\xb0\x03\x04\x36\xfb\xb4\xbc\xf5\x80\x27\x61"
        "\x20\xfc\x79\xb9\x7f\xb2\xd7\x3b\x9f\x26\xa1\xd4\xd3\x7d\xa7\xdb\x64"
        "\xca\xa8\xb9\xf3\x0f\xb1\x00\x2d\x5e\x1e\xaf\x73\x73\x73\xa9\xf2\x03"
        "\x73\x25\x47\xc4\xad\x65\xd4\x0f\xa9\x1d\xd0\xe0\x84\xc5\xdf\xce\x72"
        "\xe4\x81\x34\x99\x88\x47\x4a\x44\x3a\x15\xfd\x0b\x38\x0f\xd1\x93\x43"
        "\x46\xb1\xbd\x4c\xee\x07\xc0\x21\x31\x3d\xc6\x9e\xb6\x88\x8b\xf1\x13"
        "\xc4\x14\x31\x0c\x7a\xd2\xbc\xd7\xe9\x06\x63\x46\x8d\x9d\x6c\xd5\xa3"
        "\x13\x7d\x45\x92\xfc\x7b\xbc\xd0\x76\xcf\xda\x7d\x7a\x84\x65\x12\x02"
        "\x59\x79\xc9\x32\x16\xf0\x46\xa6\xb4\xf7\x78\x07\xa1\x7c\xaa\x18\x3f"
        "\xd8\x85\xa9\x96\x46\x61\x2f\x9f\x5c\x61\x22\x81\xf4\xb0\x8f\x86\xb8"
        "\xac\x2f\xcb\x86\x95\xa6\xdc\xdc\x82\xe1\x9c\xb2\x39\xb6\xb7\x57\xab"
        "\xf7\xbb\x93\xc1\xa3\xa0\xc7\x0f\x05\xfd\x48\x84\xb1\x9c\x65\x60\xf1"
        "\xe2\x33\xca\x3d\x03\x15\x63\x38\x40\x4a\x5b\x29\xfb\x34\xcb\x96\xcc"
        "\x2c\x21\xea\x5b\xfd\x77\x6a\xb4\xc9\x00\xf6\x32\x49\x41\x7d\xf6\x3d"
        "\x30\x1c\x7c\x78\x9a\x08\xcf\xce\xdb\x44\xa1\x0d\xd7\x42\x65\xaf\xde"
        "\xeb\x84\xb3\xbb\x73\xd4\x5d\x63\x2b\x96\x95\x99\x1d\x41\x6b\x0d\x84"
        "\x76\x4e\xf8\x92\x59\x63\x2a\xe9\x61\xc1\x07\x47\xe9\x9f\x98\x65\x89"
        "\xf9\x28\x7e\x20\xb2\x61\x6f\xc3\xc6\xc4\xfc\x3e\x51\x88\x8c\x86\x8b"
        "\x18\xb1\x17\xfe\x3c\x7b\x37\x76\x0b\xd3\x24\x61\x4c\x72\x38\xd4\x33"
        "\xf3\x88\x53\x46\x87\x1a\x37\x46\xc6\xca\x98\x3c\x47\x12\xe9\x76\x2b"
        "\x57\xcf\x57\x0f\x42\xe9\xaf\xe9\x54\x33\x87\x83\xd4\x79\xfa\x3a\xf9"
        "\xcc\xc3\xf4\xbb\x90\xac\x2c\x0e\x4e\x25\x3e\x7b\x54\xbf\x59\x4a\x49"
        "\xd2\xf9\x9b\x9f\x1d\x2b\x4b\x5f\x33\xe1\x47\x2e\x46\x99\x01\x0a\x56"
        "\x28\x33\x90\x54\x93\xdf\xda\x63\x21\x6a\xb2\x68\x46\xb0\x76\xfc\x80"
        "\x29\x14\x52\xf4\x31\x4c\x2a\x6b\x52\x47\x3a\xf7\xa9\x13\x33\x43\x00"
        "\x6e\x62\xce\x7f\x0a\x96\x96\xe8\xf4\xc8\x74\xaf\x2e\xc0\x34\x27\x1e"
        "\x64\x4e\xd0\xb1\xd5\x4b\xda\x45\x7e\x83\xe9\xed\x2e\xc4\xab\x13\x18"
        "\x72\x67\x29\x81\x1f\xe8\x82\x8f\x28\xc1\x87\x27\xd1\x95\xc5\xf4\x69"
        "\x80\x18\x2e\x79\x0a\xd9\x74\xc9\x41\x8a\xa5\x2a\x1b\x24\xb4\x87\xc9"
        "\xf5\x27\xa8\x29\x0b\x45\x5d\x75\x96\x88\xf3\x48\xf3\x81\x5a\xf2\x9d"
        "\x19\x72\x96\x17\x3e\x02\x76\x50\xc0\xf0\x0d\xa2\xe4\xa2\x46\xdc\x42"
        "\x34\x3e\xf6\xf9\x98\xb0\x87\x43\x81\x3d\x2d\xdb\x9d\x6c\x9b\xbe\x46"
        "\x21\x30\x0d\x0d\xd1\x55\x60\xda\x9f\x34\xc0\x7f\xe2\x1f\x1e\x31\x0b"
        "\xe5\xfe\x93\x6b\x67\x23\xbd\xa2\x66\x12\x2d\x38\x31\xab\xa4\x33\xa3"
        "\x95\x1b\x92\x99\x0d\x05\x46\x04\x8c\xfd\x73\x1a\x5d\x18\xff\xa8\xe9"
        "\x35\xd6\xa1\xdd\x56\x76\x3f\x4c\xaa\x28\x48\xba\x46\x78\x8a\x8e\xc2"
        "\x96\x08\xd2\x5c\x46\x3d\x9d\x6c\xde\xd4\x5a\xe8\xa3\xd0\xf3\xb3\xb9"
        "\xac\xa3\xff\x94\xe2\x32\x81\xff\x8c\xf5\x00\xa2\x45\xfc\x78\x4c\x5a"
        "\xfb\xd2\x26\xf9\xbe\xcd\x9f\xbe\xd3\xdd\xd4\x4a\xa2\x6c\xe1\xc5\xb8"
        "\xbb\xfd\x43\x3a\x71\x63\xbf\x5f\x28\x01\x39\x24\x4c\xc7\xe5\x0f\x84"
        "\xc7\x73\x58\x8c\x0a\x2f\x58\x62\x7a\x24\xdb\x7d\x3d\x5b\xd1\x7f\x32"
        "\x07\x2e\x83\x00\xbd\xd0\x34\x4d\x70\x80\xb9\x87\x73\x43\xf2\x41\xa1"
        "\xf0\x20\x26\xb9\xb8\x39\x92\x67\xe2\xea\x58\x8c\x01\xab\x0a\x3e\x0f"
        "\x94\x2e\x37\xa0\x51\xfa\x66\xfd\x14\x8d\xd4\x8a\x80\x4a\x5f\xf8\x0b"
        "\x5a\xc6\xbf\xe2\x70\x83\xe1\x15\x45\xec\xa3\xe4\x03\xa0\xce\x4a\xce"
        "\x2a\x24\xc6\x05\x8b\x2d\xc7\x52\x26\x26\x0e\xac\xf5\x22\x4c\xe1\x87"
        "\x43\xf5\x4e\x19\xf8\xdb\xb5\xb0\x07\x78\x48\xb9\x99\xa0\x36\x07\x7f"
        "\xe2\xfb\x4e\xfc\xf7\xe0\x35\x38\xdf\xe7\x9d\x1f\xbe\xd1\x37\xd8\xc1"
        "\x5c\x84\x69\x4d\x58\x2c\x7e\x5b\x0e\x6b\xcb\x8c\xab\x04\x09\x7a\x2e"
        "\x82\x4f\xb2\x5c\x6b\x5d\x55\x06\xe3\xe4\x08\x6a\x69\x4d\x28\x1c\xcd"
        "\xac\x65\xe9\x6e\xdd\xaf\x13\x1d\x46\xf2\xad\x51\x05\xe1\xcc\xbb\x1b"
        "\xbd\x92\x39\xcd\x73\xec\x10\x5c\x8d\x16\x36\xcc\x30\x94\x70\x1c\xe8"
        "\x26\xc1\xf2\x33\x1e\x4d\x85\x87\x0b\x76\x39\xe4\xe2\xcb\x4e\x13\x65"
        "\x1b\x1b\x66\xc5\x58\xdf\x71\xd2\x88\x18\x7c\x8b\xba\xf7\x13\x76\x89"
        "\xd6\x32\x49\x31\xcc\xe2\x2e\xec\x30\x0b\xb2\x08\x3e\x2a\xbf\x27\x4d"
        "\xd3\xf3\x43\x09\x04\x0a\xa0\x06\x71\x12\x77\x65\x7c\x1b\x1f\xf5\x52"
        "\x6d\x76\x5c\xac\xbf\x91\xb2\x2c\xdc\x75\x5e\xd4\x49\x01\x50\x8c\x10"
        "\xde\x33\x3d\xd1\x26\xfc\x4b\x89\x0c\xc9\xcb\x03\x5a\x6d\xdf\x91\x5e"
        "\xcc\x3c\x80\x5a\x9b\xff\x67\xd9\x01\xe4\xf5\xae\xb4\x35\x3c\x5e\xd1"
        "\xef\x6f\x92\x59\x0b\x03\x62\xac\xae\x8a\x8a\x54\xb3\x95\x9d\x54\x2a"
        "\x58\x84\x32\x11\x2a\xaa\x7a\x8a\x29\x79\x30\xa3\x52\x65\x6f\x4e\x55"
        "\x65\xc1\x0d\xbb\xcd\xff\xdd\xf6\x12\x5a\x4d\x2c\x10\x43\xf2\xfe\xb6"
        "\xd3\x1e\x3a\xcc\x9c\xe2\xc9\xe3\x74\xb2\x8c\x60\x2b\x01\xca\xb7\x27"
        "\x68\x65\x8b\x77\xbd\x7e\x07\x06\xce\xa5\xdc\x06\x9f\xd7\x00\xb0\xe2"
        "\x9a\xd0\x4e\xab\xd8\xfd\x57\x9a\x80\xc3\xf3\x94\x82\xd3\xac\x33\x85"
        "\x74\xe0\xc5\x48\xe4\x5f\xa6\x49\x87\x3e\xd7\xa6\x84\xdc\xe4\x3f\x5b"
        "\xd0\x23\xb5\xaa\x5e\xeb\x52\xf8\xc0\x8d\xce\xef\x86\x44\xd8\xc5\x53"
        "\xcb\x45\xd6\xbb\x0a\xa1\xc7\xad\xc9\x28\xd4\x7c\xed\x61\xa1\x7e\xed"
        "\x3d\x86\x9b\x92\x68\xde\xcd\x67\xa7\x2a\xa8\x44\xc9\xe0\x5e\xba\x7a"
        "\x88\xd9\xbd\xcd\xd7\x85\x17\xa2\x7e\x2c\x4c\x20\x21\xd5\x89\xad\x84"
        "\x8f\x1c\x37\xd5\x2e\x40\xfc\x8c\x04\x30\xb4\x9b\x3d\x15\xcc\x9d\x7e"
        "\xc4\x12\x3f\xee\x31\x4d\xc5\xe6\x7f\xfb\xa1\x3a\xfb\x85\xee\x7c\x3b"
        "\x8f\x0b\xe2\x3b\x80\x1a\x7a\x56\xfc\xcf\x28\x18\x80\xed\x00\xe4\x6f"
        "\x42\x5f\x33\xc9\xc7\x26\x9e\x91\x85\x85\x16\x25\xff\x2c\x93\xd9\x4f"
        "\x2c\x6c\xfb\x54\x37\x6f\x4a\x09\x45\xe2\xaa\xae\x69\xb2\x78\x77\xd0"
        "\x34\xaf\xce\xbb\x5a\x44\x27\xaf\x74\x94\x9a\x0e\x1c\x26\xed\x29\x5e"
        "\x59\xb0\xe7\xad\x35\x05\x28\xb8\xe5\xfa\xf8\x62\xab\x81\xe8\x70\x0c"
        "\x25\x99\x0e\x7d\x3b\x86\x87\x51\x3a\x05\x9c\xee\x1d\x31\x6a\xac\xb7"
        "\xf0\x66\x85\x1d\xb7\xf4\x6e\xca\x8f\x7e\xf0\x9c\xf5\x5a\x38\x6b\x09"
        "\x21\xcf\x62\xa0\x05\x92\x08\x88\x51\x2e\x9d\xe8\x60\x66\x96\xe3\x20"
        "\x66\x7c\xe5\x94\x98\x7b\xe2\x5a\x3b\x4e\x0e\xc1\xbf\xa7\x99\xb1\xbe"
        "\xb2\x3b\x32\xeb\x6e\xf3\x0b\x9b\x6b\xd4\x1f\x5f\xea\x79\x2a\xfd\x38"
        "\x37\x85\xd3\xbc\x22\xa6\xa4\xec\x99\xf6\x95\x4e\xd1\x81\x93\xd4\xbd"
        "\x34\x00\x7e\xb6\xa3\xa7\xc0\x86\x7f\x00\x01\x95\xd9\x72\xcb\xef\xd7"
        "\x1a\xbc\xe2\xaa\xfd\x34\x6b\x78\x6b\xb0\xa4\xd7\xc7\x19\x92\xbb\x25"
        "\xd8\xde\xdf\xa1\xb2\xe0\xf0\x81\xf0\xa7\x48\x1a\xcd\x86\xbf\xf7\x8b"
        "\x34\xa2\x3a\x7d\xc7\xdb\x92\x02\x6d\xd1\xeb\xcf\x59\xd0\x4e\x99\x10"
        "\x6a\xd4\x6e\xcc\x04\x68\x1a\xf6\x7b\xef\x18\x89\x60\xbd\x77\x22\x9a"
        "\x88\x14\x92\xee\xb2\xba\xfe\x5c\x22\x4b\xe2\x8e\x33\x9b\x54\xc5\x3c"
        "\x4f\xb4\x32\xbb\xe2\x44\xb2\x59\x88\x99\xfc\x9f\xfc\x32\x76\xc5\xa6"
        "\x32\x5a\x58\x2b\x60\xe9\x78\x89\x33\x04\x0a\xf7\x81\x5d\xf6\x81\x7c"
        "\xdb\xd4\xb6\x40\xcd\xd2\xa9\xa4\xcb\x93\x89\xec\x7b\x93\x83\x9a\xe9"
        "\xf0\x0c\xdd\xc4\x22\x94\xda\x71\xb9\x35\x87\x08\x41\xde\xbe\xba\x96"
        "\x08\x71\x22\x1b\x47\x06\x8a\xe1\xbe\x19\x96\xfb\xbb\x59\xb1\xc4\x47"
        "\xb7\x57\x3f\x86\x01\xac\xa2\x23\xff\xcc\xdd\xc1\x8b\x64\xec\x92\x76"
        "\x0c\x84\x7b\x11\x2a\x8f\xe7\xbb\x1d\xee\x83\xc7\x40\xe5\x98\xa7\x0d"
        "\xca\xe0\x06\x0f\x0d\xc8\x1f\x34\xc0\xaa\x9d\x63\x26\x80\xb4\x54\x7f"
        "\xbe\x8f\x31\x45\x46\xbc\x1f\x1c\xdf\x5d\xd2\xd6\x32\x08\xb4\xf7\x99"
        "\x1a\x00\x69\x48\x6e\xae\x07\xcf\xed\x63\xae\xbc\xb7\x37\x0d\x0a\x92"
        "\x3b\x3c\x07\x4d\x5b\x7f\xae\x5f\x5d\x7f\xb0\xe4\x30\xa9\xc0\x77\xc8"
        "\xd4\x71\x56\x62\x6d\xf0\xc9\xee\x4c\x18\xe4\x29\x4b\xa7\xde\xdb\x9f"
        "\x84\x7e\x27\x67\xdf\x89\x87\x74\x5d\xd4\xe7\xa4\xea\xf0\x3b\x69\x56"
        "\x76\x87\x9b\xfa\x0b\x96\xcb\x18\x46\x45\x96\x3f\x9a\x9e\xa7\x0a\xa3"
        "\xb1\x32\x82\x37\xf5\xd8\xe5\x08\x57\x1d\x6e\x06\xc7\xe7\x59\x0a\x8b"
        "\x79\x56\x7c\x39\x19\x5b\xff\xc8\x3c\x81\x05\x5d\x17\x0c\x59\x21\x9d"
        "\xc2\x67\x56\xb1\xe7\x2e\x64\xd3\x2e\x12\x47\x81\x2e\x18\x69\x4b\xf4"
        "\xe6\x2f\xe6\x5d\x5c\x14\x85\xb5\x9e\xff\xa2\x89\xbc\x93\x9c\xe4\xb2"
        "\xc9\xa0\xbb\x35\x3b\x6f\x0c\xa5\x29\xb9\x0f\xc4\x7b\x87\x76\xbe\x1b"
        "\x03\x6a\x63\xda\x93\x4b\xac\x5a\x5f\xb9\x1a\xf7\x4b\xa1\x12\x88\x82"
        "\xbd\xa6\x02\xa8\xa0\x5e\x2c\x89\x0e\x52\xf2\xe6\x27\x27\x54\x06\xfc"
        "\xb7\x01\x60\x84\x69\xab\x5a\x0c\xd5\x77\x43\xae\xf6\x3a\x33\xa7\xed"
        "\xba\x34\x33\xef\xa5\xc4\x9d\x03\xe2\x0b\x17\xe2\x21\xf1\xcc\x45",
        4096));
    NONFAILING(*(uint64_t*)0x20000008 = 0x1000);
    syscall(__NR_writev, -1, 0x20000000ul, 1ul);
    break;
  case 4:
    res = syscall(__NR_ioctl, r[1], 0xae41, 0ul);
    if (res != -1)
      r[2] = res;
    break;
  case 5:
    NONFAILING(*(uint32_t*)0x20000400 = 0);
    NONFAILING(*(uint32_t*)0x20000404 = 3);
    NONFAILING(*(uint64_t*)0x20000408 = 0);
    NONFAILING(*(uint64_t*)0x20000410 = 0x2000);
    NONFAILING(*(uint64_t*)0x20000418 = 0x20000000);
    syscall(__NR_ioctl, r[1], 0x4020ae46, 0x20000400ul);
    break;
  case 6:
    NONFAILING(*(uint32_t*)0x20000040 = 0);
    NONFAILING(*(uint32_t*)0x20000044 = 0x70);
    NONFAILING(*(uint8_t*)0x20000048 = 3);
    NONFAILING(*(uint8_t*)0x20000049 = 0);
    NONFAILING(*(uint8_t*)0x2000004a = 0);
    NONFAILING(*(uint8_t*)0x2000004b = 0);
    NONFAILING(*(uint32_t*)0x2000004c = 0);
    NONFAILING(*(uint64_t*)0x20000050 = 0);
    NONFAILING(*(uint64_t*)0x20000058 = 0);
    NONFAILING(*(uint64_t*)0x20000060 = 0);
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 0, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 1, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 2, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 3, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 4, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 5, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 6, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 7, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 8, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 9, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 10, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 11, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 12, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 13, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 14, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 15, 2));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 17, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 18, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 19, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 20, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 21, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 22, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 23, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 24, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 25, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 26, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 27, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 28, 1));
    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000068, 0, 29, 35));
    NONFAILING(*(uint32_t*)0x20000070 = 0);
    NONFAILING(*(uint32_t*)0x20000074 = 0);
    NONFAILING(*(uint64_t*)0x20000078 = 0);
    NONFAILING(*(uint64_t*)0x20000080 = 0);
    NONFAILING(*(uint64_t*)0x20000088 = 0);
    NONFAILING(*(uint64_t*)0x20000090 = 0);
    NONFAILING(*(uint32_t*)0x20000098 = 0);
    NONFAILING(*(uint32_t*)0x2000009c = 0);
    NONFAILING(*(uint64_t*)0x200000a0 = 0);
    NONFAILING(*(uint32_t*)0x200000a8 = 0);
    NONFAILING(*(uint16_t*)0x200000ac = 0);
    NONFAILING(*(uint16_t*)0x200000ae = 0);
    syscall(__NR_perf_event_open, 0x20000040ul, 0, 0ul, -1, 0ul);
    break;
  case 7:
    syz_kvm_setup_cpu(r[1], -1, 0x20000000, 0, 0, 0, 0, 0);
    break;
  case 8:
    NONFAILING(*(uint64_t*)0x20000180 = 0x200000c0);
    NONFAILING(*(uint16_t*)0x200000c0 = 0x10);
    NONFAILING(*(uint16_t*)0x200000c2 = 0);
    NONFAILING(*(uint32_t*)0x200000c4 = 0);
    NONFAILING(*(uint32_t*)0x200000c8 = 0);
    NONFAILING(*(uint32_t*)0x20000188 = 0xc);
    NONFAILING(*(uint64_t*)0x20000190 = 0x20000100);
    NONFAILING(*(uint64_t*)0x20000100 = 0x20001440);
    NONFAILING(*(uint64_t*)0x20000108 = 0x14);
    NONFAILING(*(uint64_t*)0x20000198 = 1);
    NONFAILING(*(uint64_t*)0x200001a0 = 0);
    NONFAILING(*(uint64_t*)0x200001a8 = 0);
    NONFAILING(*(uint32_t*)0x200001b0 = 0x40000);
    syscall(__NR_sendmsg, -1, 0x20000180ul, 0ul);
    break;
  case 9:
    NONFAILING(*(uint64_t*)0x200001c0 = 0);
    NONFAILING(*(uint32_t*)0x200001c8 = 0x11d000);
    NONFAILING(*(uint32_t*)0x200001cc = 0);
    syscall(__NR_ioctl, r[1], 0x4010ae67, 0x200001c0ul);
    break;
  case 10:
    syscall(__NR_ioctl, r[2], 0xae9a, 0);
    break;
  case 11:
    syscall(__NR_ioctl, r[2], 0xae80, 0ul);
    break;
  case 12:
    syscall(__NR_ioctl, r[2], 0xae80, 0ul);
    break;
  }
}
int main(void)
{
  syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  install_segv_handler();
  loop();
  return 0;
}