linux/arch/arm64/kvm/sys_regs.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (C) 2012,2013 - ARM Ltd
   4 * Author: Marc Zyngier <marc.zyngier@arm.com>
   5 *
   6 * Derived from arch/arm/kvm/coproc.h
   7 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
   8 * Authors: Christoffer Dall <c.dall@virtualopensystems.com>
   9 */
  10
  11#ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
  12#define __ARM64_KVM_SYS_REGS_LOCAL_H__
  13
  14struct sys_reg_params {
  15        u8      Op0;
  16        u8      Op1;
  17        u8      CRn;
  18        u8      CRm;
  19        u8      Op2;
  20        u64     regval;
  21        bool    is_write;
  22        bool    is_aarch32;
  23        bool    is_32bit;       /* Only valid if is_aarch32 is true */
  24};
  25
  26struct sys_reg_desc {
  27        /* Sysreg string for debug */
  28        const char *name;
  29
  30        /* MRS/MSR instruction which accesses it. */
  31        u8      Op0;
  32        u8      Op1;
  33        u8      CRn;
  34        u8      CRm;
  35        u8      Op2;
  36
  37        /* Trapped access from guest, if non-NULL. */
  38        bool (*access)(struct kvm_vcpu *,
  39                       struct sys_reg_params *,
  40                       const struct sys_reg_desc *);
  41
  42        /* Initialization for vcpu. */
  43        void (*reset)(struct kvm_vcpu *, const struct sys_reg_desc *);
  44
  45        /* Index into sys_reg[], or 0 if we don't need to save it. */
  46        int reg;
  47
  48        /* Value (usually reset value) */
  49        u64 val;
  50
  51        /* Custom get/set_user functions, fallback to generic if NULL */
  52        int (*get_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
  53                        const struct kvm_one_reg *reg, void __user *uaddr);
  54        int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
  55                        const struct kvm_one_reg *reg, void __user *uaddr);
  56
  57        /* Return mask of REG_* runtime visibility overrides */
  58        unsigned int (*visibility)(const struct kvm_vcpu *vcpu,
  59                                   const struct sys_reg_desc *rd);
  60};
  61
  62#define REG_HIDDEN_USER         (1 << 0) /* hidden from userspace ioctls */
  63#define REG_HIDDEN_GUEST        (1 << 1) /* hidden from guest */
  64
  65static __printf(2, 3)
  66inline void print_sys_reg_msg(const struct sys_reg_params *p,
  67                                       char *fmt, ...)
  68{
  69        va_list va;
  70
  71        va_start(va, fmt);
  72        /* Look, we even formatted it for you to paste into the table! */
  73        kvm_pr_unimpl("%pV { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), func_%s },\n",
  74                      &(struct va_format){ fmt, &va },
  75                      p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, p->is_write ? "write" : "read");
  76        va_end(va);
  77}
  78
  79static inline void print_sys_reg_instr(const struct sys_reg_params *p)
  80{
  81        /* GCC warns on an empty format string */
  82        print_sys_reg_msg(p, "%s", "");
  83}
  84
  85static inline bool ignore_write(struct kvm_vcpu *vcpu,
  86                                const struct sys_reg_params *p)
  87{
  88        return true;
  89}
  90
  91static inline bool read_zero(struct kvm_vcpu *vcpu,
  92                             struct sys_reg_params *p)
  93{
  94        p->regval = 0;
  95        return true;
  96}
  97
  98/* Reset functions */
  99static inline void reset_unknown(struct kvm_vcpu *vcpu,
 100                                 const struct sys_reg_desc *r)
 101{
 102        BUG_ON(!r->reg);
 103        BUG_ON(r->reg >= NR_SYS_REGS);
 104        __vcpu_sys_reg(vcpu, r->reg) = 0x1de7ec7edbadc0deULL;
 105}
 106
 107static inline void reset_val(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 108{
 109        BUG_ON(!r->reg);
 110        BUG_ON(r->reg >= NR_SYS_REGS);
 111        __vcpu_sys_reg(vcpu, r->reg) = r->val;
 112}
 113
 114static inline bool sysreg_hidden_from_guest(const struct kvm_vcpu *vcpu,
 115                                            const struct sys_reg_desc *r)
 116{
 117        if (likely(!r->visibility))
 118                return false;
 119
 120        return r->visibility(vcpu, r) & REG_HIDDEN_GUEST;
 121}
 122
 123static inline bool sysreg_hidden_from_user(const struct kvm_vcpu *vcpu,
 124                                           const struct sys_reg_desc *r)
 125{
 126        if (likely(!r->visibility))
 127                return false;
 128
 129        return r->visibility(vcpu, r) & REG_HIDDEN_USER;
 130}
 131
 132static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
 133                              const struct sys_reg_desc *i2)
 134{
 135        BUG_ON(i1 == i2);
 136        if (!i1)
 137                return 1;
 138        else if (!i2)
 139                return -1;
 140        if (i1->Op0 != i2->Op0)
 141                return i1->Op0 - i2->Op0;
 142        if (i1->Op1 != i2->Op1)
 143                return i1->Op1 - i2->Op1;
 144        if (i1->CRn != i2->CRn)
 145                return i1->CRn - i2->CRn;
 146        if (i1->CRm != i2->CRm)
 147                return i1->CRm - i2->CRm;
 148        return i1->Op2 - i2->Op2;
 149}
 150
 151const struct sys_reg_desc *find_reg_by_id(u64 id,
 152                                          struct sys_reg_params *params,
 153                                          const struct sys_reg_desc table[],
 154                                          unsigned int num);
 155
 156#define Op0(_x)         .Op0 = _x
 157#define Op1(_x)         .Op1 = _x
 158#define CRn(_x)         .CRn = _x
 159#define CRm(_x)         .CRm = _x
 160#define Op2(_x)         .Op2 = _x
 161
 162#define SYS_DESC(reg)                                   \
 163        .name = #reg,                                   \
 164        Op0(sys_reg_Op0(reg)), Op1(sys_reg_Op1(reg)),   \
 165        CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)),   \
 166        Op2(sys_reg_Op2(reg))
 167
 168#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */
 169