Loading Documentation/virtual/kvm/api.txt +6 −1 Original line number Diff line number Diff line Loading @@ -2391,7 +2391,8 @@ struct kvm_reg_list { This ioctl returns the guest registers that are supported for the KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. 4.85 KVM_ARM_SET_DEVICE_ADDR 4.85 KVM_ARM_SET_DEVICE_ADDR (deprecated) Capability: KVM_CAP_ARM_SET_DEVICE_ADDR Architectures: arm, arm64 Loading Loading @@ -2429,6 +2430,10 @@ must be called after calling KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the base addresses will return -EEXIST. Note, this IOCTL is deprecated and the more flexible SET/GET_DEVICE_ATTR API should be used instead. 4.86 KVM_PPC_RTAS_DEFINE_TOKEN Capability: KVM_CAP_PPC_RTAS Loading Documentation/virtual/kvm/devices/arm-vgic.txt 0 → 100644 +73 −0 Original line number Diff line number Diff line ARM Virtual Generic Interrupt Controller (VGIC) =============================================== Device types supported: KVM_DEV_TYPE_ARM_VGIC_V2 ARM Generic Interrupt Controller v2.0 Only one VGIC instance may be instantiated through either this API or the legacy KVM_CREATE_IRQCHIP api. The created VGIC will act as the VM interrupt controller, requiring emulated user-space devices to inject interrupts to the VGIC instead of directly to CPUs. Groups: KVM_DEV_ARM_VGIC_GRP_ADDR Attributes: KVM_VGIC_V2_ADDR_TYPE_DIST (rw, 64-bit) Base address in the guest physical address space of the GIC distributor register mappings. KVM_VGIC_V2_ADDR_TYPE_CPU (rw, 64-bit) Base address in the guest physical address space of the GIC virtual cpu interface register mappings. KVM_DEV_ARM_VGIC_GRP_DIST_REGS Attributes: The attr field of kvm_device_attr encodes two values: bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | values: | reserved | cpu id | offset | All distributor regs are (rw, 32-bit) The offset is relative to the "Distributor base address" as defined in the GICv2 specs. Getting or setting such a register has the same effect as reading or writing the register on the actual hardware from the cpu specified with cpu id field. Note that most distributor fields are not banked, but return the same value regardless of the cpu id used to access the register. Limitations: - Priorities are not implemented, and registers are RAZ/WI Errors: -ENODEV: Getting or setting this register is not yet supported -EBUSY: One or more VCPUs are running KVM_DEV_ARM_VGIC_GRP_CPU_REGS Attributes: The attr field of kvm_device_attr encodes two values: bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | values: | reserved | cpu id | offset | All CPU interface regs are (rw, 32-bit) The offset specifies the offset from the "CPU interface base address" as defined in the GICv2 specs. Getting or setting such a register has the same effect as reading or writing the register on the actual hardware. The Active Priorities Registers APRn are implementation defined, so we set a fixed format for our implementation that fits with the model of a "GICv2 implementation without the security extensions" which we present to the guest. This interface always exposes four register APR[0-3] describing the maximum possible 128 preemption levels. The semantics of the register indicate if any interrupts in a given preemption level are in the active state by setting the corresponding bit. Thus, preemption level X has one or more active interrupts if and only if: APRn[X mod 32] == 0b1, where n = X / 32 Bits for undefined preemption levels are RAZ/WI. Limitations: - Priorities are not implemented, and registers are RAZ/WI Errors: -ENODEV: Getting or setting this register is not yet supported -EBUSY: One or more VCPUs are running arch/arm/include/asm/kvm_host.h +3 −0 Original line number Diff line number Diff line Loading @@ -225,4 +225,7 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) int kvm_perf_init(void); int kvm_perf_teardown(void); u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); #endif /* __ARM_KVM_HOST_H__ */ arch/arm/include/uapi/asm/kvm.h +28 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,26 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800 #define KVM_REG_ARM_32_CRN_SHIFT 11 #define ARM_CP15_REG_SHIFT_MASK(x,n) \ (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK) #define __ARM_CP15_REG(op1,crn,crm,op2) \ (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | \ ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | \ ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | \ ARM_CP15_REG_SHIFT_MASK(crm, CRM) | \ ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2)) #define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32) #define __ARM_CP15_REG64(op1,crm) \ (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64) #define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__) #define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1) #define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14) #define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14) /* Normal registers are mapped as coprocessor 16. */ #define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4) Loading @@ -143,6 +163,14 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_VFP_FPINST 0x1009 #define KVM_REG_ARM_VFP_FPINST2 0x100A /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 #define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32 #define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 Loading arch/arm/kvm/arm.c +15 −4 Original line number Diff line number Diff line Loading @@ -137,6 +137,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (ret) goto out_free_stage2_pgd; kvm_timer_init(kvm); /* Mark the initial VMID generation invalid */ kvm->arch.vmid_gen = 0; Loading Loading @@ -188,6 +190,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IRQCHIP: r = vgic_present; break; case KVM_CAP_DEVICE_CTRL: case KVM_CAP_USER_MEMORY: case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: Loading Loading @@ -339,6 +342,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { /* * The arch-generic KVM code expects the cpu field of a vcpu to be -1 * if the vcpu is no longer assigned to a cpu. This is used for the * optimized make_all_cpus_request path. */ vcpu->cpu = -1; kvm_arm_set_running_vcpu(NULL); } Loading Loading @@ -462,6 +472,8 @@ static void update_vttbr(struct kvm *kvm) static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) { int ret; if (likely(vcpu->arch.has_run_once)) return 0; Loading @@ -471,9 +483,8 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) * Initialize the VGIC before running a vcpu the first time on * this VM. */ if (irqchip_in_kernel(vcpu->kvm) && unlikely(!vgic_initialized(vcpu->kvm))) { int ret = kvm_vgic_init(vcpu->kvm); if (unlikely(!vgic_initialized(vcpu->kvm))) { ret = kvm_vgic_init(vcpu->kvm); if (ret) return ret; } Loading Loading @@ -772,7 +783,7 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, case KVM_ARM_DEVICE_VGIC_V2: if (!vgic_present) return -ENXIO; return kvm_vgic_set_addr(kvm, type, dev_addr->addr); return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); default: return -ENODEV; } Loading Loading
Documentation/virtual/kvm/api.txt +6 −1 Original line number Diff line number Diff line Loading @@ -2391,7 +2391,8 @@ struct kvm_reg_list { This ioctl returns the guest registers that are supported for the KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. 4.85 KVM_ARM_SET_DEVICE_ADDR 4.85 KVM_ARM_SET_DEVICE_ADDR (deprecated) Capability: KVM_CAP_ARM_SET_DEVICE_ADDR Architectures: arm, arm64 Loading Loading @@ -2429,6 +2430,10 @@ must be called after calling KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the base addresses will return -EEXIST. Note, this IOCTL is deprecated and the more flexible SET/GET_DEVICE_ATTR API should be used instead. 4.86 KVM_PPC_RTAS_DEFINE_TOKEN Capability: KVM_CAP_PPC_RTAS Loading
Documentation/virtual/kvm/devices/arm-vgic.txt 0 → 100644 +73 −0 Original line number Diff line number Diff line ARM Virtual Generic Interrupt Controller (VGIC) =============================================== Device types supported: KVM_DEV_TYPE_ARM_VGIC_V2 ARM Generic Interrupt Controller v2.0 Only one VGIC instance may be instantiated through either this API or the legacy KVM_CREATE_IRQCHIP api. The created VGIC will act as the VM interrupt controller, requiring emulated user-space devices to inject interrupts to the VGIC instead of directly to CPUs. Groups: KVM_DEV_ARM_VGIC_GRP_ADDR Attributes: KVM_VGIC_V2_ADDR_TYPE_DIST (rw, 64-bit) Base address in the guest physical address space of the GIC distributor register mappings. KVM_VGIC_V2_ADDR_TYPE_CPU (rw, 64-bit) Base address in the guest physical address space of the GIC virtual cpu interface register mappings. KVM_DEV_ARM_VGIC_GRP_DIST_REGS Attributes: The attr field of kvm_device_attr encodes two values: bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | values: | reserved | cpu id | offset | All distributor regs are (rw, 32-bit) The offset is relative to the "Distributor base address" as defined in the GICv2 specs. Getting or setting such a register has the same effect as reading or writing the register on the actual hardware from the cpu specified with cpu id field. Note that most distributor fields are not banked, but return the same value regardless of the cpu id used to access the register. Limitations: - Priorities are not implemented, and registers are RAZ/WI Errors: -ENODEV: Getting or setting this register is not yet supported -EBUSY: One or more VCPUs are running KVM_DEV_ARM_VGIC_GRP_CPU_REGS Attributes: The attr field of kvm_device_attr encodes two values: bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | values: | reserved | cpu id | offset | All CPU interface regs are (rw, 32-bit) The offset specifies the offset from the "CPU interface base address" as defined in the GICv2 specs. Getting or setting such a register has the same effect as reading or writing the register on the actual hardware. The Active Priorities Registers APRn are implementation defined, so we set a fixed format for our implementation that fits with the model of a "GICv2 implementation without the security extensions" which we present to the guest. This interface always exposes four register APR[0-3] describing the maximum possible 128 preemption levels. The semantics of the register indicate if any interrupts in a given preemption level are in the active state by setting the corresponding bit. Thus, preemption level X has one or more active interrupts if and only if: APRn[X mod 32] == 0b1, where n = X / 32 Bits for undefined preemption levels are RAZ/WI. Limitations: - Priorities are not implemented, and registers are RAZ/WI Errors: -ENODEV: Getting or setting this register is not yet supported -EBUSY: One or more VCPUs are running
arch/arm/include/asm/kvm_host.h +3 −0 Original line number Diff line number Diff line Loading @@ -225,4 +225,7 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) int kvm_perf_init(void); int kvm_perf_teardown(void); u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); #endif /* __ARM_KVM_HOST_H__ */
arch/arm/include/uapi/asm/kvm.h +28 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,26 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800 #define KVM_REG_ARM_32_CRN_SHIFT 11 #define ARM_CP15_REG_SHIFT_MASK(x,n) \ (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK) #define __ARM_CP15_REG(op1,crn,crm,op2) \ (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | \ ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | \ ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | \ ARM_CP15_REG_SHIFT_MASK(crm, CRM) | \ ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2)) #define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32) #define __ARM_CP15_REG64(op1,crm) \ (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64) #define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__) #define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1) #define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14) #define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14) /* Normal registers are mapped as coprocessor 16. */ #define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4) Loading @@ -143,6 +163,14 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_VFP_FPINST 0x1009 #define KVM_REG_ARM_VFP_FPINST2 0x100A /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 #define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32 #define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 Loading
arch/arm/kvm/arm.c +15 −4 Original line number Diff line number Diff line Loading @@ -137,6 +137,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (ret) goto out_free_stage2_pgd; kvm_timer_init(kvm); /* Mark the initial VMID generation invalid */ kvm->arch.vmid_gen = 0; Loading Loading @@ -188,6 +190,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IRQCHIP: r = vgic_present; break; case KVM_CAP_DEVICE_CTRL: case KVM_CAP_USER_MEMORY: case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: Loading Loading @@ -339,6 +342,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { /* * The arch-generic KVM code expects the cpu field of a vcpu to be -1 * if the vcpu is no longer assigned to a cpu. This is used for the * optimized make_all_cpus_request path. */ vcpu->cpu = -1; kvm_arm_set_running_vcpu(NULL); } Loading Loading @@ -462,6 +472,8 @@ static void update_vttbr(struct kvm *kvm) static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) { int ret; if (likely(vcpu->arch.has_run_once)) return 0; Loading @@ -471,9 +483,8 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) * Initialize the VGIC before running a vcpu the first time on * this VM. */ if (irqchip_in_kernel(vcpu->kvm) && unlikely(!vgic_initialized(vcpu->kvm))) { int ret = kvm_vgic_init(vcpu->kvm); if (unlikely(!vgic_initialized(vcpu->kvm))) { ret = kvm_vgic_init(vcpu->kvm); if (ret) return ret; } Loading Loading @@ -772,7 +783,7 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, case KVM_ARM_DEVICE_VGIC_V2: if (!vgic_present) return -ENXIO; return kvm_vgic_set_addr(kvm, type, dev_addr->addr); return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); default: return -ENODEV; } Loading