Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 912902ce authored by Radim Krčmář's avatar Radim Krčmář
Browse files

Merge tag 'kvm-arm-for-4.8' of...

Merge tag 'kvm-arm-for-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into next

KVM/ARM changes for Linux 4.8

- GICv3 ITS emulation
- Simpler idmap management that fixes potential TLB conflicts
- Honor the kernel protection in HYP mode
- Removal of the old vgic implementation
parents 61f5dea1 3a88bded
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -2182,7 +2182,7 @@ after pausing the vcpu, but before it is resumed.
4.71 KVM_SIGNAL_MSI

Capability: KVM_CAP_SIGNAL_MSI
Architectures: x86
Architectures: x86 arm64
Type: vm ioctl
Parameters: struct kvm_msi (in)
Returns: >0 on delivery, 0 if guest blocked the MSI, and -1 on error
@@ -2195,10 +2195,18 @@ struct kvm_msi {
	__u32 address_hi;
	__u32 data;
	__u32 flags;
	__u8  pad[16];
	__u32 devid;
	__u8  pad[12];
};

No flags are defined so far. The corresponding field must be 0.
flags: KVM_MSI_VALID_DEVID: devid contains a valid value
devid: If KVM_MSI_VALID_DEVID is set, contains a unique device identifier
       for the device that wrote the MSI message.
       For PCI, this is usually a BFD identifier in the lower 16 bits.

The per-VM KVM_CAP_MSI_DEVID capability advertises the need to provide
the device ID. If this capability is not set, userland cannot rely on
the kernel to allow the KVM_MSI_VALID_DEVID flag being set.

On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is
enabled.  If it is enabled, address_hi bits 31-8 provide bits 31-8 of the
+19 −6
Original line number Diff line number Diff line
@@ -4,16 +4,22 @@ ARM Virtual Generic Interrupt Controller (VGIC)
Device types supported:
  KVM_DEV_TYPE_ARM_VGIC_V2     ARM Generic Interrupt Controller v2.0
  KVM_DEV_TYPE_ARM_VGIC_V3     ARM Generic Interrupt Controller v3.0
  KVM_DEV_TYPE_ARM_VGIC_ITS    ARM Interrupt Translation Service Controller

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.
Only one VGIC instance of the V2/V3 types above 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.

Creating a guest GICv3 device requires a host GICv3 as well.
GICv3 implementations with hardware compatibility support allow a guest GICv2
as well.

Creating a virtual ITS controller requires a host GICv3 (but does not depend
on having physical ITS controllers).
There can be multiple ITS controllers per guest, each of them has to have
a separate, non-overlapping MMIO region.

Groups:
  KVM_DEV_ARM_VGIC_GRP_ADDR
  Attributes:
@@ -39,6 +45,13 @@ Groups:
      Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
      This address needs to be 64K aligned.

    KVM_VGIC_V3_ADDR_TYPE_ITS (rw, 64-bit)
      Base address in the guest physical address space of the GICv3 ITS
      control register frame. The ITS allows MSI(-X) interrupts to be
      injected into guests. This extension is optional. If the kernel
      does not support the ITS, the call returns -ENODEV.
      Only valid for KVM_DEV_TYPE_ARM_VGIC_ITS.
      This address needs to be 64K aligned and the region covers 128K.

  KVM_DEV_ARM_VGIC_GRP_DIST_REGS
  Attributes:
@@ -109,8 +122,8 @@ Groups:
  KVM_DEV_ARM_VGIC_GRP_CTRL
  Attributes:
    KVM_DEV_ARM_VGIC_CTRL_INIT
      request the initialization of the VGIC, no additional parameter in
      kvm_device_attr.addr.
      request the initialization of the VGIC or ITS, no additional parameter
      in kvm_device_attr.addr.
  Errors:
    -ENXIO: VGIC not properly configured as required prior to calling
     this attribute
+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);

extern void __init_stage2_translation(void);

extern void __kvm_hyp_reset(unsigned long);
#endif

#endif /* __ARM_KVM_ASM_H__ */
+9 −18
Original line number Diff line number Diff line
@@ -241,8 +241,7 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
		int exception_index);

static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
				       phys_addr_t pgd_ptr,
static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
				       unsigned long hyp_stack_ptr,
				       unsigned long vector_ptr)
{
@@ -251,18 +250,13 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
	 * code. The init code doesn't need to preserve these
	 * registers as r0-r3 are already callee saved according to
	 * the AAPCS.
	 * Note that we slightly misuse the prototype by casing the
	 * Note that we slightly misuse the prototype by casting the
	 * stack pointer to a void *.
	 *
	 * We don't have enough registers to perform the full init in
	 * one go.  Install the boot PGD first, and then install the
	 * runtime PGD, stack pointer and vectors. The PGDs are always
	 * passed as the third argument, in order to be passed into
	 * r2-r3 to the init code (yes, this is compliant with the
	 * PCS!).
	 */

	kvm_call_hyp(NULL, 0, boot_pgd_ptr);
	 * The PGDs are always passed as the third argument, in order
	 * to be passed into r2-r3 to the init code (yes, this is
	 * compliant with the PCS!).
	 */

	kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
}
@@ -272,16 +266,13 @@ static inline void __cpu_init_stage2(void)
	kvm_call_hyp(__init_stage2_translation);
}

static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
					phys_addr_t phys_idmap_start)
{
	/*
	 * TODO
	 * kvm_call_reset(boot_pgd_ptr, phys_idmap_start);
	 */
	kvm_call_hyp((void *)virt_to_idmap(__kvm_hyp_reset), vector_ptr);
}

static inline int kvm_arch_dev_ioctl_check_extension(long ext)
static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
{
	return 0;
}
+0 −3
Original line number Diff line number Diff line
@@ -25,9 +25,6 @@

#define __hyp_text __section(.hyp.text) notrace

#define kern_hyp_va(v) (v)
#define hyp_kern_va(v) (v)

#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
#define __ACCESS_CP15_64(Op1, CRm)		\
Loading