Commit d460bb6c authored by Niklas Schnelle's avatar Niklas Schnelle Committed by Vasily Gorbik
Browse files

s390: enable HAVE_IOREMAP_PROT



In commit b02002cc ("s390/pci: Implement ioremap_wc/prot() with
MIO") we implemented both ioremap_wc() and ioremap_prot() however until
now we had not set HAVE_IOREMAP_PROT in Kconfig, do so now.

This also requires implementing pte_pgprot() as this is used in the
generic_access_phys() code enabled by CONFIG_HAVE_IOREMAP_PROT. As with
ioremap_wc() we need to take the MMIO Write Back bit index into account.

Moreover since the pgprot value returned from pte_pgprot() is to be used
for mappings into kernel address space we must make sure that it uses
appropriate kernel page table protection bits. In particular a pgprot
value originally coming from userspace could have the _PAGE_PROTECT
bit set to enable fault based dirty bit accounting which would then make
the mapping inaccessible when used in kernel address space.

Fixes: b02002cc ("s390/pci: Implement ioremap_wc/prot() with MIO")
Reviewed-by: default avatarGerald Schaefer <gerald.schaefer@linux.ibm.com>
Signed-off-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 15e5b53f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@ config S390
	select HAVE_FUTEX_CMPXCHG if FUTEX
	select HAVE_GCC_PLUGINS
	select HAVE_GENERIC_VDSO
	select HAVE_IOREMAP_PROT if PCI
	select HAVE_IRQ_EXIT_ON_IRQ_STACK
	select HAVE_KERNEL_BZIP2
	select HAVE_KERNEL_GZIP
+19 −0
Original line number Diff line number Diff line
@@ -865,6 +865,25 @@ static inline int pte_unused(pte_t pte)
	return pte_val(pte) & _PAGE_UNUSED;
}

/*
 * Extract the pgprot value from the given pte while at the same time making it
 * usable for kernel address space mappings where fault driven dirty and
 * young/old accounting is not supported, i.e _PAGE_PROTECT and _PAGE_INVALID
 * must not be set.
 */
static inline pgprot_t pte_pgprot(pte_t pte)
{
	unsigned long pte_flags = pte_val(pte) & _PAGE_CHG_MASK;

	if (pte_write(pte))
		pte_flags |= pgprot_val(PAGE_KERNEL);
	else
		pte_flags |= pgprot_val(PAGE_KERNEL_RO);
	pte_flags |= pte_val(pte) & mio_wb_bit_mask;

	return __pgprot(pte_flags);
}

/*
 * pgd/pmd/pte modification functions
 */