linux/arch/arm64/kvm/guest.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012,2013 - ARM Ltd
   3 * Author: Marc Zyngier <marc.zyngier@arm.com>
   4 *
   5 * Derived from arch/arm/kvm/guest.c:
   6 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
   7 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#include <linux/errno.h>
  23#include <linux/err.h>
  24#include <linux/kvm_host.h>
  25#include <linux/module.h>
  26#include <linux/vmalloc.h>
  27#include <linux/fs.h>
  28#include <asm/cputype.h>
  29#include <asm/uaccess.h>
  30#include <asm/kvm.h>
  31#include <asm/kvm_asm.h>
  32#include <asm/kvm_emulate.h>
  33#include <asm/kvm_coproc.h>
  34
  35struct kvm_stats_debugfs_item debugfs_entries[] = {
  36        { NULL }
  37};
  38
  39int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
  40{
  41        vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
  42        return 0;
  43}
  44
  45static u64 core_reg_offset_from_id(u64 id)
  46{
  47        return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
  48}
  49
  50static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
  51{
  52        /*
  53         * Because the kvm_regs structure is a mix of 32, 64 and
  54         * 128bit fields, we index it as if it was a 32bit
  55         * array. Hence below, nr_regs is the number of entries, and
  56         * off the index in the "array".
  57         */
  58        __u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
  59        struct kvm_regs *regs = vcpu_gp_regs(vcpu);
  60        int nr_regs = sizeof(*regs) / sizeof(__u32);
  61        u32 off;
  62
  63        /* Our ID is an index into the kvm_regs struct. */
  64        off = core_reg_offset_from_id(reg->id);
  65        if (off >= nr_regs ||
  66            (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
  67                return -ENOENT;
  68
  69        if (copy_to_user(uaddr, ((u32 *)regs) + off, KVM_REG_SIZE(reg->id)))
  70                return -EFAULT;
  71
  72        return 0;
  73}
  74
  75static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
  76{
  77        __u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
  78        struct kvm_regs *regs = vcpu_gp_regs(vcpu);
  79        int nr_regs = sizeof(*regs) / sizeof(__u32);
  80        __uint128_t tmp;
  81        void *valp = &tmp;
  82        u64 off;
  83        int err = 0;
  84
  85        /* Our ID is an index into the kvm_regs struct. */
  86        off = core_reg_offset_from_id(reg->id);
  87        if (off >= nr_regs ||
  88            (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
  89                return -ENOENT;
  90
  91        if (KVM_REG_SIZE(reg->id) > sizeof(tmp))
  92                return -EINVAL;
  93
  94        if (copy_from_user(valp, uaddr, KVM_REG_SIZE(reg->id))) {
  95                err = -EFAULT;
  96                goto out;
  97        }
  98
  99        if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
 100                u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
 101                switch (mode) {
 102                case COMPAT_PSR_MODE_USR:
 103                case COMPAT_PSR_MODE_FIQ:
 104                case COMPAT_PSR_MODE_IRQ:
 105                case COMPAT_PSR_MODE_SVC:
 106                case COMPAT_PSR_MODE_ABT:
 107                case COMPAT_PSR_MODE_UND:
 108                case PSR_MODE_EL0t:
 109                case PSR_MODE_EL1t:
 110                case PSR_MODE_EL1h:
 111                        break;
 112                default:
 113                        err = -EINVAL;
 114                        goto out;
 115                }
 116        }
 117
 118        memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id));
 119out:
 120        return err;
 121}
 122
 123int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 124{
 125        return -EINVAL;
 126}
 127
 128int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 129{
 130        return -EINVAL;
 131}
 132
 133static unsigned long num_core_regs(void)
 134{
 135        return sizeof(struct kvm_regs) / sizeof(__u32);
 136}
 137
 138/**
 139 * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG
 140 *
 141 * This is for all registers.
 142 */
 143unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 144{
 145        return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu);
 146}
 147
 148/**
 149 * kvm_arm_copy_reg_indices - get indices of all registers.
 150 *
 151 * We do core registers right here, then we apppend system regs.
 152 */
 153int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 154{
 155        unsigned int i;
 156        const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE;
 157
 158        for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {
 159                if (put_user(core_reg | i, uindices))
 160                        return -EFAULT;
 161                uindices++;
 162        }
 163
 164        return kvm_arm_copy_sys_reg_indices(vcpu, uindices);
 165}
 166
 167int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 168{
 169        /* We currently use nothing arch-specific in upper 32 bits */
 170        if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
 171                return -EINVAL;
 172
 173        /* Register group 16 means we want a core register. */
 174        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
 175                return get_core_reg(vcpu, reg);
 176
 177        return kvm_arm_sys_reg_get_reg(vcpu, reg);
 178}
 179
 180int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 181{
 182        /* We currently use nothing arch-specific in upper 32 bits */
 183        if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
 184                return -EINVAL;
 185
 186        /* Register group 16 means we set a core register. */
 187        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
 188                return set_core_reg(vcpu, reg);
 189
 190        return kvm_arm_sys_reg_set_reg(vcpu, reg);
 191}
 192
 193int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 194                                  struct kvm_sregs *sregs)
 195{
 196        return -EINVAL;
 197}
 198
 199int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 200                                  struct kvm_sregs *sregs)
 201{
 202        return -EINVAL;
 203}
 204
 205int __attribute_const__ kvm_target_cpu(void)
 206{
 207        unsigned long implementor = read_cpuid_implementor();
 208        unsigned long part_number = read_cpuid_part_number();
 209
 210        if (implementor != ARM_CPU_IMP_ARM)
 211                return -EINVAL;
 212
 213        switch (part_number) {
 214        case ARM_CPU_PART_AEM_V8:
 215                return KVM_ARM_TARGET_AEM_V8;
 216        case ARM_CPU_PART_FOUNDATION:
 217                return KVM_ARM_TARGET_FOUNDATION_V8;
 218        case ARM_CPU_PART_CORTEX_A57:
 219                /* Currently handled by the generic backend */
 220                return KVM_ARM_TARGET_CORTEX_A57;
 221        default:
 222                return -EINVAL;
 223        }
 224}
 225
 226int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 227                        const struct kvm_vcpu_init *init)
 228{
 229        unsigned int i;
 230        int phys_target = kvm_target_cpu();
 231
 232        if (init->target != phys_target)
 233                return -EINVAL;
 234
 235        vcpu->arch.target = phys_target;
 236        bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
 237
 238        /* -ENOENT for unknown features, -EINVAL for invalid combinations. */
 239        for (i = 0; i < sizeof(init->features) * 8; i++) {
 240                if (init->features[i / 32] & (1 << (i % 32))) {
 241                        if (i >= KVM_VCPU_MAX_FEATURES)
 242                                return -ENOENT;
 243                        set_bit(i, vcpu->arch.features);
 244                }
 245        }
 246
 247        /* Now we know what it is, we can reset it. */
 248        return kvm_reset_vcpu(vcpu);
 249}
 250
 251int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 252{
 253        return -EINVAL;
 254}
 255
 256int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 257{
 258        return -EINVAL;
 259}
 260
 261int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 262                                  struct kvm_translation *tr)
 263{
 264        return -EINVAL;
 265}
 266