Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc3 222 lines 5.7 kB view raw
1/* 2 * Copyright (C) 2012 - Virtual Open Systems and Columbia University 3 * Author: Christoffer Dall <c.dall@virtualopensystems.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License, version 2, as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#include <linux/errno.h> 20#include <linux/err.h> 21#include <linux/kvm_host.h> 22#include <linux/module.h> 23#include <linux/vmalloc.h> 24#include <linux/fs.h> 25#include <asm/uaccess.h> 26#include <asm/kvm.h> 27#include <asm/kvm_asm.h> 28#include <asm/kvm_emulate.h> 29#include <asm/kvm_coproc.h> 30 31#define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM } 32#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU } 33 34struct kvm_stats_debugfs_item debugfs_entries[] = { 35 { NULL } 36}; 37 38int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 39{ 40 return 0; 41} 42 43static u64 core_reg_offset_from_id(u64 id) 44{ 45 return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE); 46} 47 48static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 49{ 50 u32 __user *uaddr = (u32 __user *)(long)reg->addr; 51 struct kvm_regs *regs = &vcpu->arch.regs; 52 u64 off; 53 54 if (KVM_REG_SIZE(reg->id) != 4) 55 return -ENOENT; 56 57 /* Our ID is an index into the kvm_regs struct. */ 58 off = core_reg_offset_from_id(reg->id); 59 if (off >= sizeof(*regs) / KVM_REG_SIZE(reg->id)) 60 return -ENOENT; 61 62 return put_user(((u32 *)regs)[off], uaddr); 63} 64 65static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 66{ 67 u32 __user *uaddr = (u32 __user *)(long)reg->addr; 68 struct kvm_regs *regs = &vcpu->arch.regs; 69 u64 off, val; 70 71 if (KVM_REG_SIZE(reg->id) != 4) 72 return -ENOENT; 73 74 /* Our ID is an index into the kvm_regs struct. */ 75 off = core_reg_offset_from_id(reg->id); 76 if (off >= sizeof(*regs) / KVM_REG_SIZE(reg->id)) 77 return -ENOENT; 78 79 if (get_user(val, uaddr) != 0) 80 return -EFAULT; 81 82 if (off == KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr)) { 83 unsigned long mode = val & MODE_MASK; 84 switch (mode) { 85 case USR_MODE: 86 case FIQ_MODE: 87 case IRQ_MODE: 88 case SVC_MODE: 89 case ABT_MODE: 90 case UND_MODE: 91 break; 92 default: 93 return -EINVAL; 94 } 95 } 96 97 ((u32 *)regs)[off] = val; 98 return 0; 99} 100 101int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 102{ 103 return -EINVAL; 104} 105 106int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 107{ 108 return -EINVAL; 109} 110 111static unsigned long num_core_regs(void) 112{ 113 return sizeof(struct kvm_regs) / sizeof(u32); 114} 115 116/** 117 * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG 118 * 119 * This is for all registers. 120 */ 121unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) 122{ 123 return num_core_regs() + kvm_arm_num_coproc_regs(vcpu); 124} 125 126/** 127 * kvm_arm_copy_reg_indices - get indices of all registers. 128 * 129 * We do core registers right here, then we apppend coproc regs. 130 */ 131int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) 132{ 133 unsigned int i; 134 const u64 core_reg = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE; 135 136 for (i = 0; i < sizeof(struct kvm_regs)/sizeof(u32); i++) { 137 if (put_user(core_reg | i, uindices)) 138 return -EFAULT; 139 uindices++; 140 } 141 142 return kvm_arm_copy_coproc_indices(vcpu, uindices); 143} 144 145int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 146{ 147 /* We currently use nothing arch-specific in upper 32 bits */ 148 if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM >> 32) 149 return -EINVAL; 150 151 /* Register group 16 means we want a core register. */ 152 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) 153 return get_core_reg(vcpu, reg); 154 155 return kvm_arm_coproc_get_reg(vcpu, reg); 156} 157 158int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) 159{ 160 /* We currently use nothing arch-specific in upper 32 bits */ 161 if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM >> 32) 162 return -EINVAL; 163 164 /* Register group 16 means we set a core register. */ 165 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) 166 return set_core_reg(vcpu, reg); 167 168 return kvm_arm_coproc_set_reg(vcpu, reg); 169} 170 171int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, 172 struct kvm_sregs *sregs) 173{ 174 return -EINVAL; 175} 176 177int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, 178 struct kvm_sregs *sregs) 179{ 180 return -EINVAL; 181} 182 183int kvm_vcpu_set_target(struct kvm_vcpu *vcpu, 184 const struct kvm_vcpu_init *init) 185{ 186 unsigned int i; 187 188 /* We can only do a cortex A15 for now. */ 189 if (init->target != kvm_target_cpu()) 190 return -EINVAL; 191 192 vcpu->arch.target = init->target; 193 bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES); 194 195 /* -ENOENT for unknown features, -EINVAL for invalid combinations. */ 196 for (i = 0; i < sizeof(init->features) * 8; i++) { 197 if (test_bit(i, (void *)init->features)) { 198 if (i >= KVM_VCPU_MAX_FEATURES) 199 return -ENOENT; 200 set_bit(i, vcpu->arch.features); 201 } 202 } 203 204 /* Now we know what it is, we can reset it. */ 205 return kvm_reset_vcpu(vcpu); 206} 207 208int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 209{ 210 return -EINVAL; 211} 212 213int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 214{ 215 return -EINVAL; 216} 217 218int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, 219 struct kvm_translation *tr) 220{ 221 return -EINVAL; 222}