static inline void __cpu_install_idmap(pgd_t *idmap)
{
	cpu_set_reserved_ttbr0();
	local_flush_tlb_all();
	cpu_set_idmap_tcr_t0sz();

	cpu_switch_mm(lm_alias(idmap), &init_mm);
}

static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
{
	typedef void (ttbr_replace_func)(phys_addr_t);
	extern ttbr_replace_func idmap_cpu_replace_ttbr1;
	ttbr_replace_func *replace_phys;
	unsigned long daif;

	/* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
	phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));

	if (system_supports_cnp() && !WARN_ON(pgdp != lm_alias(swapper_pg_dir))) {
		/*
		 * cpu_replace_ttbr1() is used when there's a boot CPU
		 * up (i.e. cpufeature framework is not up yet) and
		 * latter only when we enable CNP via cpufeature's
		 * enable() callback.
		 * Also we rely on the system_cpucaps bit being set before
		 * calling the enable() function.
		 */
		ttbr1 |= TTBR_CNP_BIT;
	}

	replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);

	__cpu_install_idmap(idmap);

	/*
	 * We really don't want to take *any* exceptions while TTBR1 is
	 * in the process of being replaced so mask everything.
	 */
	daif = local_daif_save();
	replace_phys(ttbr1);
	local_daif_restore(daif);

	cpu_uninstall_idmap();
}