Commit 49b3deaa authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-5.8-1' of...

Merge tag 'kvmarm-fixes-5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for Linux 5.8, take #1

* 32bit VM fixes:
  - Fix embarassing mapping issue between AArch32 CSSELR and AArch64
    ACTLR
  - Add ACTLR2 support for AArch32
  - Get rid of the useless ACTLR_EL1 save/restore
  - Fix CP14/15 accesses for AArch32 guests on BE hosts
  - Ensure that we don't loose any state when injecting a 32bit
    exception when running on a VHE host

* 64bit VM fixes:
  - Fix PtrAuth host saving happening in preemptible contexts
  - Optimize PtrAuth lazy enable
  - Drop vcpu to cpu context pointer
  - Fix sparse warnings for HYP per-CPU accesses
parents e0135a10 15c99816
Loading
Loading
Loading
Loading
+30 −3
Original line number Diff line number Diff line
@@ -81,12 +81,39 @@ extern u32 __kvm_get_mdcr_el2(void);

extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ];

/* Home-grown __this_cpu_{ptr,read} variants that always work at HYP */
/*
 * Obtain the PC-relative address of a kernel symbol
 * s: symbol
 *
 * The goal of this macro is to return a symbol's address based on a
 * PC-relative computation, as opposed to a loading the VA from a
 * constant pool or something similar. This works well for HYP, as an
 * absolute VA is guaranteed to be wrong. Only use this if trying to
 * obtain the address of a symbol (i.e. not something you obtained by
 * following a pointer).
 */
#define hyp_symbol_addr(s)						\
	({								\
		typeof(s) *addr;					\
		asm("adrp	%0, %1\n"				\
		    "add	%0, %0, :lo12:%1\n"			\
		    : "=r" (addr) : "S" (&s));				\
		addr;							\
	})

/*
 * Home-grown __this_cpu_{ptr,read} variants that always work at HYP,
 * provided that sym is really a *symbol* and not a pointer obtained from
 * a data structure. As for SHIFT_PERCPU_PTR(), the creative casting keeps
 * sparse quiet.
 */
#define __hyp_this_cpu_ptr(sym)						\
	({								\
		void *__ptr = hyp_symbol_addr(sym);			\
		void *__ptr;						\
		__verify_pcpu_ptr(&sym);				\
		__ptr = hyp_symbol_addr(sym);				\
		__ptr += read_sysreg(tpidr_el2);			\
		(typeof(&sym))__ptr;					\
		(typeof(sym) __kernel __force *)__ptr;			\
	 })

#define __hyp_this_cpu_read(sym)					\
+0 −6
Original line number Diff line number Diff line
@@ -112,12 +112,6 @@ static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu)
	vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK);
}

static inline void vcpu_ptrauth_setup_lazy(struct kvm_vcpu *vcpu)
{
	if (vcpu_has_ptrauth(vcpu))
		vcpu_ptrauth_disable(vcpu);
}

static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.vsesr_el2;
+4 −5
Original line number Diff line number Diff line
@@ -284,9 +284,6 @@ struct kvm_vcpu_arch {
	struct kvm_guest_debug_arch vcpu_debug_state;
	struct kvm_guest_debug_arch external_debug_state;

	/* Pointer to host CPU context */
	struct kvm_cpu_context *host_cpu_context;

	struct thread_info *host_thread_info;	/* hyp VA */
	struct user_fpsimd_state *host_fpsimd_state;	/* hyp VA */

@@ -404,8 +401,10 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
 * CP14 and CP15 live in the same array, as they are backed by the
 * same system registers.
 */
#define vcpu_cp14(v,r)		((v)->arch.ctxt.copro[(r)])
#define vcpu_cp15(v,r)		((v)->arch.ctxt.copro[(r)])
#define CPx_BIAS		IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)

#define vcpu_cp14(v,r)		((v)->arch.ctxt.copro[(r) ^ CPx_BIAS])
#define vcpu_cp15(v,r)		((v)->arch.ctxt.copro[(r) ^ CPx_BIAS])

struct kvm_vm_stat {
	ulong remote_tlb_flush;
+0 −20
Original line number Diff line number Diff line
@@ -107,26 +107,6 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)

#define kern_hyp_va(v) 	((typeof(v))(__kern_hyp_va((unsigned long)(v))))

/*
 * Obtain the PC-relative address of a kernel symbol
 * s: symbol
 *
 * The goal of this macro is to return a symbol's address based on a
 * PC-relative computation, as opposed to a loading the VA from a
 * constant pool or something similar. This works well for HYP, as an
 * absolute VA is guaranteed to be wrong. Only use this if trying to
 * obtain the address of a symbol (i.e. not something you obtained by
 * following a pointer).
 */
#define hyp_symbol_addr(s)						\
	({								\
		typeof(s) *addr;					\
		asm("adrp	%0, %1\n"				\
		    "add	%0, %0, :lo12:%1\n"			\
		    : "=r" (addr) : "S" (&s));				\
		addr;							\
	})

/*
 * We currently support using a VM-specified IPA size. For backward
 * compatibility, the default IPA size is fixed to 40bits.
+28 −0
Original line number Diff line number Diff line
@@ -33,6 +33,26 @@ static const u8 return_offsets[8][2] = {
	[7] = { 4, 4 },		/* FIQ, unused */
};

static bool pre_fault_synchronize(struct kvm_vcpu *vcpu)
{
	preempt_disable();
	if (vcpu->arch.sysregs_loaded_on_cpu) {
		kvm_arch_vcpu_put(vcpu);
		return true;
	}

	preempt_enable();
	return false;
}

static void post_fault_synchronize(struct kvm_vcpu *vcpu, bool loaded)
{
	if (loaded) {
		kvm_arch_vcpu_load(vcpu, smp_processor_id());
		preempt_enable();
	}
}

/*
 * When an exception is taken, most CPSR fields are left unchanged in the
 * handler. However, some are explicitly overridden (e.g. M[4:0]).
@@ -155,7 +175,10 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)

void kvm_inject_undef32(struct kvm_vcpu *vcpu)
{
	bool loaded = pre_fault_synchronize(vcpu);

	prepare_fault32(vcpu, PSR_AA32_MODE_UND, 4);
	post_fault_synchronize(vcpu, loaded);
}

/*
@@ -168,6 +191,9 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
	u32 vect_offset;
	u32 *far, *fsr;
	bool is_lpae;
	bool loaded;

	loaded = pre_fault_synchronize(vcpu);

	if (is_pabt) {
		vect_offset = 12;
@@ -191,6 +217,8 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
		/* no need to shuffle FS[4] into DFSR[10] as its 0 */
		*fsr = DFSR_FSC_EXTABT_nLPAE;
	}

	post_fault_synchronize(vcpu, loaded);
}

void kvm_inject_dabt32(struct kvm_vcpu *vcpu, unsigned long addr)
Loading