From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoffer Dall Subject: [PATCH v4 01/13] KVM: ARM: Introduce KVM_SET_DEVICE_ADDRESS ioctl Date: Sat, 10 Nov 2012 16:44:23 +0100 Message-ID: <20121110154423.3061.68533.stgit@chazy-air> References: <20121110154358.3061.16338.stgit@chazy-air> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE To: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu Return-path: Received: from mail-wg0-f44.google.com ([74.125.82.44]:50326 "EHLO mail-wg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751975Ab2KJPo0 (ORCPT ); Sat, 10 Nov 2012 10:44:26 -0500 Received: by mail-wg0-f44.google.com with SMTP id dr13so3215314wgb.1 for ; Sat, 10 Nov 2012 07:44:25 -0800 (PST) In-Reply-To: <20121110154358.3061.16338.stgit@chazy-air> Sender: kvm-owner@vger.kernel.org List-ID: On ARM (and possibly other architectures) 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 try to make this API slightly more generic than for our specific use= , but so far only the VGIC uses this feature. Signed-off-by: Christoffer Dall --- Documentation/virtual/kvm/api.txt | 37 +++++++++++++++++++++++++++++= ++++++++ arch/arm/include/uapi/asm/kvm.h | 13 +++++++++++++ arch/arm/kvm/arm.c | 24 +++++++++++++++++++++++- include/uapi/linux/kvm.h | 8 ++++++++ 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/= kvm/api.txt index 9ffd702..35f6275 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2191,6 +2191,43 @@ This ioctl returns the guest registers that are = supported for the KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. =20 =20 +4.80 KVM_SET_DEVICE_ADDRESS + +Capability: KVM_CAP_SET_DEVICE_ADDRESS +Architectures: arm +Type: vm ioctl +Parameters: struct kvm_device_address (in) +Returns: 0 on success, -1 on error +Errors: + ENODEV: The device id is unknown + ENXIO: Device not supported on current system + EEXIST: Address already set + E2BIG: Address outside guest physical address space + +struct kvm_device_address { + __u64 id; + __u64 addr; +}; + +Specify a device address in the guest's physical address space where g= uests +can access emulated or directly exposed devices, which the host kernel= needs +to know about. The id field is an architecture specific identifier for= a +specific device. + +ARM divides the id field into two parts, a device id and an address ty= pe id +specific to the individual device. + + =C2=A0bits: | 31 ... 16 | 15 ... 0 | + field: | device id | addr type id | + +ARM currently only require this when using the in-kernel GIC support f= or the +hardware vGIC features, using KVM_ARM_DEVICE_VGIC_V2 as the device id.= When +setting the base address for the guest's mapping of the vGIC virtual C= PU +and distributor interface, the ioctl must be called after calling +KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. C= alling +this ioctl twice for any of the base addresses will return -EEXIST. + + 5. The kvm_run structure ------------------------ =20 diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/as= m/kvm.h index 5142cab..b1c7871 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -41,6 +41,19 @@ struct kvm_regs { #define KVM_ARM_TARGET_CORTEX_A15 0 #define KVM_ARM_NUM_TARGETS 1 =20 +/* KVM_SET_DEVICE_ADDRESS ioctl id encoding */ +#define KVM_DEVICE_TYPE_SHIFT 0 +#define KVM_DEVICE_TYPE_MASK (0xffff << KVM_DEVICE_TYPE_SHIFT) +#define KVM_DEVICE_ID_SHIFT 16 +#define KVM_DEVICE_ID_MASK (0xffff << KVM_DEVICE_ID_SHIFT) + +/* Supported device IDs */ +#define KVM_ARM_DEVICE_VGIC_V2 0 + +/* Supported VGIC address types */ +#define KVM_VGIC_V2_ADDR_TYPE_DIST 0 +#define KVM_VGIC_V2_ADDR_TYPE_CPU 1 + struct kvm_vcpu_init { __u32 target; __u32 features[7]; diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 435c5cc..2cdc07b 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -164,6 +164,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_COALESCED_MMIO: r =3D KVM_COALESCED_MMIO_PAGE_OFFSET; break; + case KVM_CAP_SET_DEVICE_ADDR: + r =3D 1; + break; default: r =3D 0; break; @@ -777,10 +780,29 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, s= truct kvm_dirty_log *log) return -EINVAL; } =20 +static int kvm_vm_ioctl_set_device_address(struct kvm *kvm, + struct kvm_device_address *dev_addr) +{ + return -ENODEV; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { - return -EINVAL; + struct kvm *kvm =3D filp->private_data; + void __user *argp =3D (void __user *)arg; + + switch (ioctl) { + case KVM_SET_DEVICE_ADDRESS: { + struct kvm_device_address dev_addr; + + if (copy_from_user(&dev_addr, argp, sizeof(dev_addr))) + return -EFAULT; + return kvm_vm_ioctl_set_device_address(kvm, &dev_addr); + } + default: + return -EINVAL; + } } =20 static void cpu_init_hyp_mode(void *vector) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 1db0460..e936f8f 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -635,6 +635,7 @@ struct kvm_ppc_smmu_info { #endif #define KVM_CAP_IRQFD_RESAMPLE 82 #define KVM_CAP_PPC_BOOKE_WATCHDOG 83 +#define KVM_CAP_SET_DEVICE_ADDR 84 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 @@ -782,6 +783,11 @@ struct kvm_msi { __u8 pad[16]; }; =20 +struct kvm_device_address { + __u64 id; + __u64 addr; +}; + /* * ioctls for VM fds */ @@ -865,6 +871,8 @@ struct kvm_s390_ucas_mapping { #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_sp= apr_tce) /* Available with KVM_CAP_RMA */ #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) +/* Available with KVM_CAP_SET_DEVICE_ADDR */ +#define KVM_SET_DEVICE_ADDRESS _IOW(KVMIO, 0xaa, struct kvm_device_= address) =20 /* * ioctls for vcpu fds