Commit 621ab20c authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files
KVM/arm updates for Linux 5.6

- Fix MMIO sign extension
- Fix HYP VA tagging on tag space exhaustion
- Fix PSTATE/CPSR handling when generating exception
- Fix MMU notifier's advertizing of young pages
- Fix poisoned page handling
- Fix PMU SW event handling
- Fix TVAL register access
- Fix AArch32 external abort injection
- Fix ITS unmapped collection handling
- Various cleanups
parents 3009afc6 4a267aa7
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2196,6 +2196,15 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value:
arm64 system registers have the following id bit patterns:
  0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>

WARNING:
     Two system register IDs do not follow the specified pattern.  These
     are KVM_REG_ARM_TIMER_CVAL and KVM_REG_ARM_TIMER_CNT, which map to
     system registers CNTV_CVAL_EL0 and CNTVCT_EL0 respectively.  These
     two had their values accidentally swapped, which means TIMER_CVAL is
     derived from the register encoding for CNTVCT_EL0 and TIMER_CNT is
     derived from the register encoding for CNTV_CVAL_EL0.  As this is
     API, it must remain this way.

arm64 firmware pseudo-registers have the following bit pattern:
  0x6030 0000 0014 <regno:16>

+24 −3
Original line number Diff line number Diff line
@@ -9,18 +9,29 @@

#include <linux/kvm_host.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_mmio.h>
#include <asm/kvm_arm.h>
#include <asm/cputype.h>

/* arm64 compatibility macros */
#define PSR_AA32_MODE_FIQ	FIQ_MODE
#define PSR_AA32_MODE_SVC	SVC_MODE
#define PSR_AA32_MODE_ABT	ABT_MODE
#define PSR_AA32_MODE_UND	UND_MODE
#define PSR_AA32_T_BIT		PSR_T_BIT
#define PSR_AA32_F_BIT		PSR_F_BIT
#define PSR_AA32_I_BIT		PSR_I_BIT
#define PSR_AA32_A_BIT		PSR_A_BIT
#define PSR_AA32_E_BIT		PSR_E_BIT
#define PSR_AA32_IT_MASK	PSR_IT_MASK
#define PSR_AA32_GE_MASK	0x000f0000
#define PSR_AA32_DIT_BIT	0x00200000
#define PSR_AA32_PAN_BIT	0x00400000
#define PSR_AA32_SSBS_BIT	0x00800000
#define PSR_AA32_Q_BIT		PSR_Q_BIT
#define PSR_AA32_V_BIT		PSR_V_BIT
#define PSR_AA32_C_BIT		PSR_C_BIT
#define PSR_AA32_Z_BIT		PSR_Z_BIT
#define PSR_AA32_N_BIT		PSR_N_BIT

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

@@ -41,6 +52,11 @@ static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v)
	*__vcpu_spsr(vcpu) = v;
}

static inline unsigned long host_spsr_to_spsr32(unsigned long spsr)
{
	return spsr;
}

static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu,
					 u8 reg_num)
{
@@ -182,6 +198,11 @@ static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu)
	return kvm_vcpu_get_hsr(vcpu) & HSR_SSE;
}

static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu)
{
	return false;
}

static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu)
{
	return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
@@ -198,7 +219,7 @@ static inline bool kvm_vcpu_dabt_is_cm(struct kvm_vcpu *vcpu)
}

/* Get Access Size from a data abort */
static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
static inline unsigned int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
{
	switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) {
	case 0:
@@ -209,7 +230,7 @@ static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
		return 4;
	default:
		kvm_err("Hardware is weird: SAS 0b11 is reserved\n");
		return -EFAULT;
		return 4;
	}
}

+8 −4
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
#include <asm/cputype.h>
#include <asm/kvm.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_mmio.h>
#include <asm/fpstate.h>
#include <kvm/arm_arch_timer.h>

@@ -202,9 +201,6 @@ struct kvm_vcpu_arch {
	 /* Don't run the guest (internal implementation need) */
	bool pause;

	/* IO related fields */
	struct kvm_decode mmio_decode;

	/* Cache some mmu pages needed inside spinlock regions */
	struct kvm_mmu_memory_cache mmu_page_cache;

@@ -298,6 +294,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
static inline void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
				     int exception_index) {}

/* MMIO helpers */
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);

int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
		 phys_addr_t fault_ipa);

static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
				       unsigned long hyp_stack_ptr,
				       unsigned long vector_ptr)
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include <linux/compiler.h>
#include <linux/kvm_host.h>
#include <asm/cp15.h>
#include <asm/kvm_arm.h>
#include <asm/vfp.h>

#define __hyp_text __section(.hyp.text) notrace

arch/arm/include/asm/kvm_mmio.h

deleted100644 → 0
+0 −26
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
 */

#ifndef __ARM_KVM_MMIO_H__
#define __ARM_KVM_MMIO_H__

#include <linux/kvm_host.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_arm.h>

struct kvm_decode {
	unsigned long rt;
	bool sign_extend;
};

void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);

int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
		 phys_addr_t fault_ipa);

#endif	/* __ARM_KVM_MMIO_H__ */
Loading