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

Merge tag 'kvm-arm-for-v4.15' of...

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

KVM/ARM Changes for v4.15

Changes include:
 - Optimized arch timer handling for KVM/ARM
 - Improvements to the VGIC ITS code and introduction of an ITS reset
   ioctl
 - Unification of the 32-bit fault injection logic
 - More exact external abort matching logic
parents 6d6ab940 a2b83133
Loading
Loading
Loading
Loading
+20 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,10 @@ Groups:
      request the initialization of the ITS, no additional parameter in
      request the initialization of the ITS, no additional parameter in
      kvm_device_attr.addr.
      kvm_device_attr.addr.


    KVM_DEV_ARM_ITS_CTRL_RESET
      reset the ITS, no additional parameter in kvm_device_attr.addr.
      See "ITS Reset State" section.

    KVM_DEV_ARM_ITS_SAVE_TABLES
    KVM_DEV_ARM_ITS_SAVE_TABLES
      save the ITS table data into guest RAM, at the location provisioned
      save the ITS table data into guest RAM, at the location provisioned
      by the guest in corresponding registers/table entries.
      by the guest in corresponding registers/table entries.
@@ -157,3 +161,19 @@ Then vcpus can be started.
 - pINTID is the physical LPI ID; if zero, it means the entry is not valid
 - pINTID is the physical LPI ID; if zero, it means the entry is not valid
   and other fields are not meaningful.
   and other fields are not meaningful.
 - ICID is the collection ID
 - ICID is the collection ID

 ITS Reset State:
 ----------------

RESET returns the ITS to the same state that it was when first created and
initialized. When the RESET command returns, the following things are
guaranteed:

- The ITS is not enabled and quiescent
  GITS_CTLR.Enabled = 0 .Quiescent=1
- There is no internally cached state
- No collection or device table are used
  GITS_BASER<n>.Valid = 0
- GITS_CBASER = 0, GITS_CREADR = 0, GITS_CWRITER = 0
- The ABI version is unchanged and remains the one set when the ITS
  device was first created.
+2 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,8 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);


extern void __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high);

extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);


extern void __init_stage2_translation(void);
extern void __init_stage2_translation(void);
+34 −4
Original line number Original line Diff line number Diff line
@@ -25,7 +25,22 @@
#include <asm/kvm_arm.h>
#include <asm/kvm_arm.h>
#include <asm/cputype.h>
#include <asm/cputype.h>


/* arm64 compatibility macros */
#define COMPAT_PSR_MODE_ABT	ABT_MODE
#define COMPAT_PSR_MODE_UND	UND_MODE
#define COMPAT_PSR_T_BIT	PSR_T_BIT
#define COMPAT_PSR_I_BIT	PSR_I_BIT
#define COMPAT_PSR_A_BIT	PSR_A_BIT
#define COMPAT_PSR_E_BIT	PSR_E_BIT
#define COMPAT_PSR_IT_MASK	PSR_IT_MASK

unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);

static inline unsigned long *vcpu_reg32(struct kvm_vcpu *vcpu, u8 reg_num)
{
	return vcpu_reg(vcpu, reg_num);
}

unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);


static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
@@ -42,10 +57,25 @@ static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,


bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr);
void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr);
void kvm_inject_undefined(struct kvm_vcpu *vcpu);
void kvm_inject_undef32(struct kvm_vcpu *vcpu);
void kvm_inject_dabt32(struct kvm_vcpu *vcpu, unsigned long addr);
void kvm_inject_pabt32(struct kvm_vcpu *vcpu, unsigned long addr);
void kvm_inject_vabt(struct kvm_vcpu *vcpu);
void kvm_inject_vabt(struct kvm_vcpu *vcpu);
void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);

void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
static inline void kvm_inject_undefined(struct kvm_vcpu *vcpu)
{
	kvm_inject_undef32(vcpu);
}

static inline void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
{
	kvm_inject_dabt32(vcpu, addr);
}

static inline void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
{
	kvm_inject_pabt32(vcpu, addr);
}


static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
{
{
@@ -203,7 +233,7 @@ static inline u8 kvm_vcpu_trap_get_fault_type(struct kvm_vcpu *vcpu)


static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu)
static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu)
{
{
	switch (kvm_vcpu_trap_get_fault_type(vcpu)) {
	switch (kvm_vcpu_trap_get_fault(vcpu)) {
	case FSC_SEA:
	case FSC_SEA:
	case FSC_SEA_TTW0:
	case FSC_SEA_TTW0:
	case FSC_SEA_TTW1:
	case FSC_SEA_TTW1:
+2 −2
Original line number Original line Diff line number Diff line
@@ -98,8 +98,8 @@
#define cntvoff_el2			CNTVOFF
#define cntvoff_el2			CNTVOFF
#define cnthctl_el2			CNTHCTL
#define cnthctl_el2			CNTHCTL


void __timer_save_state(struct kvm_vcpu *vcpu);
void __timer_enable_traps(struct kvm_vcpu *vcpu);
void __timer_restore_state(struct kvm_vcpu *vcpu);
void __timer_disable_traps(struct kvm_vcpu *vcpu);


void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
+7 −0
Original line number Original line Diff line number Diff line
@@ -151,6 +151,12 @@ struct kvm_arch_memory_slot {
	(__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
	(__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)


/* PL1 Physical Timer Registers */
#define KVM_REG_ARM_PTIMER_CTL		ARM_CP15_REG32(0, 14, 2, 1)
#define KVM_REG_ARM_PTIMER_CNT		ARM_CP15_REG64(0, 14)
#define KVM_REG_ARM_PTIMER_CVAL		ARM_CP15_REG64(2, 14)

/* Virtual Timer Registers */
#define KVM_REG_ARM_TIMER_CTL		ARM_CP15_REG32(0, 14, 3, 1)
#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_CNT		ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14)
#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14)
@@ -215,6 +221,7 @@ struct kvm_arch_memory_slot {
#define   KVM_DEV_ARM_ITS_SAVE_TABLES		1
#define   KVM_DEV_ARM_ITS_SAVE_TABLES		1
#define   KVM_DEV_ARM_ITS_RESTORE_TABLES	2
#define   KVM_DEV_ARM_ITS_RESTORE_TABLES	2
#define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
#define   KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES	3
#define   KVM_DEV_ARM_ITS_CTRL_RESET		4


/* KVM_IRQ_LINE irq field index values */
/* KVM_IRQ_LINE irq field index values */
#define KVM_ARM_IRQ_TYPE_SHIFT		24
#define KVM_ARM_IRQ_TYPE_SHIFT		24
Loading