diff options
author | Christoffer Dall <c.dall@virtualopensystems.com> | 2013-01-23 13:18:04 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2013-02-11 13:58:39 -0500 |
commit | 3401d54696f992edf036f00f46c8c399d1b75c2a (patch) | |
tree | bbb3bb02050b3b513e4b55839b553d793c1e63b9 /arch/arm/kvm | |
parent | a96ab03917dcf4c9477d03b31e8d74779bca1074 (diff) |
KVM: ARM: Introduce KVM_ARM_SET_DEVICE_ADDR ioctl
On ARM some bits are specific to the model being emulated for the guest and
user space needs a way to tell the kernel about those bits. An example is mmio
device base addresses, where KVM must know the base address for a given device
to properly emulate mmio accesses within a certain address range or directly
map a device with virtualiation extensions into the guest address space.
We make this API ARM-specific as we haven't yet reached a consensus for a
generic API for all KVM architectures that will allow us to do something like
this.
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r-- | arch/arm/kvm/arm.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 2d30e3afdaf9..523f77a44e44 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -167,6 +167,8 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
167 | case KVM_CAP_COALESCED_MMIO: | 167 | case KVM_CAP_COALESCED_MMIO: |
168 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 168 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
169 | break; | 169 | break; |
170 | case KVM_CAP_ARM_SET_DEVICE_ADDR: | ||
171 | r = 1; | ||
170 | case KVM_CAP_NR_VCPUS: | 172 | case KVM_CAP_NR_VCPUS: |
171 | r = num_online_cpus(); | 173 | r = num_online_cpus(); |
172 | break; | 174 | break; |
@@ -827,10 +829,29 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) | |||
827 | return -EINVAL; | 829 | return -EINVAL; |
828 | } | 830 | } |
829 | 831 | ||
832 | static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, | ||
833 | struct kvm_arm_device_addr *dev_addr) | ||
834 | { | ||
835 | return -ENODEV; | ||
836 | } | ||
837 | |||
830 | long kvm_arch_vm_ioctl(struct file *filp, | 838 | long kvm_arch_vm_ioctl(struct file *filp, |
831 | unsigned int ioctl, unsigned long arg) | 839 | unsigned int ioctl, unsigned long arg) |
832 | { | 840 | { |
833 | return -EINVAL; | 841 | struct kvm *kvm = filp->private_data; |
842 | void __user *argp = (void __user *)arg; | ||
843 | |||
844 | switch (ioctl) { | ||
845 | case KVM_ARM_SET_DEVICE_ADDR: { | ||
846 | struct kvm_arm_device_addr dev_addr; | ||
847 | |||
848 | if (copy_from_user(&dev_addr, argp, sizeof(dev_addr))) | ||
849 | return -EFAULT; | ||
850 | return kvm_vm_ioctl_set_device_addr(kvm, &dev_addr); | ||
851 | } | ||
852 | default: | ||
853 | return -EINVAL; | ||
854 | } | ||
834 | } | 855 | } |
835 | 856 | ||
836 | static void cpu_init_hyp_mode(void *vector) | 857 | static void cpu_init_hyp_mode(void *vector) |