Commit 1b21c8db authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files
KVM/arm64 updates for Linux 5.10

- New page table code for both hypervisor and guest stage-2
- Introduction of a new EL2-private host context
- Allow EL2 to have its own private per-CPU variables
- Support of PMU event filtering
- Complete rework of the Spectre mitigation
parents 628ade2d 4e5dc64c
Loading
Loading
Loading
Loading
+53 −4
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ Returns:

	 =======  ========================================================
	 -EBUSY   The PMU overflow interrupt is already set
	 -ENXIO   The overflow interrupt not set when attempting to get it
	 -ENODEV  PMUv3 not supported
	 -EFAULT  Error reading interrupt number
	 -ENXIO   PMUv3 not supported or the overflow interrupt not set
		  when attempting to get it
	 -ENODEV  KVM_ARM_VCPU_PMU_V3 feature missing from VCPU
	 -EINVAL  Invalid PMU overflow interrupt number supplied or
		  trying to set the IRQ number without using an in-kernel
		  irqchip.
@@ -45,9 +47,10 @@ all vcpus, while as an SPI it must be a separate number per vcpu.
Returns:

	 =======  ======================================================
	 -EEXIST  Interrupt number already used
	 -ENODEV  PMUv3 not supported or GIC not initialized
	 -ENXIO   PMUv3 not properly configured or in-kernel irqchip not
		  configured as required prior to calling this attribute
	 -ENXIO   PMUv3 not supported, missing VCPU feature or interrupt
		  number not set
	 -EBUSY   PMUv3 already initialized
	 =======  ======================================================

@@ -55,6 +58,52 @@ Request the initialization of the PMUv3. If using the PMUv3 with an in-kernel
virtual GIC implementation, this must be done after initializing the in-kernel
irqchip.

1.3 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_FILTER
-----------------------------------------

:Parameters: in kvm_device_attr.addr the address for a PMU event filter is a
             pointer to a struct kvm_pmu_event_filter

:Returns:

	 =======  ======================================================
	 -ENODEV  PMUv3 not supported or GIC not initialized
	 -ENXIO   PMUv3 not properly configured or in-kernel irqchip not
	 	  configured as required prior to calling this attribute
	 -EBUSY   PMUv3 already initialized
	 -EINVAL  Invalid filter range
	 =======  ======================================================

Request the installation of a PMU event filter described as follows::

    struct kvm_pmu_event_filter {
	    __u16	base_event;
	    __u16	nevents;

    #define KVM_PMU_EVENT_ALLOW	0
    #define KVM_PMU_EVENT_DENY	1

	    __u8	action;
	    __u8	pad[3];
    };

A filter range is defined as the range [@base_event, @base_event + @nevents),
together with an @action (KVM_PMU_EVENT_ALLOW or KVM_PMU_EVENT_DENY). The
first registered range defines the global policy (global ALLOW if the first
@action is DENY, global DENY if the first @action is ALLOW). Multiple ranges
can be programmed, and must fit within the event space defined by the PMU
architecture (10 bits on ARMv8.0, 16 bits from ARMv8.1 onwards).

Note: "Cancelling" a filter by registering the opposite action for the same
range doesn't change the default action. For example, installing an ALLOW
filter for event range [0:10) as the first filter and then applying a DENY
action for the same range will leave the whole range as disabled.

Restrictions: Event 0 (SW_INCR) is never filtered, as it doesn't count a
hardware event. Filtering event 0x1E (CHAIN) has no effect either, as it
isn't strictly speaking an event. Filtering the cycle counter is possible
using event 0x11 (CPU_CYCLES).


2. GROUP: KVM_ARM_VCPU_TIMER_CTRL
=================================
+0 −26
Original line number Diff line number Diff line
@@ -1165,32 +1165,6 @@ config UNMAP_KERNEL_AT_EL0

	  If unsure, say Y.

config HARDEN_BRANCH_PREDICTOR
	bool "Harden the branch predictor against aliasing attacks" if EXPERT
	default y
	help
	  Speculation attacks against some high-performance processors rely on
	  being able to manipulate the branch predictor for a victim context by
	  executing aliasing branches in the attacker context.  Such attacks
	  can be partially mitigated against by clearing internal branch
	  predictor state and limiting the prediction logic in some situations.

	  This config option will take CPU-specific actions to harden the
	  branch predictor against aliasing attacks and may rely on specific
	  instruction sequences or control bits being set by the system
	  firmware.

	  If unsure, say Y.

config ARM64_SSBD
	bool "Speculative Store Bypass Disable" if EXPERT
	default y
	help
	  This enables mitigation of the bypassing of previous stores
	  by speculative loads.

	  If unsure, say Y.

config RODATA_FULL_DEFAULT_ENABLED
	bool "Apply r/o permissions of VM areas also to their linear aliases"
	default y
+19 −10
Original line number Diff line number Diff line
@@ -218,6 +218,23 @@ lr .req x30 // link register
	str	\src, [\tmp, :lo12:\sym]
	.endm

	/*
	 * @dst: destination register
	 */
#if defined(__KVM_NVHE_HYPERVISOR__) || defined(__KVM_VHE_HYPERVISOR__)
	.macro	this_cpu_offset, dst
	mrs	\dst, tpidr_el2
	.endm
#else
	.macro	this_cpu_offset, dst
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
	mrs	\dst, tpidr_el1
alternative_else
	mrs	\dst, tpidr_el2
alternative_endif
	.endm
#endif

	/*
	 * @dst: Result of per_cpu(sym, smp_processor_id()) (can be SP)
	 * @sym: The name of the per-cpu variable
@@ -226,11 +243,7 @@ lr .req x30 // link register
	.macro adr_this_cpu, dst, sym, tmp
	adrp	\tmp, \sym
	add	\dst, \tmp, #:lo12:\sym
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
	mrs	\tmp, tpidr_el1
alternative_else
	mrs	\tmp, tpidr_el2
alternative_endif
	this_cpu_offset \tmp
	add	\dst, \dst, \tmp
	.endm

@@ -241,11 +254,7 @@ alternative_endif
	 */
	.macro ldr_this_cpu dst, sym, tmp
	adr_l	\dst, \sym
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
	mrs	\tmp, tpidr_el1
alternative_else
	mrs	\tmp, tpidr_el2
alternative_endif
	this_cpu_offset \tmp
	ldr	\dst, [\dst, \tmp]
	.endm

+2 −2
Original line number Diff line number Diff line
@@ -31,13 +31,13 @@
#define ARM64_HAS_DCPOP				21
#define ARM64_SVE				22
#define ARM64_UNMAP_KERNEL_AT_EL0		23
#define ARM64_HARDEN_BRANCH_PREDICTOR		24
#define ARM64_SPECTRE_V2			24
#define ARM64_HAS_RAS_EXTN			25
#define ARM64_WORKAROUND_843419			26
#define ARM64_HAS_CACHE_IDC			27
#define ARM64_HAS_CACHE_DIC			28
#define ARM64_HW_DBM				29
#define ARM64_SSBD				30
#define ARM64_SPECTRE_V4			30
#define ARM64_MISMATCHED_CACHE_TYPE		31
#define ARM64_HAS_STAGE2_FWB			32
#define ARM64_HAS_CRC32				33
+0 −24
Original line number Diff line number Diff line
@@ -698,30 +698,6 @@ static inline bool system_supports_tlb_range(void)
		cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
}

#define ARM64_BP_HARDEN_UNKNOWN		-1
#define ARM64_BP_HARDEN_WA_NEEDED	0
#define ARM64_BP_HARDEN_NOT_REQUIRED	1

int get_spectre_v2_workaround_state(void);

#define ARM64_SSBD_UNKNOWN		-1
#define ARM64_SSBD_FORCE_DISABLE	0
#define ARM64_SSBD_KERNEL		1
#define ARM64_SSBD_FORCE_ENABLE		2
#define ARM64_SSBD_MITIGATED		3

static inline int arm64_get_ssbd_state(void)
{
#ifdef CONFIG_ARM64_SSBD
	extern int ssbd_state;
	return ssbd_state;
#else
	return ARM64_SSBD_UNKNOWN;
#endif
}

void arm64_set_ssbd_mitigation(bool state);

extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);

static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
Loading