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_emulate.h>
  32#include <asm/kvm_coproc.h>
  33
  34#include "trace.h"
  35
  36#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM }
  37#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
  38
  39struct kvm_stats_debugfs_item debugfs_entries[] = {
  40        VCPU_STAT(hvc_exit_stat),
  41        VCPU_STAT(wfe_exit_stat),
  42        VCPU_STAT(wfi_exit_stat),
  43        VCPU_STAT(mmio_exit_user),
  44        VCPU_STAT(mmio_exit_kernel),
  45        VCPU_STAT(exits),
  46        { NULL }
  47};
  48
  49int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
  50{
  51        return 0;
  52}
  53
  54static u64 core_reg_offset_from_id(u64 id)
  55{
  56        return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
  57}
  58
  59static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
  60{
  61        /*
  62         * Because the kvm_regs structure is a mix of 32, 64 and
  63         * 128bit fields, we index it as if it was a 32bit
  64         * array. Hence below, nr_regs is the number of entries, and
  65         * off the index in the "array".
  66         */
  67        __u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
  68        struct kvm_regs *regs = vcpu_gp_regs(vcpu);
  69        int nr_regs = sizeof(*regs) / sizeof(__u32);
  70        u32 off;
  71
  72        /* Our ID is an index into the kvm_regs struct. */
  73        off = core_reg_offset_from_id(reg->id);
  74        if (off >= nr_regs ||
  75            (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
  76                return -ENOENT;
  77
  78        if (copy_to_user(uaddr, ((u32 *)regs) + off, KVM_REG_SIZE(reg->id)))
  79                return -EFAULT;
  80
  81        return 0;
  82}
  83
  84static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
  85{
  86        __u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
  87        struct kvm_regs *regs = vcpu_gp_regs(vcpu);
  88        int nr_regs = sizeof(*regs) / sizeof(__u32);
  89        __uint128_t tmp;
  90        void *valp = &tmp;
  91        u64 off;
  92        int err = 0;
  93
  94        /* Our ID is an index into the kvm_regs struct. */
  95        off = core_reg_offset_from_id(reg->id);
  96        if (off >= nr_regs ||
  97            (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
  98                return -ENOENT;
  99
 100        if (KVM_REG_SIZE(reg->id) > sizeof(tmp))
 101                return -EINVAL;
 102
 103        if (copy_from_user(valp, uaddr, KVM_REG_SIZE(reg->id))) {
 104                err = -EFAULT;
 105                goto out;
 106        }
 107
 108        if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
 109                u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
 110                switch (mode) {
 111                case COMPAT_PSR_MODE_USR:
 112                case COMPAT_PSR_MODE_FIQ:
 113                case COMPAT_PSR_MODE_IRQ:
 114                case COMPAT_PSR_MODE_SVC:
 115                case COMPAT_PSR_MODE_ABT:
 116                case COMPAT_PSR_MODE_UND:
 117                case PSR_MODE_EL0t:
 118                case PSR_MODE_EL1t:
 119                case PSR_MODE_EL1h:
 120                        break;
 121                default:
 122                        err = -EINVAL;
 123                        goto out;
 124                }
 125        }
 126
 127        memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id));
 128out:
 129        return err;
 130}
 131
 132int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 133{
 134        return -EINVAL;
 135}
 136
 137int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 138{
 139        return -EINVAL;
 140}
 141
 142static unsigned long num_core_regs(void)
 143{
 144        return sizeof(struct kvm_regs) / sizeof(__u32);
 145}
 146
 147/**
 148 * ARM64 versions of the TIMER registers, always available on arm64
 149 */
 150
 151#define NUM_TIMER_REGS 3
 152
 153static bool is_timer_reg(u64 index)
 154{
 155        switch (index) {
 156        case KVM_REG_ARM_TIMER_CTL:
 157        case KVM_REG_ARM_TIMER_CNT:
 158        case KVM_REG_ARM_TIMER_CVAL:
 159                return true;
 160        }
 161        return false;
 162}
 163
 164static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 165{
 166        if (put_user(KVM_REG_ARM_TIMER_CTL, uindices))
 167                return -EFAULT;
 168        uindices++;
 169        if (put_user(KVM_REG_ARM_TIMER_CNT, uindices))
 170                return -EFAULT;
 171        uindices++;
 172        if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices))
 173                return -EFAULT;
 174
 175        return 0;
 176}
 177
 178static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 179{
 180        void __user *uaddr = (void __user *)(long)reg->addr;
 181        u64 val;
 182        int ret;
 183
 184        ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id));
 185        if (ret != 0)
 186                return -EFAULT;
 187
 188        return kvm_arm_timer_set_reg(vcpu, reg->id, val);
 189}
 190
 191static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 192{
 193        void __user *uaddr = (void __user *)(long)reg->addr;
 194        u64 val;
 195
 196        val = kvm_arm_timer_get_reg(vcpu, reg->id);
 197        return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
 198}
 199
 200/**
 201 * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG
 202 *
 203 * This is for all registers.
 204 */
 205unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 206{
 207        return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu)
 208                + NUM_TIMER_REGS;
 209}
 210
 211/**
 212 * kvm_arm_copy_reg_indices - get indices of all registers.
 213 *
 214 * We do core registers right here, then we apppend system regs.
 215 */
 216int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 217{
 218        unsigned int i;
 219        const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE;
 220        int ret;
 221
 222        for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {
 223                if (put_user(core_reg | i, uindices))
 224                        return -EFAULT;
 225                uindices++;
 226        }
 227
 228        ret = copy_timer_indices(vcpu, uindices);
 229        if (ret)
 230                return ret;
 231        uindices += NUM_TIMER_REGS;
 232
 233        return kvm_arm_copy_sys_reg_indices(vcpu, uindices);
 234}
 235
 236int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 237{
 238        /* We currently use nothing arch-specific in upper 32 bits */
 239        if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
 240                return -EINVAL;
 241
 242        /* Register group 16 means we want a core register. */
 243        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
 244                return get_core_reg(vcpu, reg);
 245
 246        if (is_timer_reg(reg->id))
 247                return get_timer_reg(vcpu, reg);
 248
 249        return kvm_arm_sys_reg_get_reg(vcpu, reg);
 250}
 251
 252int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 253{
 254        /* We currently use nothing arch-specific in upper 32 bits */
 255        if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
 256                return -EINVAL;
 257
 258        /* Register group 16 means we set a core register. */
 259        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
 260                return set_core_reg(vcpu, reg);
 261
 262        if (is_timer_reg(reg->id))
 263                return set_timer_reg(vcpu, reg);
 264
 265        return kvm_arm_sys_reg_set_reg(vcpu, reg);
 266}
 267
 268int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 269                                  struct kvm_sregs *sregs)
 270{
 271        return -EINVAL;
 272}
 273
 274int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 275                                  struct kvm_sregs *sregs)
 276{
 277        return -EINVAL;
 278}
 279
 280int __attribute_const__ kvm_target_cpu(void)
 281{
 282        unsigned long implementor = read_cpuid_implementor();
 283        unsigned long part_number = read_cpuid_part_number();
 284
 285        switch (implementor) {
 286        case ARM_CPU_IMP_ARM:
 287                switch (part_number) {
 288                case ARM_CPU_PART_AEM_V8:
 289                        return KVM_ARM_TARGET_AEM_V8;
 290                case ARM_CPU_PART_FOUNDATION:
 291                        return KVM_ARM_TARGET_FOUNDATION_V8;
 292                case ARM_CPU_PART_CORTEX_A53:
 293                        return KVM_ARM_TARGET_CORTEX_A53;
 294                case ARM_CPU_PART_CORTEX_A57:
 295                        return KVM_ARM_TARGET_CORTEX_A57;
 296                };
 297                break;
 298        case ARM_CPU_IMP_APM:
 299                switch (part_number) {
 300                case APM_CPU_PART_POTENZA:
 301                        return KVM_ARM_TARGET_XGENE_POTENZA;
 302                };
 303                break;
 304        };
 305
 306        /* Return a default generic target */
 307        return KVM_ARM_TARGET_GENERIC_V8;
 308}
 309
 310int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
 311{
 312        int target = kvm_target_cpu();
 313
 314        if (target < 0)
 315                return -ENODEV;
 316
 317        memset(init, 0, sizeof(*init));
 318
 319        /*
 320         * For now, we don't return any features.
 321         * In future, we might use features to return target
 322         * specific features available for the preferred
 323         * target type.
 324         */
 325        init->target = (__u32)target;
 326
 327        return 0;
 328}
 329
 330int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 331{
 332        return -EINVAL;
 333}
 334
 335int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 336{
 337        return -EINVAL;
 338}
 339
 340int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 341                                  struct kvm_translation *tr)
 342{
 343        return -EINVAL;
 344}
 345
 346#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
 347                            KVM_GUESTDBG_USE_SW_BP | \
 348                            KVM_GUESTDBG_USE_HW | \
 349                            KVM_GUESTDBG_SINGLESTEP)
 350
 351/**
 352 * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
 353 * @kvm:        pointer to the KVM struct
 354 * @kvm_guest_debug: the ioctl data buffer
 355 *
 356 * This sets up and enables the VM for guest debugging. Userspace
 357 * passes in a control flag to enable different debug types and
 358 * potentially other architecture specific information in the rest of
 359 * the structure.
 360 */
 361int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 362                                        struct kvm_guest_debug *dbg)
 363{
 364        trace_kvm_set_guest_debug(vcpu, dbg->control);
 365
 366        if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
 367                return -EINVAL;
 368
 369        if (dbg->control & KVM_GUESTDBG_ENABLE) {
 370                vcpu->guest_debug = dbg->control;
 371
 372                /* Hardware assisted Break and Watch points */
 373                if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
 374                        vcpu->arch.external_debug_state = dbg->arch;
 375                }
 376
 377        } else {
 378                /* If not enabled clear all flags */
 379                vcpu->guest_debug = 0;
 380        }
 381        return 0;
 382}
 383
 384int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
 385                               struct kvm_device_attr *attr)
 386{
 387        int ret;
 388
 389        switch (attr->group) {
 390        case KVM_ARM_VCPU_PMU_V3_CTRL:
 391                ret = kvm_arm_pmu_v3_set_attr(vcpu, attr);
 392                break;
 393        default:
 394                ret = -ENXIO;
 395                break;
 396        }
 397
 398        return ret;
 399}
 400
 401int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
 402                               struct kvm_device_attr *attr)
 403{
 404        int ret;
 405
 406        switch (attr->group) {
 407        case KVM_ARM_VCPU_PMU_V3_CTRL:
 408                ret = kvm_arm_pmu_v3_get_attr(vcpu, attr);
 409                break;
 410        default:
 411                ret = -ENXIO;
 412                break;
 413        }
 414
 415        return ret;
 416}
 417
 418int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
 419                               struct kvm_device_attr *attr)
 420{
 421        int ret;
 422
 423        switch (attr->group) {
 424        case KVM_ARM_VCPU_PMU_V3_CTRL:
 425                ret = kvm_arm_pmu_v3_has_attr(vcpu, attr);
 426                break;
 427        default:
 428                ret = -ENXIO;
 429                break;
 430        }
 431
 432        return ret;
 433}
 434