Path: blob/master/arch/arm64/kvm/vgic/vgic-kvm-device.c
26530 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* VGIC: KVM DEVICE API3*4* Copyright (C) 2015 ARM Ltd.5* Author: Marc Zyngier <[email protected]>6*/7#include <linux/irqchip/arm-gic-v3.h>8#include <linux/kvm_host.h>9#include <kvm/arm_vgic.h>10#include <linux/uaccess.h>11#include <asm/kvm_mmu.h>12#include <asm/cputype.h>13#include "vgic.h"1415/* common helpers */1617int vgic_check_iorange(struct kvm *kvm, phys_addr_t ioaddr,18phys_addr_t addr, phys_addr_t alignment,19phys_addr_t size)20{21if (!IS_VGIC_ADDR_UNDEF(ioaddr))22return -EEXIST;2324if (!IS_ALIGNED(addr, alignment) || !IS_ALIGNED(size, alignment))25return -EINVAL;2627if (addr + size < addr)28return -EINVAL;2930if (addr & ~kvm_phys_mask(&kvm->arch.mmu) ||31(addr + size) > kvm_phys_size(&kvm->arch.mmu))32return -E2BIG;3334return 0;35}3637static int vgic_check_type(struct kvm *kvm, int type_needed)38{39if (kvm->arch.vgic.vgic_model != type_needed)40return -ENODEV;41else42return 0;43}4445int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr)46{47struct vgic_dist *vgic = &kvm->arch.vgic;48int r;4950mutex_lock(&kvm->arch.config_lock);51switch (FIELD_GET(KVM_ARM_DEVICE_TYPE_MASK, dev_addr->id)) {52case KVM_VGIC_V2_ADDR_TYPE_DIST:53r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);54if (!r)55r = vgic_check_iorange(kvm, vgic->vgic_dist_base, dev_addr->addr,56SZ_4K, KVM_VGIC_V2_DIST_SIZE);57if (!r)58vgic->vgic_dist_base = dev_addr->addr;59break;60case KVM_VGIC_V2_ADDR_TYPE_CPU:61r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);62if (!r)63r = vgic_check_iorange(kvm, vgic->vgic_cpu_base, dev_addr->addr,64SZ_4K, KVM_VGIC_V2_CPU_SIZE);65if (!r)66vgic->vgic_cpu_base = dev_addr->addr;67break;68default:69r = -ENODEV;70}7172mutex_unlock(&kvm->arch.config_lock);7374return r;75}7677/**78* kvm_vgic_addr - set or get vgic VM base addresses79* @kvm: pointer to the vm struct80* @attr: pointer to the attribute being retrieved/updated81* @write: if true set the address in the VM address space, if false read the82* address83*84* Set or get the vgic base addresses for the distributor and the virtual CPU85* interface in the VM physical address space. These addresses are properties86* of the emulated core/SoC and therefore user space initially knows this87* information.88* Check them for sanity (alignment, double assignment). We can't check for89* overlapping regions in case of a virtual GICv3 here, since we don't know90* the number of VCPUs yet, so we defer this check to map_resources().91*/92static int kvm_vgic_addr(struct kvm *kvm, struct kvm_device_attr *attr, bool write)93{94u64 __user *uaddr = (u64 __user *)attr->addr;95struct vgic_dist *vgic = &kvm->arch.vgic;96phys_addr_t *addr_ptr, alignment, size;97u64 undef_value = VGIC_ADDR_UNDEF;98u64 addr;99int r;100101/* Reading a redistributor region addr implies getting the index */102if (write || attr->attr == KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION)103if (get_user(addr, uaddr))104return -EFAULT;105106/*107* Since we can't hold config_lock while registering the redistributor108* iodevs, take the slots_lock immediately.109*/110mutex_lock(&kvm->slots_lock);111switch (attr->attr) {112case KVM_VGIC_V2_ADDR_TYPE_DIST:113r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);114addr_ptr = &vgic->vgic_dist_base;115alignment = SZ_4K;116size = KVM_VGIC_V2_DIST_SIZE;117break;118case KVM_VGIC_V2_ADDR_TYPE_CPU:119r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);120addr_ptr = &vgic->vgic_cpu_base;121alignment = SZ_4K;122size = KVM_VGIC_V2_CPU_SIZE;123break;124case KVM_VGIC_V3_ADDR_TYPE_DIST:125r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V3);126addr_ptr = &vgic->vgic_dist_base;127alignment = SZ_64K;128size = KVM_VGIC_V3_DIST_SIZE;129break;130case KVM_VGIC_V3_ADDR_TYPE_REDIST: {131struct vgic_redist_region *rdreg;132133r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V3);134if (r)135break;136if (write) {137r = vgic_v3_set_redist_base(kvm, 0, addr, 0);138goto out;139}140rdreg = list_first_entry_or_null(&vgic->rd_regions,141struct vgic_redist_region, list);142if (!rdreg)143addr_ptr = &undef_value;144else145addr_ptr = &rdreg->base;146break;147}148case KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION:149{150struct vgic_redist_region *rdreg;151u8 index;152153r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V3);154if (r)155break;156157index = addr & KVM_VGIC_V3_RDIST_INDEX_MASK;158159if (write) {160gpa_t base = addr & KVM_VGIC_V3_RDIST_BASE_MASK;161u32 count = FIELD_GET(KVM_VGIC_V3_RDIST_COUNT_MASK, addr);162u8 flags = FIELD_GET(KVM_VGIC_V3_RDIST_FLAGS_MASK, addr);163164if (!count || flags)165r = -EINVAL;166else167r = vgic_v3_set_redist_base(kvm, index,168base, count);169goto out;170}171172rdreg = vgic_v3_rdist_region_from_index(kvm, index);173if (!rdreg) {174r = -ENOENT;175goto out;176}177178addr = index;179addr |= rdreg->base;180addr |= (u64)rdreg->count << KVM_VGIC_V3_RDIST_COUNT_SHIFT;181goto out;182}183default:184r = -ENODEV;185}186187if (r)188goto out;189190mutex_lock(&kvm->arch.config_lock);191if (write) {192r = vgic_check_iorange(kvm, *addr_ptr, addr, alignment, size);193if (!r)194*addr_ptr = addr;195} else {196addr = *addr_ptr;197}198mutex_unlock(&kvm->arch.config_lock);199200out:201mutex_unlock(&kvm->slots_lock);202203if (!r && !write)204r = put_user(addr, uaddr);205206return r;207}208209static int vgic_set_common_attr(struct kvm_device *dev,210struct kvm_device_attr *attr)211{212int r;213214switch (attr->group) {215case KVM_DEV_ARM_VGIC_GRP_ADDR:216r = kvm_vgic_addr(dev->kvm, attr, true);217return (r == -ENODEV) ? -ENXIO : r;218case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: {219u32 __user *uaddr = (u32 __user *)(long)attr->addr;220u32 val;221int ret = 0;222223if (get_user(val, uaddr))224return -EFAULT;225226/*227* We require:228* - at least 32 SPIs on top of the 16 SGIs and 16 PPIs229* - at most 1024 interrupts230* - a multiple of 32 interrupts231*/232if (val < (VGIC_NR_PRIVATE_IRQS + 32) ||233val > VGIC_MAX_RESERVED ||234(val & 31))235return -EINVAL;236237mutex_lock(&dev->kvm->arch.config_lock);238239/*240* Either userspace has already configured NR_IRQS or241* the vgic has already been initialized and vgic_init()242* supplied a default amount of SPIs.243*/244if (dev->kvm->arch.vgic.nr_spis)245ret = -EBUSY;246else247dev->kvm->arch.vgic.nr_spis =248val - VGIC_NR_PRIVATE_IRQS;249250mutex_unlock(&dev->kvm->arch.config_lock);251252return ret;253}254case KVM_DEV_ARM_VGIC_GRP_CTRL: {255switch (attr->attr) {256case KVM_DEV_ARM_VGIC_CTRL_INIT:257mutex_lock(&dev->kvm->arch.config_lock);258r = vgic_init(dev->kvm);259mutex_unlock(&dev->kvm->arch.config_lock);260return r;261case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:262/*263* OK, this one isn't common at all, but we264* want to handle all control group attributes265* in a single place.266*/267if (vgic_check_type(dev->kvm, KVM_DEV_TYPE_ARM_VGIC_V3))268return -ENXIO;269mutex_lock(&dev->kvm->lock);270271if (kvm_trylock_all_vcpus(dev->kvm)) {272mutex_unlock(&dev->kvm->lock);273return -EBUSY;274}275276mutex_lock(&dev->kvm->arch.config_lock);277r = vgic_v3_save_pending_tables(dev->kvm);278mutex_unlock(&dev->kvm->arch.config_lock);279kvm_unlock_all_vcpus(dev->kvm);280mutex_unlock(&dev->kvm->lock);281return r;282}283break;284}285}286287return -ENXIO;288}289290static int vgic_get_common_attr(struct kvm_device *dev,291struct kvm_device_attr *attr)292{293int r = -ENXIO;294295switch (attr->group) {296case KVM_DEV_ARM_VGIC_GRP_ADDR:297r = kvm_vgic_addr(dev->kvm, attr, false);298return (r == -ENODEV) ? -ENXIO : r;299case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: {300u32 __user *uaddr = (u32 __user *)(long)attr->addr;301302r = put_user(dev->kvm->arch.vgic.nr_spis +303VGIC_NR_PRIVATE_IRQS, uaddr);304break;305}306}307308return r;309}310311static int vgic_create(struct kvm_device *dev, u32 type)312{313return kvm_vgic_create(dev->kvm, type);314}315316static void vgic_destroy(struct kvm_device *dev)317{318kfree(dev);319}320321int kvm_register_vgic_device(unsigned long type)322{323int ret = -ENODEV;324325switch (type) {326case KVM_DEV_TYPE_ARM_VGIC_V2:327ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,328KVM_DEV_TYPE_ARM_VGIC_V2);329break;330case KVM_DEV_TYPE_ARM_VGIC_V3:331ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,332KVM_DEV_TYPE_ARM_VGIC_V3);333334if (ret)335break;336ret = kvm_vgic_register_its_device();337break;338}339340return ret;341}342343int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,344struct vgic_reg_attr *reg_attr)345{346int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);347348reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;349reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);350if (!reg_attr->vcpu)351return -EINVAL;352353return 0;354}355356/**357* vgic_v2_attr_regs_access - allows user space to access VGIC v2 state358*359* @dev: kvm device handle360* @attr: kvm device attribute361* @is_write: true if userspace is writing a register362*/363static int vgic_v2_attr_regs_access(struct kvm_device *dev,364struct kvm_device_attr *attr,365bool is_write)366{367u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr;368struct vgic_reg_attr reg_attr;369gpa_t addr;370struct kvm_vcpu *vcpu;371int ret;372u32 val;373374ret = vgic_v2_parse_attr(dev, attr, ®_attr);375if (ret)376return ret;377378vcpu = reg_attr.vcpu;379addr = reg_attr.addr;380381if (is_write)382if (get_user(val, uaddr))383return -EFAULT;384385mutex_lock(&dev->kvm->lock);386387if (kvm_trylock_all_vcpus(dev->kvm)) {388mutex_unlock(&dev->kvm->lock);389return -EBUSY;390}391392mutex_lock(&dev->kvm->arch.config_lock);393394ret = vgic_init(dev->kvm);395if (ret)396goto out;397398switch (attr->group) {399case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:400ret = vgic_v2_cpuif_uaccess(vcpu, is_write, addr, &val);401break;402case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:403ret = vgic_v2_dist_uaccess(vcpu, is_write, addr, &val);404break;405default:406ret = -EINVAL;407break;408}409410out:411mutex_unlock(&dev->kvm->arch.config_lock);412kvm_unlock_all_vcpus(dev->kvm);413mutex_unlock(&dev->kvm->lock);414415if (!ret && !is_write)416ret = put_user(val, uaddr);417418return ret;419}420421static int vgic_v2_set_attr(struct kvm_device *dev,422struct kvm_device_attr *attr)423{424switch (attr->group) {425case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:426case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:427return vgic_v2_attr_regs_access(dev, attr, true);428default:429return vgic_set_common_attr(dev, attr);430}431}432433static int vgic_v2_get_attr(struct kvm_device *dev,434struct kvm_device_attr *attr)435{436switch (attr->group) {437case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:438case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:439return vgic_v2_attr_regs_access(dev, attr, false);440default:441return vgic_get_common_attr(dev, attr);442}443}444445static int vgic_v2_has_attr(struct kvm_device *dev,446struct kvm_device_attr *attr)447{448switch (attr->group) {449case KVM_DEV_ARM_VGIC_GRP_ADDR:450switch (attr->attr) {451case KVM_VGIC_V2_ADDR_TYPE_DIST:452case KVM_VGIC_V2_ADDR_TYPE_CPU:453return 0;454}455break;456case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:457case KVM_DEV_ARM_VGIC_GRP_CPU_REGS:458return vgic_v2_has_attr_regs(dev, attr);459case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:460return 0;461case KVM_DEV_ARM_VGIC_GRP_CTRL:462switch (attr->attr) {463case KVM_DEV_ARM_VGIC_CTRL_INIT:464return 0;465}466}467return -ENXIO;468}469470struct kvm_device_ops kvm_arm_vgic_v2_ops = {471.name = "kvm-arm-vgic-v2",472.create = vgic_create,473.destroy = vgic_destroy,474.set_attr = vgic_v2_set_attr,475.get_attr = vgic_v2_get_attr,476.has_attr = vgic_v2_has_attr,477};478479int vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,480struct vgic_reg_attr *reg_attr)481{482unsigned long vgic_mpidr, mpidr_reg;483484/*485* For KVM_DEV_ARM_VGIC_GRP_DIST_REGS group,486* attr might not hold MPIDR. Hence assume vcpu0.487*/488if (attr->group != KVM_DEV_ARM_VGIC_GRP_DIST_REGS) {489vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>490KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;491492mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);493reg_attr->vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);494} else {495reg_attr->vcpu = kvm_get_vcpu(dev->kvm, 0);496}497498if (!reg_attr->vcpu)499return -EINVAL;500501reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;502503return 0;504}505506/*507* Allow access to certain ID-like registers prior to VGIC initialization,508* thereby allowing the VMM to provision the features / sizing of the VGIC.509*/510static bool reg_allowed_pre_init(struct kvm_device_attr *attr)511{512if (attr->group != KVM_DEV_ARM_VGIC_GRP_DIST_REGS)513return false;514515switch (attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK) {516case GICD_IIDR:517case GICD_TYPER2:518return true;519default:520return false;521}522}523524/*525* vgic_v3_attr_regs_access - allows user space to access VGIC v3 state526*527* @dev: kvm device handle528* @attr: kvm device attribute529* @is_write: true if userspace is writing a register530*/531static int vgic_v3_attr_regs_access(struct kvm_device *dev,532struct kvm_device_attr *attr,533bool is_write)534{535struct vgic_reg_attr reg_attr;536gpa_t addr;537struct kvm_vcpu *vcpu;538bool uaccess;539u32 val;540int ret;541542ret = vgic_v3_parse_attr(dev, attr, ®_attr);543if (ret)544return ret;545546vcpu = reg_attr.vcpu;547addr = reg_attr.addr;548549switch (attr->group) {550case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:551/* Sysregs uaccess is performed by the sysreg handling code */552uaccess = false;553break;554default:555uaccess = true;556}557558if (uaccess && is_write) {559u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr;560if (get_user(val, uaddr))561return -EFAULT;562}563564mutex_lock(&dev->kvm->lock);565566if (kvm_trylock_all_vcpus(dev->kvm)) {567mutex_unlock(&dev->kvm->lock);568return -EBUSY;569}570571mutex_lock(&dev->kvm->arch.config_lock);572573if (!(vgic_initialized(dev->kvm) || reg_allowed_pre_init(attr))) {574ret = -EBUSY;575goto out;576}577578switch (attr->group) {579case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:580ret = vgic_v3_dist_uaccess(vcpu, is_write, addr, &val);581break;582case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:583ret = vgic_v3_redist_uaccess(vcpu, is_write, addr, &val);584break;585case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:586ret = vgic_v3_cpu_sysregs_uaccess(vcpu, attr, is_write);587break;588case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {589unsigned int info, intid;590591info = (attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>592KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT;593if (info == VGIC_LEVEL_INFO_LINE_LEVEL) {594intid = attr->attr &595KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK;596ret = vgic_v3_line_level_info_uaccess(vcpu, is_write,597intid, &val);598} else {599ret = -EINVAL;600}601break;602}603default:604ret = -EINVAL;605break;606}607608out:609mutex_unlock(&dev->kvm->arch.config_lock);610kvm_unlock_all_vcpus(dev->kvm);611mutex_unlock(&dev->kvm->lock);612613if (!ret && uaccess && !is_write) {614u32 __user *uaddr = (u32 __user *)(unsigned long)attr->addr;615ret = put_user(val, uaddr);616}617618return ret;619}620621static int vgic_v3_set_attr(struct kvm_device *dev,622struct kvm_device_attr *attr)623{624switch (attr->group) {625case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:626case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:627case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:628case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:629return vgic_v3_attr_regs_access(dev, attr, true);630case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {631u32 __user *uaddr = (u32 __user *)attr->addr;632u32 val;633634if (get_user(val, uaddr))635return -EFAULT;636637guard(mutex)(&dev->kvm->arch.config_lock);638if (vgic_initialized(dev->kvm))639return -EBUSY;640641if (!irq_is_ppi(val))642return -EINVAL;643644dev->kvm->arch.vgic.mi_intid = val;645return 0;646}647default:648return vgic_set_common_attr(dev, attr);649}650}651652static int vgic_v3_get_attr(struct kvm_device *dev,653struct kvm_device_attr *attr)654{655switch (attr->group) {656case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:657case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:658case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:659case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:660return vgic_v3_attr_regs_access(dev, attr, false);661case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {662u32 __user *uaddr = (u32 __user *)(long)attr->addr;663664guard(mutex)(&dev->kvm->arch.config_lock);665return put_user(dev->kvm->arch.vgic.mi_intid, uaddr);666}667default:668return vgic_get_common_attr(dev, attr);669}670}671672static int vgic_v3_has_attr(struct kvm_device *dev,673struct kvm_device_attr *attr)674{675switch (attr->group) {676case KVM_DEV_ARM_VGIC_GRP_ADDR:677switch (attr->attr) {678case KVM_VGIC_V3_ADDR_TYPE_DIST:679case KVM_VGIC_V3_ADDR_TYPE_REDIST:680case KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION:681return 0;682}683break;684case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:685case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:686case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:687return vgic_v3_has_attr_regs(dev, attr);688case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:689case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:690return 0;691case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {692if (((attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>693KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT) ==694VGIC_LEVEL_INFO_LINE_LEVEL)695return 0;696break;697}698case KVM_DEV_ARM_VGIC_GRP_CTRL:699switch (attr->attr) {700case KVM_DEV_ARM_VGIC_CTRL_INIT:701return 0;702case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:703return 0;704}705}706return -ENXIO;707}708709struct kvm_device_ops kvm_arm_vgic_v3_ops = {710.name = "kvm-arm-vgic-v3",711.create = vgic_create,712.destroy = vgic_destroy,713.set_attr = vgic_v3_set_attr,714.get_attr = vgic_v3_get_attr,715.has_attr = vgic_v3_has_attr,716};717718719