Commit 7d862707 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-6.17-2' of...

Merge tag 'kvmarm-fixes-6.17-2' of https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 changes for 6.17, round #3

 - Invalidate nested MMUs upon freeing the PGD to avoid WARNs when
   visiting from an MMU notifier

 - Fixes to the TLB match process and TLB invalidation range for
   managing the VCNR pseudo-TLB

 - Prevent SPE from erroneously profiling guests due to UNKNOWN reset
   values in PMSCR_EL1

 - Fix save/restore of host MDCR_EL2 to account for eagerly programming
   at vcpu_load() on VHE systems

 - Correct lock ordering when dealing with VGIC LPIs, avoiding scenarios
   where an xarray's spinlock was nested with a *raw* spinlock

 - Permit stage-2 read permission aborts which are possible in the case
   of NV depending on the guest hypervisor's stage-2 translation

 - Call raw_spin_unlock() instead of the internal spinlock API

 - Fix parameter ordering when assigning VBAR_EL1
parents f83ec76b e6157256
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1369,6 +1369,7 @@ static inline bool kvm_system_needs_idmapped_vectors(void)
}

void kvm_init_host_debug_data(void);
void kvm_debug_init_vhe(void);
void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu);
void kvm_vcpu_put_debug(struct kvm_vcpu *vcpu);
void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu);
+0 −30
Original line number Diff line number Diff line
@@ -355,11 +355,6 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
	return pteref;
}

static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
{
	return pteref;
}

static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
{
	/*
@@ -389,11 +384,6 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
	return rcu_dereference_check(pteref, !(walker->flags & KVM_PGTABLE_WALK_SHARED));
}

static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
{
	return rcu_dereference_raw(pteref);
}

static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
{
	if (walker->flags & KVM_PGTABLE_WALK_SHARED)
@@ -561,26 +551,6 @@ static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2
 */
void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);

/**
 * kvm_pgtable_stage2_destroy_range() - Destroy the unlinked range of addresses.
 * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
 * @addr:      Intermediate physical address at which to place the mapping.
 * @size:      Size of the mapping.
 *
 * The page-table is assumed to be unreachable by any hardware walkers prior
 * to freeing and therefore no TLB invalidation is performed.
 */
void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
					u64 addr, u64 size);

/**
 * kvm_pgtable_stage2_destroy_pgd() - Destroy the PGD of guest stage-2 page-table.
 * @pgt:       Page-table structure initialised by kvm_pgtable_stage2_init*().
 *
 * It is assumed that the rest of the page-table is freed before this operation.
 */
void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);

/**
 * kvm_pgtable_stage2_free_unlinked() - Free an unlinked stage-2 paging structure.
 * @mm_ops:	Memory management callbacks.
+1 −3
Original line number Diff line number Diff line
@@ -179,9 +179,7 @@ struct pkvm_mapping {

int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
			     struct kvm_pgtable_mm_ops *mm_ops);
void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
					u64 addr, u64 size);
void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);
void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
			    enum kvm_pgtable_prot prot, void *mc,
			    enum kvm_pgtable_walk_flags flags);
+3 −1
Original line number Diff line number Diff line
@@ -2113,8 +2113,10 @@ static void cpu_hyp_init_features(void)
{
	cpu_set_hyp_vector();

	if (is_kernel_in_hyp_mode())
	if (is_kernel_in_hyp_mode()) {
		kvm_timer_init_vhe();
		kvm_debug_init_vhe();
	}

	if (vgic_present)
		kvm_vgic_init_cpu_hardware();
+13 −0
Original line number Diff line number Diff line
@@ -96,6 +96,13 @@ void kvm_init_host_debug_data(void)
	}
}

void kvm_debug_init_vhe(void)
{
	/* Clear PMSCR_EL1.E{0,1}SPE which reset to UNKNOWN values. */
	if (SYS_FIELD_GET(ID_AA64DFR0_EL1, PMSVer, read_sysreg(id_aa64dfr0_el1)))
		write_sysreg_el1(0, SYS_PMSCR);
}

/*
 * Configures the 'external' MDSCR_EL1 value for the guest, i.e. when the host
 * has taken over MDSCR_EL1.
@@ -138,6 +145,9 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)
	/* Must be called before kvm_vcpu_load_vhe() */
	KVM_BUG_ON(vcpu_get_flag(vcpu, SYSREGS_ON_CPU), vcpu->kvm);

	if (has_vhe())
		*host_data_ptr(host_debug_state.mdcr_el2) = read_sysreg(mdcr_el2);

	/*
	 * Determine which of the possible debug states we're in:
	 *
@@ -184,6 +194,9 @@ void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu)

void kvm_vcpu_put_debug(struct kvm_vcpu *vcpu)
{
	if (has_vhe())
		write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);

	if (likely(!(vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
		return;

Loading