Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7025776e authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Michael Ellerman
Browse files

powerpc/mm: Move hash table ops to a separate structure



Moving probe_machine() to after mmu init will cause the ppc_md
fields relative to the hash table management to be overwritten.

Since we have essentially disconnected the machine type from
the hash backend ops, finish the job by moving them to a different
structure.

The only callback that didn't quite fix is update_partition_table
since this is not specific to hash, so I moved it to a standalone
variable for now. We can revisit later if needed.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
[mpe: Fix ppc64e build failure in kexec]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent b521f576
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -124,6 +124,45 @@

#ifndef __ASSEMBLY__

struct mmu_hash_ops {
	void            (*hpte_invalidate)(unsigned long slot,
					   unsigned long vpn,
					   int bpsize, int apsize,
					   int ssize, int local);
	long		(*hpte_updatepp)(unsigned long slot,
					 unsigned long newpp,
					 unsigned long vpn,
					 int bpsize, int apsize,
					 int ssize, unsigned long flags);
	void            (*hpte_updateboltedpp)(unsigned long newpp,
					       unsigned long ea,
					       int psize, int ssize);
	long		(*hpte_insert)(unsigned long hpte_group,
				       unsigned long vpn,
				       unsigned long prpn,
				       unsigned long rflags,
				       unsigned long vflags,
				       int psize, int apsize,
				       int ssize);
	long		(*hpte_remove)(unsigned long hpte_group);
	int             (*hpte_removebolted)(unsigned long ea,
					     int psize, int ssize);
	void		(*flush_hash_range)(unsigned long number, int local);
	void		(*hugepage_invalidate)(unsigned long vsid,
					       unsigned long addr,
					       unsigned char *hpte_slot_array,
					       int psize, int ssize, int local);
	/*
	 * Special for kexec.
	 * To be called in real mode with interrupts disabled. No locks are
	 * taken as such, concurrent access on pre POWER5 hardware could result
	 * in a deadlock.
	 * The linear mapping is destroyed as well.
	 */
	void		(*hpte_clear_all)(void);
};
extern struct mmu_hash_ops mmu_hash_ops;

struct hash_pte {
	__be64 v;
	__be64 r;
+0 −36
Original line number Diff line number Diff line
@@ -34,42 +34,6 @@ struct pci_host_bridge;
struct machdep_calls {
	char		*name;
#ifdef CONFIG_PPC64
	void            (*hpte_invalidate)(unsigned long slot,
					   unsigned long vpn,
					   int bpsize, int apsize,
					   int ssize, int local);
	long		(*hpte_updatepp)(unsigned long slot, 
					 unsigned long newpp, 
					 unsigned long vpn,
					 int bpsize, int apsize,
					 int ssize, unsigned long flags);
	void            (*hpte_updateboltedpp)(unsigned long newpp, 
					       unsigned long ea,
					       int psize, int ssize);
	long		(*hpte_insert)(unsigned long hpte_group,
				       unsigned long vpn,
				       unsigned long prpn,
				       unsigned long rflags,
				       unsigned long vflags,
				       int psize, int apsize,
				       int ssize);
	long		(*hpte_remove)(unsigned long hpte_group);
	int             (*hpte_removebolted)(unsigned long ea,
					     int psize, int ssize);
	void		(*flush_hash_range)(unsigned long number, int local);
	void		(*hugepage_invalidate)(unsigned long vsid,
					       unsigned long addr,
					       unsigned char *hpte_slot_array,
					       int psize, int ssize, int local);
	/*
	 * Special for kexec.
	 * To be called in real mode with interrupts disabled. No locks are
	 * taken as such, concurrent access on pre POWER5 hardware could result
	 * in a deadlock.
	 * The linear mapping is destroyed as well.
	 */
	void		(*hpte_clear_all)(void);

	void __iomem *	(*ioremap)(phys_addr_t addr, unsigned long size,
				   unsigned long flags, void *caller);
	void		(*iounmap)(volatile void __iomem *token);
+7 −2
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ int default_machine_kexec_prepare(struct kimage *image)
	const unsigned long *basep;
	const unsigned int *sizep;

	if (!ppc_md.hpte_clear_all)
	if (!mmu_hash_ops.hpte_clear_all)
		return -ENOENT;

	/*
@@ -380,7 +380,12 @@ void default_machine_kexec(struct kimage *image)
	 */
	kexec_sequence(&kexec_stack, image->start, image,
			page_address(image->control_code_page),
			ppc_md.hpte_clear_all);
#ifdef CONFIG_PPC_STD_MMU
			mmu_hash_ops.hpte_clear_all
#else
			NULL
#endif
	);
	/* NOTREACHED */
}

+1 −1
Original line number Diff line number Diff line
@@ -667,7 +667,7 @@ _GLOBAL(kexec_sequence)
	mr	r12,r27
#endif
	mtctr	r12
	bctrl				/* ppc_md.hpte_clear_all(void); */
	bctrl				/* mmu_hash_ops.hpte_clear_all(void); */
#endif /* !CONFIG_PPC_BOOK3E */

/*
+10 −8
Original line number Diff line number Diff line
@@ -34,9 +34,9 @@

void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{
	ppc_md.hpte_invalidate(pte->slot, pte->host_vpn,
			       pte->pagesize, pte->pagesize, MMU_SEGSIZE_256M,
			       false);
	mmu_hash_ops.hpte_invalidate(pte->slot, pte->host_vpn,
				     pte->pagesize, pte->pagesize,
				     MMU_SEGSIZE_256M, false);
}

/* We keep 512 gvsid->hvsid entries, mapping the guest ones to the array using
@@ -169,12 +169,12 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,

	/* In case we tried normal mapping already, let's nuke old entries */
	if (attempt > 1)
		if (ppc_md.hpte_remove(hpteg) < 0) {
		if (mmu_hash_ops.hpte_remove(hpteg) < 0) {
			r = -1;
			goto out_unlock;
		}

	ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
	ret = mmu_hash_ops.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
				       hpsize, hpsize, MMU_SEGSIZE_256M);

	if (ret < 0) {
@@ -187,8 +187,10 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte,
		trace_kvm_book3s_64_mmu_map(rflags, hpteg,
					    vpn, hpaddr, orig_pte);

		/* The ppc_md code may give us a secondary entry even though we
		   asked for a primary. Fix up. */
		/*
		 * The mmu_hash_ops code may give us a secondary entry even
		 * though we asked for a primary. Fix up.
		 */
		if ((ret & _PTEIDX_SECONDARY) && !(vflags & HPTE_V_SECONDARY)) {
			hash = ~hash;
			hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
Loading