LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Getting kernel 4.14 to run on PS3
From: Sascha Schroeder @ 2017-12-31 23:26 UTC (permalink / raw)
  To: Nathan Whitehorn, Geoff Levand; +Cc: Linuxppc-dev, petitboot
In-Reply-To: <1a034ec1-5345-a2a1-780a-b5adbe0af332@freebsd.org>

[-- Attachment #1: Type: text/plain, Size: 2015 bytes --]

Sounds like progress! Nice one!

I encountered several issues with this box but still believe Cell can do more.

We're at an incredible architecture right here, what concerns me most is that we still today miss the availability of the mightyness of this machine.

Gallium 0.2 is still working for example, what we need here is people to bring this stuff further.

Heck, I have 7 SPEs on this machine, time to do something useful with these!

220Gflops FTW! 

Am 31. Dezember 2017 23:50:14 MEZ schrieb Nathan Whitehorn <nwhitehorn@freebsd.org>:
>
>
>On 12/12/17 15:05, Geoff Levand wrote:
>> Hi Nathan,
>>
>> On 12/08/2017 01:25 PM, Nathan Whitehorn wrote:
>>> I submitted patches to libfdt that resolve this particular ABI
>breakage yesterday. If the patch gets merged, newer kernels should
>become bootable again.
>> Here's the link:
>>
>>    https://github.com/dgibson/dtc/pull/12 (Add limited read-only
>support for older (V2 and V3) device tree to libfdt.)
>>
>> I rebased your patch and have it in my ps3-queue
>> branch, but my ps3 with ps3-petitboot-09.11.30 still
>> would not boot with it.  I didn't spend any time yet
>> to look into why.
>>
>>   
>https://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-linux.git/log/?h=ps3-queue
>>
>> -Geoff
>>
>
>I found a bug (and updated the pull request), which might help.
>
>The other potential issue is that the fdt_get_property*() API in libfdt
>
>is fundamentally incompatible with the way that V2 device trees align 
>data accesses since it returns a pointer to a packed structure with
>both 
>the property header and data. However, the data in V2 devtrees may be 
>offset by 4 bytes in a way that depends both on the offset within the 
>tree and the length of the property and so cannot be represented only
>as 
>the tail of a fixed structure. I don't know if Linux uses those 
>functions; I had to replace two uses in FreeBSD with the equivalent 
>fdt_getprop*() calls to get things to work.
>-Nathan

[-- Attachment #2: Type: text/html, Size: 2782 bytes --]

^ permalink raw reply

* [PATCH 2/2] powerpc/selftests: Check endianness on trap in TM
From: Gustavo Romero @ 2017-12-31 23:20 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cyrilbur
In-Reply-To: <1514762446-1323-1-git-send-email-gromero@linux.vnet.ibm.com>

Add a selftest to check if endianness is flipped inadvertently to BE
(MSR.LE set to zero) on BE and LE machines when a trap is caught in
transactional mode and load_fp and load_vec are zero, i.e. when MSR.FP
and MSR.VEC are zeroed (disabled).

Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
---
 tools/testing/selftests/powerpc/tm/.gitignore |   1 +
 tools/testing/selftests/powerpc/tm/Makefile   |   3 +-
 tools/testing/selftests/powerpc/tm/tm-trap.c  | 329 ++++++++++++++++++++++++++
 3 files changed, 332 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/powerpc/tm/tm-trap.c

diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index 241a4a4..bb90d4b 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -13,3 +13,4 @@ tm-signal-context-chk-vmx
 tm-signal-context-chk-vsx
 tm-vmx-unavail
 tm-unavailable
+tm-trap
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 8ed6f8c..a234539 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -3,7 +3,7 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu
 	tm-signal-context-chk-vmx tm-signal-context-chk-vsx
 
 TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
-	tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable \
+	tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail tm-unavailable tm-trap \
 	$(SIGNAL_CONTEXT_CHK_TESTS)
 
 include ../../lib.mk
@@ -18,6 +18,7 @@ $(OUTPUT)/tm-tmspr: CFLAGS += -pthread
 $(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64
 $(OUTPUT)/tm-resched-dscr: ../pmu/lib.o
 $(OUTPUT)/tm-unavailable: CFLAGS += -O0 -pthread -m64 -Wno-error=uninitialized -mvsx
+$(OUTPUT)/tm-trap: CFLAGS += -O0 -pthread -m64
 
 SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS))
 $(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S
diff --git a/tools/testing/selftests/powerpc/tm/tm-trap.c b/tools/testing/selftests/powerpc/tm/tm-trap.c
new file mode 100644
index 0000000..5d92c23
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-trap.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2017, Gustavo Romero, IBM Corp.
+ * Licensed under GPLv2.
+ *
+ * Check if thread endianness is flipped inadvertently to BE on trap
+ * caught in TM whilst MSR.FP and MSR.VEC are zero (i.e. just after
+ * load_fp and load_vec overflowed).
+ *
+ * The issue can be checked on LE machines simply by zeroing load_fp
+ * and load_vec and then causing a trap in TM. Since the endianness
+ * changes to BE on return from the signal handler, 'nop' is
+ * thread as an illegal instruction in following sequence:
+ *	tbegin.
+ *	beq 1f
+ *	trap
+ *	tend.
+ * 1:	nop
+ *
+ * However, although the issue is also present on BE machines, it's a
+ * bit trickier to check it on BE machines because MSR.LE bit is set
+ * to zero which determines a BE endianness that is the native
+ * endianness on BE machines, so nothing notably critical happens,
+ * i.e. no illegal instruction is observed immediately after returning
+ * from the signal handler (as it happens on LE machines). Thus to test
+ * it on BE machines LE endianness is forced after a first trap and then
+ * the endianness is verified on subsequent traps to determine if the
+ * endianness "flipped back" to the native endianness (BE).
+ */
+
+#define _GNU_SOURCE
+#include <error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <htmintrin.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#include "tm.h"
+#include "utils.h"
+
+#define pr_error(error_code, format, ...) \
+	error_at_line(1, error_code, __FILE__, __LINE__, format, ##__VA_ARGS__)
+
+#define MSR_LE 1UL
+#define LE     1UL
+
+pthread_t t0_ping;
+pthread_t t1_pong;
+
+int exit_from_pong;
+
+int trap_event;
+int le;
+
+bool success;
+
+void trap_signal_handler(int signo, siginfo_t *si, void *uc)
+{
+	ucontext_t *ucp = uc;
+	uint64_t thread_endianness;
+
+	/* Get thread endianness: extract bit LE from MSR */
+	thread_endianness = MSR_LE & ucp->uc_mcontext.gp_regs[PT_MSR];
+
+	/***
+	 * Little-Endian Machine
+	 */
+
+	if (le) {
+		/* First trap event */
+		if (trap_event == 0) {
+			/* Do nothing. Since it is returning from this trap
+			 * event that endianness is flipped by the bug, so just
+			 * let the process return from the signal handler and
+			 * check on the second trap event if endianness is
+			 * flipped or not.
+			 */
+		}
+		/* Second trap event */
+		else if (trap_event == 1) {
+			/*
+			 * Since trap was caught in TM on first trap event, if
+			 * endianness was still LE (not flipped inadvertently)
+			 * after returning from the signal handler instruction
+			 * (1) is executed (basically a 'nop'), as it's located
+			 * at address of tbegin. +4 (rollback addr). As (1) on
+			 * LE endianness does in effect nothing, instruction (2)
+			 * is then executed again as 'trap', generating a second
+			 * trap event (note that in that case 'trap' is caught
+			 * not in transacional mode). On te other hand, if after
+			 * the return from the signal handler the endianness in-
+			 * advertently flipped, instruction (1) is tread as a
+			 * branch instruction, i.e. b .+8, hence instruction (3)
+			 * and (4) are executed (tbegin.; trap;) and we get sim-
+			 * ilaly on the trap signal handler, but now in TM mode.
+			 * Either way, it's now possible to check the MSR LE bit
+			 * once in the trap handler to verify if endianness was
+			 * flipped or not after the return from the second trap
+			 * event. If endianness is flipped, the bug is present.
+			 * Finally, getting a trap in TM mode or not is just
+			 * worth noting because it affects the math to determine
+			 * the offset added to the NIP on return: the NIP for a
+			 * trap caught in TM is the rollback address, i.e. the
+			 * next instruction after 'tbegin.', whilst the NIP for
+			 * a trap caught in non-transactional mode is the very
+			 * same address of the 'trap' instruction that generated
+			 * the trap event.
+			 */
+
+			if (thread_endianness == LE) {
+				/* Go to 'success', i.e. instruction (6) */
+				ucp->uc_mcontext.gp_regs[PT_NIP] += 16;
+			} else {
+				/*
+				 * Thread endianness is BE, so it flipped
+				 * inadvertently. Thus we flip back to LE and
+				 * set NIP to go to 'failure', instruction (5).
+				 */
+				ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
+				ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
+			}
+		}
+	}
+
+	/***
+	 * Big-Endian Machine
+	 */
+
+	else {
+		/* First trap event */
+		if (trap_event == 0) {
+			/*
+			 * Force thread endianness to be LE. Instructions (1),
+			 * (3), and (4) will be executed, generating a second
+			 * trap in TM mode.
+			 */
+			ucp->uc_mcontext.gp_regs[PT_MSR] |= 1UL;
+		}
+		/* Second trap event */
+		else if (trap_event == 1) {
+			/*
+			 * Do nothing. If bug is present on return from this
+			 * second trap event endianness will flip back "automat-
+			 * ically" to BE, otherwise thread endianness will
+			 * continue to be LE, just as it was set above.
+			 */
+		}
+		/* A third trap event */
+		else {
+			/*
+			 * Once here it means that after returning from the sec-
+			 * ond trap event instruction (4) (trap) was executed
+			 * as LE, generating a third trap event. In that case
+			 * endianness is still LE as set on return from the
+			 * first trap event, hence no bug. Otherwise, bug
+			 * flipped back to BE on return from the second trap
+			 * event and instruction (4) was executed as 'tdi' (so
+			 * basically a 'nop') and branch to 'failure' in
+			 * instruction (5) was taken to indicate failure and we
+			 * never get here.
+			 */
+
+			/*
+			 * Flip back to BE and go to instruction (6), i.e. go to
+			 * 'success'.
+			 */
+			ucp->uc_mcontext.gp_regs[PT_MSR] &= ~1UL;
+			ucp->uc_mcontext.gp_regs[PT_NIP] += 8;
+		}
+	}
+
+	trap_event++;
+}
+
+void usr1_signal_handler(int signo, siginfo_t *si, void *not_used)
+{
+	/* Got a USR1 signal from ping(), so just tell pong() to exit */
+	exit_from_pong = 1;
+}
+
+void *ping(void *not_used)
+{
+	uint64_t i;
+
+	trap_event = 0;
+
+	/*
+	 * Wait an amount of context switches so load_fp and load_vec overflows
+	 * and MSR_[FP|VEC|V] is 0.
+	 */
+	for (i = 0; i < 1024*1024*512; i++)
+		;
+
+	asm goto(
+		/*
+		 * [NA] means "Native Endianness", i.e. it tells how a
+		 * instruction is executed on machine's native endianness (in
+		 * other words, native endianness matches kernel endianness).
+		 * [OP] means "Opposite Endianness", i.e. on a BE machine, it
+		 * tells how a instruction is executed as a LE instruction; con-
+		 * versely, on a LE machine, it tells how a instruction is
+		 * executed as a BE instruction. When [NA] is omitted, it means
+		 * that the native interpretation of a given instruction is not
+		 * relevant for the test. Likewise when [OP] is omitted.
+		 */
+
+		" tbegin.        ;" /* (0) tbegin. [NA]                    */
+		" tdi  0, 0, 0x48;" /* (1) nop     [NA]; b (3) [OP]        */
+		" trap           ;" /* (2) trap    [NA]                    */
+		".long 0x1D05007C;" /* (3) tbegin. [OP]                    */
+		".long 0x0800E07F;" /* (4) trap    [OP]; nop   [NA]        */
+		" b %l[failure]  ;" /* (5) b [NA]; MSR.LE flipped (bug)    */
+		" b %l[success]  ;" /* (6) b [NA]; MSR.LE did not flip (ok)*/
+
+		: : : : failure, success);
+
+failure:
+	success = false;
+	goto exit_from_ping;
+
+success:
+	success = true;
+
+exit_from_ping:
+	/* Tell pong() to exit before leaving */
+	pthread_kill(t1_pong, SIGUSR1);
+	return NULL;
+}
+
+void *pong(void *not_used)
+{
+	while (!exit_from_pong)
+		/*
+		 * Induce context switches on ping() thread
+		 * until ping() finishes its job and signs
+		 * to exit from this loop.
+		 */
+		sched_yield();
+
+	return NULL;
+}
+
+int tm_trap_test(void)
+{
+	uint16_t k = 1;
+
+	int rc;
+
+	pthread_attr_t attr;
+	cpu_set_t cpuset;
+
+	struct sigaction trap_sa;
+
+	trap_sa.sa_flags = SA_SIGINFO;
+	trap_sa.sa_sigaction = trap_signal_handler;
+	sigaction(SIGTRAP, &trap_sa, NULL);
+
+	struct sigaction usr1_sa;
+
+	usr1_sa.sa_flags = SA_SIGINFO;
+	usr1_sa.sa_sigaction = usr1_signal_handler;
+	sigaction(SIGUSR1, &usr1_sa, NULL);
+
+	/* Set only CPU 0 in the mask. Both threads will be bound to cpu 0. */
+	CPU_ZERO(&cpuset);
+	CPU_SET(0, &cpuset);
+
+	/* Init pthread attribute */
+	rc = pthread_attr_init(&attr);
+	if (rc)
+		pr_error(rc, "pthread_attr_init()");
+
+	/*
+	 * Bind thread ping() and pong() both to CPU 0 so they ping-pong and
+	 * speed up context switches on ping() thread, speeding up the load_fp
+	 * and load_vec overflow.
+	 */
+	rc = pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
+	if (rc)
+		pr_error(rc, "pthread_attr_setaffinity()");
+
+	/* Figure out the machine endianness */
+	le = (int) *(uint8_t *)&k;
+
+	printf("%s machine detected. Checking if endianness flips %s",
+		le ? "Little-Endian" : "Big-Endian",
+		"inadvertently on trap in TM... ");
+
+	rc = fflush(0);
+	if (rc)
+		pr_error(rc, "fflush()");
+
+	/* Launch ping() */
+	rc = pthread_create(&t0_ping, &attr, ping, NULL);
+	if (rc)
+		pr_error(rc, "pthread_create()");
+
+	exit_from_pong = 0;
+
+	/* Launch pong() */
+	rc = pthread_create(&t1_pong, &attr, pong, NULL);
+	if (rc)
+		pr_error(rc, "pthread_create()");
+
+	rc = pthread_join(t0_ping, NULL);
+	if (rc)
+		pr_error(rc, "pthread_join()");
+
+	rc = pthread_join(t1_pong, NULL);
+	if (rc)
+		pr_error(rc, "pthread_join()");
+
+	if (success) {
+		printf("no.\n"); /* no, endianness did not flip inadvertently */
+		return EXIT_SUCCESS;
+	}
+
+	printf("yes!\n"); /* yes, endianness did flip inadvertently */
+	return EXIT_FAILURE;
+}
+
+int main(int argc, char **argv)
+{
+	return test_harness(tm_trap_test, "tm_trap_test");
+}
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/2] powerpc/tm: Fix endianness flip on trap
From: Gustavo Romero @ 2017-12-31 23:20 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: cyrilbur

Currently it's possible that a thread on PPC64 LE has its endianness
flipped inadvertently to Big-Endian resulting in a crash once the process
is back from the signal handler.

If giveup_all() is called when regs->msr has the bits MSR.FP and MSR.VEC
disabled (and hence MSR.VSX disabled too) it returns without calling
check_if_tm_restore_required() which copies regs->msr to ckpt_regs->msr if
the process caught a signal whilst in transactional mode. Then once in
setup_tm_sigcontexts() MSR from ckpt_regs.msr is used, but since
check_if_tm_restore_required() was not called previuosly, gp_regs[PT_MSR]
gets a copy of invalid MSR bits as MSR in ckpt_regs was not updated from
regs->msr and so is zeroed. Later when leaving the signal handler once in
sys_rt_sigreturn() the TS bits of gp_regs[PT_MSR] are checked to determine
if restore_tm_sigcontexts() must be called to pull in the correct MSR state
into the user context. Because TS bits are zeroed
restore_tm_sigcontexts() is never called and MSR restored from the user
context on returning from the signal handler has the MSR.LE (the endianness
bit) forced to zero (Big-Endian). That leads, for instance, to 'nop' being
treated as an illegal instruction in the following sequence:

	tbegin.
	beq	1f
	trap
	tend.
1:	nop

on PPC64 LE machines and the process dies just after returning from the
signal handler.

PPC64 BE is also affected but in a subtle way since forcing Big-Endian on
a BE machine does not change the endianness.

This commit fixes the issue described above by ensuring that once in
setup_tm_sigcontexts() the MSR used is from regs->msr instead of from
ckpt_regs->msr and by ensuring that we pull in only the MSR.FP, MSR.VEC,
and MSR.VSX bits from ckpt_regs->msr.

The fix was tested both on LE and BE machines and no regression regarding
the powerpc/tm selftests was observed.

Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
---
 arch/powerpc/kernel/signal_64.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 4b9ca35..b1b9962 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -207,7 +207,7 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
 	elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc);
 #endif
 	struct pt_regs *regs = tsk->thread.regs;
-	unsigned long msr = tsk->thread.ckpt_regs.msr;
+	unsigned long msr = tsk->thread.regs->msr;
 	long err = 0;
 
 	BUG_ON(tsk != current);
@@ -216,6 +216,12 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
 
 	WARN_ON(tm_suspend_disabled);
 
+	/* Restore checkpointed FP, VEC, and VSX bits from ckpt_regs as
+	 * it contains the correct FP, VEC, VSX state after we treclaimed
+	 * the transaction and giveup_all() was called on reclaiming.
+	 */
+	msr |= tsk->thread.ckpt_regs.msr & (MSR_FP | MSR_VEC | MSR_VSX);
+
 	/* Remove TM bits from thread's MSR.  The MSR in the sigcontext
 	 * just indicates to userland that we were doing a transaction, but we
 	 * don't want to return in transactional state.  This also ensures
-- 
2.7.4

^ permalink raw reply related

* Re: Getting kernel 4.14 to run on PS3
From: Nathan Whitehorn @ 2017-12-31 22:50 UTC (permalink / raw)
  To: Geoff Levand, Sascha Schroeder; +Cc: Linuxppc-dev, petitboot
In-Reply-To: <5c41fd34-5aac-028e-af12-59b6ab576d91@infradead.org>



On 12/12/17 15:05, Geoff Levand wrote:
> Hi Nathan,
>
> On 12/08/2017 01:25 PM, Nathan Whitehorn wrote:
>> I submitted patches to libfdt that resolve this particular ABI breakage yesterday. If the patch gets merged, newer kernels should become bootable again.
> Here's the link:
>
>    https://github.com/dgibson/dtc/pull/12 (Add limited read-only support for older (V2 and V3) device tree to libfdt.)
>
> I rebased your patch and have it in my ps3-queue
> branch, but my ps3 with ps3-petitboot-09.11.30 still
> would not boot with it.  I didn't spend any time yet
> to look into why.
>
>    https://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-linux.git/log/?h=ps3-queue
>
> -Geoff
>

I found a bug (and updated the pull request), which might help.

The other potential issue is that the fdt_get_property*() API in libfdt 
is fundamentally incompatible with the way that V2 device trees align 
data accesses since it returns a pointer to a packed structure with both 
the property header and data. However, the data in V2 devtrees may be 
offset by 4 bytes in a way that depends both on the offset within the 
tree and the length of the property and so cannot be represented only as 
the tail of a fixed structure. I don't know if Linux uses those 
functions; I had to replace two uses in FreeBSD with the equivalent 
fdt_getprop*() calls to get things to work.
-Nathan

^ permalink raw reply

* [RESEND PATCH] i2c/busses/pasemi: Remove hardcoded bus numbers on smbus
From: Darren Stevens @ 2017-12-31 20:53 UTC (permalink / raw)
  To: wsa, linux-i2c, linux-kernel; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

  AmigaOS...........: http://yam.ch/
  Unix/MacOS/Windows: http://www.mozilla.com/thunderbird/

General information about MIME can be found at:
http://en.wikipedia.org/wiki/MIME

[-- Attachment #2: Type: text/plain, Size: 398 bytes --]

The pasemi smbus controller uses PCI_FUNC(dev->devfn) to define which
number bus to attach to, however this fails when something else is 
probed first, for example an ATI Radeon graphics card will claim 9 or
10 busses, including the ones the pasemi wants.
Patch the driver to call i2c_add_adapter rather than
i2c_add_numbered_adapter.

Signed-off-by: Darren Stevens <darren@stevens-zone.net>

---


[-- Attachment #3: i2c.patch --]
[-- Type: text/plain, Size: 826 bytes --]

diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
index df1dbc9..05847fd 100644
--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -365,7 +365,6 @@ static int pasemi_smb_probe(struct pci_dev *dev,
 	smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	smbus->adapter.algo = &smbus_algorithm;
 	smbus->adapter.algo_data = smbus;
-	smbus->adapter.nr = PCI_FUNC(dev->devfn);
 
 	/* set up the sysfs linkage to our parent device */
 	smbus->adapter.dev.parent = &dev->dev;
@@ -373,7 +372,7 @@ static int pasemi_smb_probe(struct pci_dev *dev,
 	reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
 		  (CLK_100K_DIV & CTL_CLK_M)));
 
-	error = i2c_add_numbered_adapter(&smbus->adapter);
+	error = i2c_add_adapter(&smbus->adapter);
 	if (error)
 		goto out_release_region;
 

^ permalink raw reply related

* [PATCH NEXT 3/4] powerpc/pasemi: Add Nemo board device init code.
From: Darren Stevens @ 2017-12-31 22:08 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Christian Zigotzky

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

  AmigaOS...........: http://yam.ch/
  Unix/MacOS/Windows: http://www.mozilla.com/thunderbird/

General information about MIME can be found at:
http://en.wikipedia.org/wiki/MIME

[-- Attachment #2: Type: text/plain, Size: 297 bytes --]

    Add routines for Nemo specific devices to init at boot time, these
    being board level power-off and SB600's rtc.
    
    Also add a run time variable to prevent these being activated
    if we boot on a reference board.
    
    Signed-off-by: Darren Stevens <Darren@stevens-zone.net>

---

[-- Attachment #3: devs.patch --]
[-- Type: text/plain, Size: 1563 bytes --]

diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index c583c17..8d3664f 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -73,6 +73,19 @@ static void __noreturn pas_restart(char *cmd)
 		out_le32(reset_reg, 0x6000000);
 }
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+/* A flag to indicate we are running on Nemo */
+static bool nemo_board = false;
+
+void pas_shutdown(void)
+{
+	/* Set the PLD bit that makes the SB600 think the power button is being pressed */
+	void __iomem *pld_map = ioremap(0xf5000000,4096);
+	while (1)
+		out_8(pld_map+7,0x01);
+}
+#endif
+
 #ifdef CONFIG_SMP
 static arch_spinlock_t timebase_lock;
 static unsigned long timebase;
@@ -492,6 +505,20 @@ static inline void pasemi_pcmcia_init(void)
 	{},
 };
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+static struct resource rtc_resource[] = {{
+	.name = "rtc",
+	.start = 0x70,
+	.end = 0x71,
+	.flags = IORESOURCE_IO,
+}, {
+	.name = "rtc",
+	.start = 8,
+	.end = 8,
+	.flags = IORESOURCE_IRQ,
+}};
+#endif
+
 static int __init pasemi_publish_devices(void)
 {
 	pasemi_pcmcia_init();
@@ -499,6 +526,14 @@ static int __init pasemi_publish_devices(void)
 	/* Publish OF platform devices for SDC and other non-PCI devices */
 	of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+	/*
+	 * Activate the SB600's rtc
+	 */
+	if (nemo_board)
+		platform_device_register_simple("rtc_cmos", -1, rtc_resource, 2);
+#endif
+
 	return 0;
 }
 machine_device_initcall(pasemi, pasemi_publish_devices);

^ permalink raw reply related

* [PATCH NEXT 1/4] powerpc/pasemi: Add PCI initialisation for Nemo board.
From: Darren Stevens @ 2017-12-31 22:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: chzigotzky

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

  AmigaOS...........: http://yam.ch/
  Unix/MacOS/Windows: http://www.mozilla.com/thunderbird/

General information about MIME can be found at:
http://en.wikipedia.org/wiki/MIME

[-- Attachment #2: Type: text/plain, Size: 524 bytes --]

    The A-Eon Amigaone X1000's Nemo motherboard has an AMD SB600
    connected to one of the PCI-e root ports on its PaSemi
    Pwrficient 1628M SoC. Normally the SB600 southbridge would be
    connected to a hidden PCI-e port on the system's northbridge,
    and as a result doesn't fully comply with the PCI-e spec.
    
    Add code to relax the PCI-e detection in both the root port
    and the Linux kernel allowing on board devices to be detected.
    
    Signed-off-by: Darren Stevens <Darren@stevens-zone.net>

---

[-- Attachment #3: pci.patch --]
[-- Type: text/plain, Size: 5035 bytes --]

diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
index 329d2a6..8900dee 100644
--- a/arch/powerpc/platforms/pasemi/pasemi.h
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -3,6 +3,9 @@
 #define _PASEMI_PASEMI_H
 
 extern unsigned long pas_get_boot_time(void);
+#ifdef CONFIG_PPC_PASEMI_NEMO
+extern void nemo_pci_init(void);
+#endif
 extern void pas_pci_init(void);
 extern void pas_pci_irq_fixup(struct pci_dev *dev);
 extern void pas_pci_dma_dev_setup(struct pci_dev *dev);
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index 5ff6108..cb0ac87 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 
 #include <asm/pci-bridge.h>
+#include <asm/isa-bridge.h>
 #include <asm/machdep.h>
 
 #include <asm/ppc-pci.h>
@@ -108,6 +109,92 @@ static int workaround_5945(struct pci_bus *bus, unsigned int devfn,
 	return 1;
 }
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+static int sb600_bus = 5;
+static void __iomem *iob_mapbase = NULL;
+
+static void sb600_set_flag(int bus)
+{
+	struct resource res;
+	struct device_node *dn;
+	int err;
+
+	if (iob_mapbase == NULL) {
+		dn = of_find_compatible_node(NULL, "isa", "pasemi,1682m-iob");
+		if (!dn) {
+			printk(KERN_CRIT "NEMO SB600 missing iob node\n");
+			return;
+		}
+
+		err = of_address_to_resource(dn, 0, &res);
+		of_node_put(dn);
+
+		if (err) {
+			printk(KERN_CRIT "NEMO SB600 missing resource\n");
+			return;
+		}
+
+		printk(KERN_CRIT "NEMO SB600 IOB base %08lx\n",res.start);
+
+		iob_mapbase = ioremap(res.start + 0x100, 0x94);
+	}
+
+	if (iob_mapbase != NULL) {
+		if (bus == sb600_bus) {
+			/*
+			 * This is the SB600's bus, tell the PCI-e root port
+			 * to allow non-zero devices to enumerate.
+			 */
+			out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) | 0x800);
+		} else {
+			/*
+			 * Only scan device 0 on other busses
+			 */
+			out_le32(iob_mapbase + 4, in_le32(iob_mapbase + 4) & ~0x800);
+		}
+	}
+}
+
+static int nemo_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
+			      int offset, int len, u32 *val)
+{
+	struct pci_controller *hose;
+	void volatile __iomem *addr;
+
+	hose = pci_bus_to_host(bus);
+	if (!hose)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (!pa_pxp_offset_valid(bus->number, devfn, offset))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (workaround_5945(bus, devfn, offset, len, val))
+		return PCIBIOS_SUCCESSFUL;
+
+	addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
+
+	sb600_set_flag(bus->number);
+
+	/*
+	 * Note: the caller has already checked that offset is
+	 * suitably aligned and that len is 1, 2 or 4.
+	 */
+	switch (len) {
+	case 1:
+		*val = in_8(addr);
+		break;
+	case 2:
+		*val = in_le16(addr);
+		break;
+	default:
+		*val = in_le32(addr);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+#endif
+
 static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
 			      int offset, int len, u32 *val)
 {
@@ -178,6 +265,20 @@ static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
 	return PCIBIOS_SUCCESSFUL;
 }
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+static struct pci_ops nemo_pxp_ops = {
+	.read = nemo_pxp_read_config,
+	.write = pa_pxp_write_config,
+};
+
+static void __init setup_nemo_pxp(struct pci_controller *hose)
+{
+	hose->ops = &nemo_pxp_ops;
+	hose->cfg_data = ioremap(0xe0000000, 0x10000000);
+}
+
+#endif
+
 static struct pci_ops pa_pxp_ops = {
 	.read = pa_pxp_read_config,
 	.write = pa_pxp_write_config,
@@ -189,6 +290,35 @@ static void __init setup_pa_pxp(struct pci_controller *hose)
 	hose->cfg_data = ioremap(0xe0000000, 0x10000000);
 }
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+static int __init nemo_add_bridge(struct device_node *dev)
+{
+	struct pci_controller *hose;
+
+	pr_debug("Adding PCI host bridge %pOF\n", dev);
+
+	hose = pcibios_alloc_controller(dev);
+	if (!hose)
+		return -ENOMEM;
+
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+	hose->controller_ops = pasemi_pci_controller_ops;
+
+	setup_nemo_pxp(hose);
+
+	printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
+
+	/* Interpret the "ranges" property */
+	pci_process_bridge_OF_ranges(hose, dev, 1);
+
+	/* Scan for an isa bridge. */
+	isa_bridge_find_early(hose);
+
+	return 0;
+}
+#endif
+
 static int __init pas_add_bridge(struct device_node *dev)
 {
 	struct pci_controller *hose;
@@ -213,6 +343,28 @@ static int __init pas_add_bridge(struct device_node *dev)
 	return 0;
 }
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+void __init nemo_pci_init(void)
+{
+	struct device_node *np, *root;
+
+	root = of_find_node_by_path("/");
+	if (!root) {
+		printk(KERN_CRIT "pas_pci_init: can't find root "
+			"of device tree\n");
+		return;
+	}
+
+	pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
+
+	for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
+		if (np->name && !strcmp(np->name, "pxp") && !nemo_add_bridge(np))
+			of_node_get(np);
+
+	of_node_put(root);
+}
+#endif
+
 void __init pas_pci_init(void)
 {
 	struct device_node *np, *root;

^ permalink raw reply related

* [PATCH NEXT 2/4] powerpc/pasemi: Add Nemo board IRQ init routine
From: Darren Stevens @ 2017-12-31 22:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Christian Zigotzky

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

  AmigaOS...........: http://yam.ch/
  Unix/MacOS/Windows: http://www.mozilla.com/thunderbird/

General information about MIME can be found at:
http://en.wikipedia.org/wiki/MIME

[-- Attachment #2: Type: text/plain, Size: 181 bytes --]

    Add a IRQ init routine for the Nemo board which also inits and attatches
    the i8259 found in the SB600.
    
    Signed-off-by: Darren Stevens <Darren@stevens-zone.net>

---

[-- Attachment #3: irq.patch --]
[-- Type: text/plain, Size: 3025 bytes --]

diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index c4a3e93..c583c17 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -34,6 +34,7 @@
 #include <asm/prom.h>
 #include <asm/iommu.h>
 #include <asm/machdep.h>
+#include <asm/i8259.h>
 #include <asm/mpic.h>
 #include <asm/smp.h>
 #include <asm/time.h>
@@ -183,6 +184,99 @@ static int __init pas_setup_mce_regs(void)
 }
 machine_device_initcall(pasemi, pas_setup_mce_regs);
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+static void sb600_8259_cascade(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned int cascade_irq = i8259_irq();
+
+	if (cascade_irq)
+               generic_handle_irq(cascade_irq);
+
+	chip->irq_eoi(&desc->irq_data);
+}
+
+static __init void nemo_init_IRQ(void)
+{
+	struct device_node *np;
+	struct device_node *root, *mpic_node, *i8259_node;
+	unsigned long openpic_addr;
+	const unsigned int *opprop;
+	int naddr, opplen;
+	int mpic_flags;
+	const unsigned int *nmiprop;
+	struct mpic *mpic;
+	int gpio_virq;
+
+	mpic_node = NULL;
+
+	for_each_node_by_type(np, "interrupt-controller")
+		if (of_device_is_compatible(np, "open-pic")) {
+			mpic_node = np;
+			break;
+		}
+	if (!mpic_node)
+		for_each_node_by_type(np, "open-pic") {
+			mpic_node = np;
+			break;
+		}
+	if (!mpic_node) {
+		printk(KERN_ERR
+			"Failed to locate the MPIC interrupt controller\n");
+		return;
+	}
+
+	/* Find address list in /platform-open-pic */
+	root = of_find_node_by_path("/");
+	naddr = of_n_addr_cells(root);
+	opprop = of_get_property(root, "platform-open-pic", &opplen);
+	if (!opprop) {
+		printk(KERN_ERR "No platform-open-pic property.\n");
+		of_node_put(root);
+		return;
+	}
+	openpic_addr = of_read_number(opprop, naddr);
+	printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
+
+	mpic_flags = MPIC_LARGE_VECTORS | MPIC_NO_BIAS | MPIC_NO_RESET;
+
+	nmiprop = of_get_property(mpic_node, "nmi-source", NULL);
+	if (nmiprop)
+		mpic_flags |= MPIC_ENABLE_MCK;
+
+	mpic = mpic_alloc(mpic_node, openpic_addr,
+			  mpic_flags, 0, 0, "PASEMI-OPIC");
+	BUG_ON(!mpic);
+
+	mpic_assign_isu(mpic, 0, mpic->paddr + 0x10000);
+	mpic_init(mpic);
+	/* The NMI/MCK source needs to be prio 15 */
+	if (nmiprop) {
+		nmi_virq = irq_create_mapping(NULL, *nmiprop);
+		mpic_irq_set_priority(nmi_virq, 15);
+		irq_set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
+		mpic_unmask_irq(irq_get_irq_data(nmi_virq));
+	}
+
+
+	/* Connect the SB600's legacy i8259 controller */
+	i8259_node = of_find_node_by_path("/pxp@0,e0000000");
+	i8259_init(i8259_node, 0);
+	of_node_put(i8259_node);
+
+	gpio_virq = irq_create_mapping(NULL, 3);
+	irq_set_irq_type(gpio_virq, IRQ_TYPE_LEVEL_HIGH);
+	irq_set_chained_handler(gpio_virq, sb600_8259_cascade);
+	mpic_unmask_irq(irq_get_irq_data(gpio_virq));
+
+	irq_set_default_host(mpic->irqhost);
+
+	of_node_put(mpic_node);
+	of_node_put(root);
+
+}
+#endif
+
 static __init void pas_init_IRQ(void)
 {
 	struct device_node *np;

^ permalink raw reply related

* [PATCH NEXT 4/4] powerpc/pasemi: Connect Nemo boot code.
From: Darren Stevens @ 2017-12-31 22:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Christian Zigotzky

[-- Attachment #1: Type: text/plain, Size: 178 bytes --]

  AmigaOS...........: http://yam.ch/
  Unix/MacOS/Windows: http://www.mozilla.com/thunderbird/

General information about MIME can be found at:
http://en.wikipedia.org/wiki/MIME

[-- Attachment #2: Type: text/plain, Size: 254 bytes --]

    The previous 3 commits added support code for the Nemo motherbard
    as used in the Amigaone X1000, now wire them up so the board can
    be detected and initalised at boot time.
    
    Signed-off-by: Darren Stevens <Darren@stevens-zone.net>

---

[-- Attachment #3: link.patch --]
[-- Type: text/plain, Size: 1030 bytes --]

diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 8d3664f..bb3a4d5 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -136,7 +136,14 @@ static void __init pas_setup_arch(void)
 	smp_ops = &pas_smp_ops;
 #endif
 	/* Lookup PCI hosts */
+#ifdef CONFIG_PPC_PASEMI_NEMO
+	if (nemo_board)
+		nemo_pci_init();
+	else
+		pas_pci_init();
+#else
 	pas_pci_init();
+#endif
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
@@ -548,6 +555,19 @@ static int __init pas_probe(void)
 	    !of_machine_is_compatible("pasemi,pwrficient"))
 		return 0;
 
+#ifdef CONFIG_PPC_PASEMI_NEMO
+	/*
+	 * Check for the Nemo motherboard here, if we are running on one
+	 * change the machine definition to fit
+	 */
+	if (of_machine_is_compatible("pasemi,nemo")) {
+		pm_power_off		= pas_shutdown;
+		ppc_md.name		= "A-EON Amigaone X1000";
+		ppc_md.init_IRQ		= nemo_init_IRQ;
+		nemo_board = true;
+	}
+#endif
+
 	iommu_init_early_pasemi();
 
 	return 1;

^ permalink raw reply related

* [PATCH] wan/fsl_ucc_hdlc: Delete an error message for a failed memory allocation in ucc_hdlc_probe()
From: SF Markus Elfring @ 2017-12-30 21:30 UTC (permalink / raw)
  To: netdev, linuxppc-dev, Zhao Qiang; +Cc: LKML, kernel-janitors

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Sat, 30 Dec 2017 22:25:44 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/net/wan/fsl_ucc_hdlc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index 33df76405b86..98f8be206bae 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -1082,7 +1082,6 @@ static int ucc_hdlc_probe(struct platform_device *pdev)
 		utdm = kzalloc(sizeof(*utdm), GFP_KERNEL);
 		if (!utdm) {
 			ret = -ENOMEM;
-			dev_err(&pdev->dev, "No mem to alloc ucc tdm data\n");
 			goto free_uhdlc_priv;
 		}
 		uhdlc_priv->utdm = utdm;
-- 
2.15.1

^ permalink raw reply related

* Re: consolidate direct dma mapping and swiotlb support
From: Christoph Hellwig @ 2017-12-30 10:56 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: Christoph Hellwig, iommu, linux-mips, linux-ia64, linux-sh,
	sparclinux, Guan Xuetao, linux-arch, linux-s390, linux-c6x-dev,
	linux-hexagon, x86, linux-snps-arc, adi-buildroot-devel,
	linux-m68k, patches, linux-metag, linux-arm-kernel, Michal Simek,
	linux-parisc, linux-cris-kernel, linux-kernel, linux-alpha,
	linuxppc-dev
In-Reply-To: <23fee3bb-61ce-1735-b264-3acc0109c858@arm.com>

On Fri, Dec 29, 2017 at 10:52:14AM +0000, Vladimir Murzin wrote:
> Is it available in your dma-mapping.git or somewhere else?

  git://git.infradead.org/users/hch/misc.git dma-direct

Gitweb:

  http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-direct

^ permalink raw reply

* Re: [PATCH v3 0/3] create sysfs representation of ACPI HMAT
From: Brice Goglin @ 2017-12-30  9:19 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Dan Williams, Ross Zwisler, Dave Hansen, Michal Hocko,
	linux-kernel@vger.kernel.org, Anaczkowski, Lukasz, Box, David E,
	Kogut, Jaroslaw, Koss, Marcin, Koziej, Artur, Lahtinen, Joonas,
	Moore, Robert, Nachimuthu, Murugasamy, Odzioba, Lukasz,
	Rafael J. Wysocki, Rafael J. Wysocki, Schmauss, Erik,
	Verma, Vishal L, Zheng, Lv, Andrew Morton, Balbir Singh,
	Jerome Glisse, John Hubbard, Len Brown, Tim Chen, devel,
	Linux ACPI, Linux MM, linux-nvdimm@lists.01.org, Linux API,
	linuxppc-dev
In-Reply-To: <20171230065845.GD27959@bombadil.infradead.org>



Le 30/12/2017 à 07:58, Matthew Wilcox a écrit :
> On Wed, Dec 27, 2017 at 10:10:34AM +0100, Brice Goglin wrote:
>>> Perhaps we can enlist /proc/iomem or a similar enumeration interface
>>> to tell userspace the NUMA node and whether the kernel thinks it has
>>> better or worse performance characteristics relative to base
>>> system-RAM, i.e. new IORES_DESC_* values. I'm worried that if we start
>>> publishing absolute numbers in sysfs userspace will default to looking
>>> for specific magic numbers in sysfs vs asking the kernel for memory
>>> that has performance characteristics relative to base "System RAM". In
>>> other words the absolute performance information that the HMAT
>>> publishes is useful to the kernel, but it's not clear that userspace
>>> needs that vs a relative indicator for making NUMA node preference
>>> decisions.
>> Some HPC users will benchmark the machine to discovery actual
>> performance numbers anyway.
>> However, most users won't do this. They will want to know relative
>> performance of different nodes. If you normalize HMAT values by dividing
>> them with system-RAM values, that's likely OK. If you just say "that
>> node is faster than system RAM", it's not precise enough.
> So "this memory has 800% bandwidth of normal" and "this memory has 70%
> bandwidth of normal"?

I guess that would work.
Brice

^ permalink raw reply

* Re: [PATCH v3 0/3] create sysfs representation of ACPI HMAT
From: Matthew Wilcox @ 2017-12-30  6:58 UTC (permalink / raw)
  To: Brice Goglin
  Cc: Dan Williams, Ross Zwisler, Dave Hansen, Michal Hocko,
	linux-kernel@vger.kernel.org, Anaczkowski, Lukasz, Box, David E,
	Kogut, Jaroslaw, Koss, Marcin, Koziej, Artur, Lahtinen, Joonas,
	Moore, Robert, Nachimuthu, Murugasamy, Odzioba, Lukasz,
	Rafael J. Wysocki, Rafael J. Wysocki, Schmauss, Erik,
	Verma, Vishal L, Zheng, Lv, Andrew Morton, Balbir Singh,
	Jerome Glisse, John Hubbard, Len Brown, Tim Chen, devel,
	Linux ACPI, Linux MM, linux-nvdimm@lists.01.org, Linux API,
	linuxppc-dev
In-Reply-To: <71317994-af66-a1b2-4c7a-86a03253cf62@gmail.com>

On Wed, Dec 27, 2017 at 10:10:34AM +0100, Brice Goglin wrote:
> > Perhaps we can enlist /proc/iomem or a similar enumeration interface
> > to tell userspace the NUMA node and whether the kernel thinks it has
> > better or worse performance characteristics relative to base
> > system-RAM, i.e. new IORES_DESC_* values. I'm worried that if we start
> > publishing absolute numbers in sysfs userspace will default to looking
> > for specific magic numbers in sysfs vs asking the kernel for memory
> > that has performance characteristics relative to base "System RAM". In
> > other words the absolute performance information that the HMAT
> > publishes is useful to the kernel, but it's not clear that userspace
> > needs that vs a relative indicator for making NUMA node preference
> > decisions.
> 
> Some HPC users will benchmark the machine to discovery actual
> performance numbers anyway.
> However, most users won't do this. They will want to know relative
> performance of different nodes. If you normalize HMAT values by dividing
> them with system-RAM values, that's likely OK. If you just say "that
> node is faster than system RAM", it's not precise enough.

So "this memory has 800% bandwidth of normal" and "this memory has 70%
bandwidth of normal"?

^ permalink raw reply

* [PATCH] pci/hotplug: Delete error messages for a failed memory allocation in four functions
From: SF Markus Elfring @ 2017-12-29 14:55 UTC (permalink / raw)
  To: linux-pci, Arvind Yadav, Benjamin Herrenschmidt, Bjorn Helgaas,
	Kees Cook, Keith Busch, Michael Ellerman, Mika Westerberg,
	Paul Mackerras, linuxppc-dev
  Cc: LKML, kernel-janitors

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Fri, 29 Dec 2017 15:47:00 +0100

Omit extra messages for a memory allocation failure in these functions.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/pci/hotplug/pciehp_hpc.c  | 5 ++---
 drivers/pci/hotplug/pnv_php.c     | 8 +-------
 drivers/pci/hotplug/shpchp_core.c | 5 ++---
 3 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7bab0606f1a9..ed27635ec740 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -838,10 +838,9 @@ struct controller *pcie_init(struct pcie_device *dev)
 	struct pci_dev *pdev = dev->port;
 
 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
-	if (!ctrl) {
-		dev_err(&dev->device, "%s: Out of memory\n", __func__);
+	if (!ctrl)
 		goto abort;
-	}
+
 	ctrl->pcie = dev;
 	pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
 
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 74f6a17e4614..4ab318a0800d 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -266,7 +266,6 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	fdt1 = kzalloc(0x10000, GFP_KERNEL);
 	if (!fdt1) {
 		ret = -ENOMEM;
-		dev_warn(&php_slot->pdev->dev, "Cannot alloc FDT blob\n");
 		goto out;
 	}
 
@@ -280,8 +279,6 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	fdt = kzalloc(fdt_totalsize(fdt1), GFP_KERNEL);
 	if (!fdt) {
 		ret = -ENOMEM;
-		dev_warn(&php_slot->pdev->dev, "Cannot %d bytes memory\n",
-			 fdt_totalsize(fdt1));
 		goto free_fdt1;
 	}
 
@@ -756,11 +753,8 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
 	 * fine as the PCI devices (PE) aren't functional any more.
 	 */
 	event = kzalloc(sizeof(*event), GFP_ATOMIC);
-	if (!event) {
-		dev_warn(&pdev->dev, "PCI slot [%s] missed hotplug event 0x%04x\n",
-			 php_slot->name, sts);
+	if (!event)
 		return IRQ_HANDLED;
-	}
 
 	dev_info(&pdev->dev, "PCI slot [%s] %s (IRQ: %d)\n",
 		 php_slot->name, added ? "added" : "removed", irq);
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 7bfb87bd2b7e..2f2b87acf179 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -305,10 +305,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return -ENODEV;
 
 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
-	if (!ctrl) {
-		dev_err(&pdev->dev, "%s: Out of memory\n", __func__);
+	if (!ctrl)
 		goto err_out_none;
-	}
+
 	INIT_LIST_HEAD(&ctrl->slot_list);
 
 	rc = shpc_init(ctrl, pdev);
-- 
2.15.1

^ permalink raw reply related

* Re: [PATCH 27/67] dma-direct: add dma address sanity checks
From: Geert Uytterhoeven @ 2017-12-29 14:12 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: iommu, Linux MIPS Mailing List, linux-ia64, Linux-sh list,
	sparclinux, Guan Xuetao, Linux-Arch, linux-s390, linux-c6x-dev,
	open list:QUALCOMM HEXAGON..., the arch/x86 maintainers, arcml,
	adi-buildroot-devel, linux-m68k, patches,
	open list:METAG ARCHITECTURE, linux-arm-kernel, Michal Simek,
	Parisc List, Cris, Linux Kernel Mailing List, alpha, linuxppc-dev
In-Reply-To: <20171229081911.2802-28-hch@lst.de>

Hi Christoph,

On Fri, Dec 29, 2017 at 9:18 AM, Christoph Hellwig <hch@lst.de> wrote:
> Roughly based on the x86 pci-nommu implementation.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Thanks for your patch!

> --- a/lib/dma-direct.c
> +++ b/lib/dma-direct.c
> @@ -9,6 +9,24 @@
>  #include <linux/scatterlist.h>
>  #include <linux/pfn.h>
>
> +#define DIRECT_MAPPING_ERROR           0
> +
> +static bool
> +check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
> +               const char *caller)
> +{
> +       if (unlikely(dev && !dma_capable(dev, dma_addr, size))) {
> +               if (*dev->dma_mask >= DMA_BIT_MASK(32)) {
> +                       dev_err(dev,
> +                               "%s: overflow %llx+%zu of device mask %llx\n",

Please use "%pad" to format dma_addr_t ...

> +                               caller, (long long)dma_addr, size,

... and use &dma_addr.

> +                               (long long)*dev->dma_mask);

This cast is not needed, as u64 is unsigned long long in kernelspace on
all architectures.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: consolidate direct dma mapping and swiotlb support
From: Vladimir Murzin @ 2017-12-29 10:52 UTC (permalink / raw)
  To: Christoph Hellwig, iommu
  Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
	linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
	linux-snps-arc, adi-buildroot-devel, linux-m68k, patches,
	linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
	linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

On 29/12/17 08:18, Christoph Hellwig wrote:
> Almost every architecture supports a direct dma mapping implementation,
> where no iommu is used and the device dma address is a 1:1 mapping to
> the physical address or has a simple linear offset.  Currently the
> code for this implementation is most duplicated over the architectures,
> and the duplicated again in the swiotlb code, and then duplicated again
> for special cases like the x86 memory encryption DMA ops.
> 
> This series takes the existing very simple dma-noop dma mapping
> implementation, enhances it with all the x86 features and quirks, and
> creates a common set of architecture hooks for it and the swiotlb code.
> 
> It then switches a large number of architectures to this generic
> direct map implement and the new generic swiotlb dma_map ops.
> 
> Note that for now this only handles architectures that do cache coherent
> DMA, but a similar consolidation for non-coherent architectures is in the
> work for later merge windows.

Is it available in your dma-mapping.git or somewhere else?

Cheers
Vladimir

> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* Re: [PATCH 17/67] microblaze: rename dma_direct to dma_microblaze
From: Julian Calaby @ 2017-12-29 10:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: iommu, linux-alpha, linux-snps-arc, Mailing List, Arm,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch,
	linux-kernel@vger.kernel.org
In-Reply-To: <20171229081911.2802-18-hch@lst.de>

Hi Christoph,

On Fri, Dec 29, 2017 at 7:18 PM, Christoph Hellwig <hch@lst.de> wrote:
> This frees the dma_direct_* namespace for a generic implementation.

Don't you mean "dma_nommu" not "dma_microblaze" in the subject line?

Thanks,

-- 
Julian Calaby

Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

^ permalink raw reply

* [PATCH 67/67] swiotlb: remove various exports
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

All these symbols are only used by arch dma_ops implementations or
xen-swiotlb.  None of which can be modular.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 lib/swiotlb.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 77a40b508db8..823e1055a394 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -591,7 +591,6 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
 
 	return tlb_addr;
 }
-EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single);
 
 /*
  * Allocates bounce buffer and returns its kernel virtual address.
@@ -661,7 +660,6 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
 	}
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
 }
-EXPORT_SYMBOL_GPL(swiotlb_tbl_unmap_single);
 
 void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
 			     size_t size, enum dma_data_direction dir,
@@ -693,7 +691,6 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
 		BUG();
 	}
 }
-EXPORT_SYMBOL_GPL(swiotlb_tbl_sync_single);
 
 static void *
 swiotlb_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle)
@@ -827,7 +824,6 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 
 	return __phys_to_dma(dev, io_tlb_overflow_buffer);
 }
-EXPORT_SYMBOL_GPL(swiotlb_map_page);
 
 /*
  * Unmap a single streaming mode DMA translation.  The dma_addr and size must
@@ -868,7 +864,6 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
 {
 	unmap_single(hwdev, dev_addr, size, dir, attrs);
 }
-EXPORT_SYMBOL_GPL(swiotlb_unmap_page);
 
 /*
  * Make physical memory consistent for a single streaming mode DMA translation
@@ -906,7 +901,6 @@ swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
 {
 	swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
 }
-EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
 
 void
 swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
@@ -914,7 +908,6 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
 {
 	swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
 }
-EXPORT_SYMBOL(swiotlb_sync_single_for_device);
 
 /*
  * Map a set of buffers described by scatterlist in streaming mode for DMA.
@@ -966,7 +959,6 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
 	}
 	return nelems;
 }
-EXPORT_SYMBOL(swiotlb_map_sg_attrs);
 
 /*
  * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
@@ -986,7 +978,6 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
 		unmap_single(hwdev, sg->dma_address, sg_dma_len(sg), dir,
 			     attrs);
 }
-EXPORT_SYMBOL(swiotlb_unmap_sg_attrs);
 
 /*
  * Make physical memory consistent for a set of streaming mode DMA translations
@@ -1014,7 +1005,6 @@ swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
 {
 	swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
 }
-EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
 
 void
 swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
@@ -1022,14 +1012,12 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
 {
 	swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
 }
-EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
 
 int
 swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr)
 {
 	return (dma_addr == __phys_to_dma(hwdev, io_tlb_overflow_buffer));
 }
-EXPORT_SYMBOL(swiotlb_dma_mapping_error);
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -1042,7 +1030,6 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
 {
 	return __phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
 }
-EXPORT_SYMBOL(swiotlb_dma_supported);
 
 #ifdef CONFIG_DMA_DIRECT_OPS
 void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
-- 
2.14.2

^ permalink raw reply related

* [PATCH 66/67] swiotlb: remove swiotlb_{alloc,free}_coherent
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

Unused now that everyone uses swiotlb_{alloc,free}.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/swiotlb.h |  8 --------
 lib/swiotlb.c           | 41 -----------------------------------------
 2 files changed, 49 deletions(-)

diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 5b1f2a00491c..965be92c33b5 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -72,14 +72,6 @@ void *swiotlb_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
 void swiotlb_free(struct device *dev, size_t size, void *vaddr,
 		dma_addr_t dma_addr, unsigned long attrs);
 
-extern void
-*swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			dma_addr_t *dma_handle, gfp_t flags);
-
-extern void
-swiotlb_free_coherent(struct device *hwdev, size_t size,
-		      void *vaddr, dma_addr_t dma_handle);
-
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
 				   enum dma_data_direction dir,
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 4ea0b5710618..77a40b508db8 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -157,13 +157,6 @@ unsigned long swiotlb_size_or_default(void)
 	return size ? size : (IO_TLB_DEFAULT_SIZE);
 }
 
-/* Note that this doesn't work with highmem page */
-static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
-				      volatile void *address)
-{
-	return phys_to_dma(hwdev, virt_to_phys(address));
-}
-
 static bool no_iotlb_memory;
 
 void swiotlb_print_info(void)
@@ -743,31 +736,6 @@ swiotlb_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle)
 	return NULL;
 }
 
-void *
-swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-		       dma_addr_t *dma_handle, gfp_t flags)
-{
-	int order = get_order(size);
-	void *ret;
-
-	ret = (void *)__get_free_pages(flags, order);
-	if (ret) {
-		*dma_handle = swiotlb_virt_to_bus(hwdev, ret);
-		if (*dma_handle  + size - 1 <= hwdev->coherent_dma_mask) {
-			memset(ret, 0, size);
-			return ret;
-		}
-
-		/*
-		 * The allocated memory isn't reachable by the device.
-		 */
-		free_pages((unsigned long) ret, order);
-	}
-
-	return swiotlb_alloc_buffer(hwdev, size, dma_handle);
-}
-EXPORT_SYMBOL(swiotlb_alloc_coherent);
-
 static bool swiotlb_free_buffer(struct device *dev, size_t size,
 		dma_addr_t dma_addr)
 {
@@ -787,15 +755,6 @@ static bool swiotlb_free_buffer(struct device *dev, size_t size,
 	return true;
 }
 
-void
-swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-		      dma_addr_t dev_addr)
-{
-	if (!swiotlb_free_buffer(hwdev, size, dev_addr))
-		free_pages((unsigned long)vaddr, get_order(size));
-}
-EXPORT_SYMBOL(swiotlb_free_coherent);
-
 static void
 swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
 	     int do_panic)
-- 
2.14.2

^ permalink raw reply related

* [PATCH 65/67] arm64: use swiotlb_alloc and swiotlb_free
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

The generic swiotlb_alloc and swiotlb_free routines already take care
of CMA allocations and adding GFP_DMA32 where needed, so use them
instead of the arm specific helpers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm64/Kconfig          |  1 +
 arch/arm64/mm/dma-mapping.c | 46 +++------------------------------------------
 2 files changed, 4 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6b6985f15d02..53205c02b18a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -59,6 +59,7 @@ config ARM64
 	select COMMON_CLK
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS
+	select DMA_DIRECT_OPS
 	select EDAC_SUPPORT
 	select FRAME_POINTER
 	select GENERIC_ALLOCATOR
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 0d641875b20e..a96ec0181818 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -91,46 +91,6 @@ static int __free_from_pool(void *start, size_t size)
 	return 1;
 }
 
-static void *__dma_alloc_coherent(struct device *dev, size_t size,
-				  dma_addr_t *dma_handle, gfp_t flags,
-				  unsigned long attrs)
-{
-	if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
-	    dev->coherent_dma_mask <= DMA_BIT_MASK(32))
-		flags |= GFP_DMA32;
-	if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
-		struct page *page;
-		void *addr;
-
-		page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
-						 get_order(size), flags);
-		if (!page)
-			return NULL;
-
-		*dma_handle = phys_to_dma(dev, page_to_phys(page));
-		addr = page_address(page);
-		memset(addr, 0, size);
-		return addr;
-	} else {
-		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
-	}
-}
-
-static void __dma_free_coherent(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle,
-				unsigned long attrs)
-{
-	bool freed;
-	phys_addr_t paddr = dma_to_phys(dev, dma_handle);
-
-
-	freed = dma_release_from_contiguous(dev,
-					phys_to_page(paddr),
-					size >> PAGE_SHIFT);
-	if (!freed)
-		swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
 static void *__dma_alloc(struct device *dev, size_t size,
 			 dma_addr_t *dma_handle, gfp_t flags,
 			 unsigned long attrs)
@@ -152,7 +112,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
 		return addr;
 	}
 
-	ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
+	ptr = swiotlb_alloc(dev, size, dma_handle, flags, attrs);
 	if (!ptr)
 		goto no_mem;
 
@@ -173,7 +133,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
 	return coherent_ptr;
 
 no_map:
-	__dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
+	swiotlb_free(dev, size, ptr, *dma_handle, attrs);
 no_mem:
 	return NULL;
 }
@@ -191,7 +151,7 @@ static void __dma_free(struct device *dev, size_t size,
 			return;
 		vunmap(vaddr);
 	}
-	__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
+	swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs);
 }
 
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
-- 
2.14.2

^ permalink raw reply related

* [PATCH 64/67] arm64: replace ZONE_DMA with ZONE_DMA32
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

arm64 uses ZONE_DMA for allocations below 32-bits.  These days we
name the zone for that ZONE_DMA32, which will allow to use the
dma-direct and generic swiotlb code as-is, so rename it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/arm64/Kconfig          |  2 +-
 arch/arm64/mm/dma-mapping.c |  6 +++---
 arch/arm64/mm/init.c        | 16 ++++++++--------
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c9a7e9e1414f..6b6985f15d02 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -227,7 +227,7 @@ config GENERIC_CSUM
 config GENERIC_CALIBRATE_DELAY
 	def_bool y
 
-config ZONE_DMA
+config ZONE_DMA32
 	def_bool y
 
 config HAVE_GENERIC_GUP
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 6840426bbe77..0d641875b20e 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -95,9 +95,9 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
 				  unsigned long attrs)
 {
-	if (IS_ENABLED(CONFIG_ZONE_DMA) &&
+	if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
 	    dev->coherent_dma_mask <= DMA_BIT_MASK(32))
-		flags |= GFP_DMA;
+		flags |= GFP_DMA32;
 	if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
 		struct page *page;
 		void *addr;
@@ -397,7 +397,7 @@ static int __init atomic_pool_init(void)
 		page = dma_alloc_from_contiguous(NULL, nr_pages,
 						 pool_size_order, GFP_KERNEL);
 	else
-		page = alloc_pages(GFP_DMA, pool_size_order);
+		page = alloc_pages(GFP_DMA32, pool_size_order);
 
 	if (page) {
 		int ret;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 00e7b900ca41..8f03276443c9 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -217,7 +217,7 @@ static void __init reserve_elfcorehdr(void)
 }
 #endif /* CONFIG_CRASH_DUMP */
 /*
- * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
+ * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It
  * currently assumes that for memory starting above 4G, 32-bit devices will
  * use a DMA offset.
  */
@@ -233,8 +233,8 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
 
-	if (IS_ENABLED(CONFIG_ZONE_DMA))
-		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+	if (IS_ENABLED(CONFIG_ZONE_DMA32))
+		max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys());
 	max_zone_pfns[ZONE_NORMAL] = max;
 
 	free_area_init_nodes(max_zone_pfns);
@@ -251,9 +251,9 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 	memset(zone_size, 0, sizeof(zone_size));
 
 	/* 4GB maximum for 32-bit only capable devices */
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
 	max_dma = PFN_DOWN(arm64_dma_phys_limit);
-	zone_size[ZONE_DMA] = max_dma - min;
+	zone_size[ZONE_DMA32] = max_dma - min;
 #endif
 	zone_size[ZONE_NORMAL] = max - max_dma;
 
@@ -266,10 +266,10 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 		if (start >= max)
 			continue;
 
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
 		if (start < max_dma) {
 			unsigned long dma_end = min(end, max_dma);
-			zhole_size[ZONE_DMA] -= dma_end - start;
+			zhole_size[ZONE_DMA32] -= dma_end - start;
 		}
 #endif
 		if (end > max_dma) {
@@ -467,7 +467,7 @@ void __init arm64_memblock_init(void)
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
-	if (IS_ENABLED(CONFIG_ZONE_DMA))
+	if (IS_ENABLED(CONFIG_ZONE_DMA32))
 		arm64_dma_phys_limit = max_zone_dma_phys();
 	else
 		arm64_dma_phys_limit = PHYS_MASK + 1;
-- 
2.14.2

^ permalink raw reply related

* [PATCH 63/67] mips: use swiotlb_{alloc,free}
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

These already include the GFP_DMA/GFP_DMA32 usage, and will use CMA
memory if enabled, thus avoiding the GFP_NORETRY hack.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/mips/cavium-octeon/Kconfig           |  1 +
 arch/mips/cavium-octeon/dma-octeon.c      | 26 +++-----------------------
 arch/mips/loongson64/Kconfig              |  1 +
 arch/mips/loongson64/common/dma-swiotlb.c | 21 ++-------------------
 4 files changed, 7 insertions(+), 42 deletions(-)

diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 204a1670fd9b..b5eee1a57d6c 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -75,6 +75,7 @@ config NEED_SG_DMA_LENGTH
 
 config SWIOTLB
 	def_bool y
+	select DMA_DIRECT_OPS
 	select IOMMU_HELPER
 	select NEED_SG_DMA_LENGTH
 
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 6440ad3f9e3b..7b335ab21697 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -159,33 +159,13 @@ static void octeon_dma_sync_sg_for_device(struct device *dev,
 static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
 	dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	void *ret;
-
-	if (IS_ENABLED(CONFIG_ZONE_DMA) && dev == NULL)
-		gfp |= __GFP_DMA;
-	else if (IS_ENABLED(CONFIG_ZONE_DMA) &&
-		 dev->coherent_dma_mask <= DMA_BIT_MASK(24))
-		gfp |= __GFP_DMA;
-	else if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
-		 dev->coherent_dma_mask <= DMA_BIT_MASK(32))
-		gfp |= __GFP_DMA32;
-
-	/* Don't invoke OOM killer */
-	gfp |= __GFP_NORETRY;
-
-	ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+	void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
 
 	mb();
 
 	return ret;
 }
 
-static void octeon_dma_free_coherent(struct device *dev, size_t size,
-	void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
-	swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
 static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
 	return paddr;
@@ -225,7 +205,7 @@ EXPORT_SYMBOL(__dma_to_phys);
 static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
 	.dma_map_ops = {
 		.alloc = octeon_dma_alloc_coherent,
-		.free = octeon_dma_free_coherent,
+		.free = swiotlb_free,
 		.map_page = octeon_dma_map_page,
 		.unmap_page = swiotlb_unmap_page,
 		.map_sg = octeon_dma_map_sg,
@@ -311,7 +291,7 @@ void __init plat_swiotlb_setup(void)
 static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
 	.dma_map_ops = {
 		.alloc = octeon_dma_alloc_coherent,
-		.free = octeon_dma_free_coherent,
+		.free = swiotlb_free,
 		.map_page = octeon_dma_map_page,
 		.unmap_page = swiotlb_unmap_page,
 		.map_sg = octeon_dma_map_sg,
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 0d249fc3cfe9..6f109bb54cdb 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -136,6 +136,7 @@ config SWIOTLB
 	bool "Soft IOMMU Support for All-Memory DMA"
 	default y
 	depends on CPU_LOONGSON3
+	select DMA_DIRECT_OPS
 	select IOMMU_HELPER
 	select NEED_SG_DMA_LENGTH
 	select NEED_DMA_MAP_STATE
diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c
index 0a02ea70e39f..6a739f8ae110 100644
--- a/arch/mips/loongson64/common/dma-swiotlb.c
+++ b/arch/mips/loongson64/common/dma-swiotlb.c
@@ -13,29 +13,12 @@
 static void *loongson_dma_alloc_coherent(struct device *dev, size_t size,
 		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
-	void *ret;
+	void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
 
-	if ((IS_ENABLED(CONFIG_ISA) && dev == NULL) ||
-	    (IS_ENABLED(CONFIG_ZONE_DMA) &&
-	     dev->coherent_dma_mask < DMA_BIT_MASK(32)))
-		gfp |= __GFP_DMA;
-	else if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
-		 dev->coherent_dma_mask < DMA_BIT_MASK(40))
-		gfp |= __GFP_DMA32;
-
-	gfp |= __GFP_NORETRY;
-
-	ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
 	mb();
 	return ret;
 }
 
-static void loongson_dma_free_coherent(struct device *dev, size_t size,
-		void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
-	swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
 static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page,
 				unsigned long offset, size_t size,
 				enum dma_data_direction dir,
@@ -106,7 +89,7 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr)
 
 static const struct dma_map_ops loongson_dma_map_ops = {
 	.alloc = loongson_dma_alloc_coherent,
-	.free = loongson_dma_free_coherent,
+	.free = swiotlb_free,
 	.map_page = loongson_dma_map_page,
 	.unmap_page = swiotlb_unmap_page,
 	.map_sg = loongson_dma_map_sg,
-- 
2.14.2

^ permalink raw reply related

* [PATCH 62/67] mips/netlogic: remove swiotlb support
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

nlm_swiotlb_dma_ops is unused code, so the whole swiotlb support is dead.
If it gets resurrected at some point it should use the generic
swiotlb_dma_ops instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/mips/include/asm/netlogic/common.h |  3 --
 arch/mips/netlogic/Kconfig              |  5 --
 arch/mips/netlogic/common/Makefile      |  1 -
 arch/mips/netlogic/common/nlm-dma.c     | 94 ---------------------------------
 4 files changed, 103 deletions(-)
 delete mode 100644 arch/mips/netlogic/common/nlm-dma.c

diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
index a6e6cbebe046..57616649b4f3 100644
--- a/arch/mips/include/asm/netlogic/common.h
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -87,9 +87,6 @@ unsigned int nlm_get_cpu_frequency(void);
 extern const struct plat_smp_ops nlm_smp_ops;
 extern char nlm_reset_entry[], nlm_reset_entry_end[];
 
-/* SWIOTLB */
-extern const struct dma_map_ops nlm_swiotlb_dma_ops;
-
 extern unsigned int nlm_threads_per_core;
 extern cpumask_t nlm_cpumask;
 
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index 8296b13affd2..7fcfc7fe9f14 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -89,9 +89,4 @@ config IOMMU_HELPER
 config NEED_SG_DMA_LENGTH
 	bool
 
-config SWIOTLB
-	def_bool y
-	select NEED_SG_DMA_LENGTH
-	select IOMMU_HELPER
-
 endif
diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile
index 60d00b5d748e..89f6e3f39fed 100644
--- a/arch/mips/netlogic/common/Makefile
+++ b/arch/mips/netlogic/common/Makefile
@@ -1,6 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y				+= irq.o time.o
-obj-y				+= nlm-dma.o
 obj-y				+= reset.o
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o
 obj-$(CONFIG_EARLY_PRINTK)	+= earlycons.o
diff --git a/arch/mips/netlogic/common/nlm-dma.c b/arch/mips/netlogic/common/nlm-dma.c
deleted file mode 100644
index 49c975b6aa28..000000000000
--- a/arch/mips/netlogic/common/nlm-dma.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-*  Copyright (C) 2003-2013 Broadcom Corporation
-*  All Rights Reserved
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the Broadcom
- * license below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/bootmem.h>
-#include <linux/export.h>
-#include <linux/swiotlb.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-
-#include <asm/bootinfo.h>
-
-static char *nlm_swiotlb;
-
-static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
-{
-#ifdef CONFIG_ZONE_DMA32
-	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
-		gfp |= __GFP_DMA32;
-#endif
-
-	/* Don't invoke OOM killer */
-	gfp |= __GFP_NORETRY;
-
-	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
-}
-
-static void nlm_dma_free_coherent(struct device *dev, size_t size,
-	void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
-	swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
-const struct dma_map_ops nlm_swiotlb_dma_ops = {
-	.alloc = nlm_dma_alloc_coherent,
-	.free = nlm_dma_free_coherent,
-	.map_page = swiotlb_map_page,
-	.unmap_page = swiotlb_unmap_page,
-	.map_sg = swiotlb_map_sg_attrs,
-	.unmap_sg = swiotlb_unmap_sg_attrs,
-	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
-	.sync_single_for_device = swiotlb_sync_single_for_device,
-	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-	.sync_sg_for_device = swiotlb_sync_sg_for_device,
-	.mapping_error = swiotlb_dma_mapping_error,
-	.dma_supported = swiotlb_dma_supported
-};
-
-void __init plat_swiotlb_setup(void)
-{
-	size_t swiotlbsize;
-	unsigned long swiotlb_nslabs;
-
-	swiotlbsize = 1 << 20; /* 1 MB for now */
-	swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
-	swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
-	swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
-
-	nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
-	swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1);
-}
-- 
2.14.2

^ permalink raw reply related

* [PATCH 61/67] tile: use generic swiotlb_ops
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

These are identical to the tile ops, and would also support CMA
if enabled on tile.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/tile/Kconfig          |  1 +
 arch/tile/kernel/pci-dma.c | 36 +++---------------------------------
 2 files changed, 4 insertions(+), 33 deletions(-)

diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 30c586686f29..ef9d403cbbe4 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -261,6 +261,7 @@ config NEED_SG_DMA_LENGTH
 config SWIOTLB
 	bool
 	default TILEGX
+	select DMA_DIRECT_OPS
 	select IOMMU_HELPER
 	select NEED_SG_DMA_LENGTH
 	select ARCH_HAS_DMA_SET_COHERENT_MASK
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index a9b48520eeb9..6e9365234b6a 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -511,39 +511,9 @@ EXPORT_SYMBOL(gx_pci_dma_map_ops);
 /* PCI DMA mapping functions for legacy PCI devices */
 
 #ifdef CONFIG_SWIOTLB
-static void *tile_swiotlb_alloc_coherent(struct device *dev, size_t size,
-					 dma_addr_t *dma_handle, gfp_t gfp,
-					 unsigned long attrs)
-{
-	gfp |= GFP_DMA32;
-	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
-}
-
-static void tile_swiotlb_free_coherent(struct device *dev, size_t size,
-				       void *vaddr, dma_addr_t dma_addr,
-				       unsigned long attrs)
-{
-	swiotlb_free_coherent(dev, size, vaddr, dma_addr);
-}
-
-static const struct dma_map_ops pci_swiotlb_dma_ops = {
-	.alloc = tile_swiotlb_alloc_coherent,
-	.free = tile_swiotlb_free_coherent,
-	.map_page = swiotlb_map_page,
-	.unmap_page = swiotlb_unmap_page,
-	.map_sg = swiotlb_map_sg_attrs,
-	.unmap_sg = swiotlb_unmap_sg_attrs,
-	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
-	.sync_single_for_device = swiotlb_sync_single_for_device,
-	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-	.sync_sg_for_device = swiotlb_sync_sg_for_device,
-	.dma_supported = swiotlb_dma_supported,
-	.mapping_error = swiotlb_dma_mapping_error,
-};
-
 static const struct dma_map_ops pci_hybrid_dma_ops = {
-	.alloc = tile_swiotlb_alloc_coherent,
-	.free = tile_swiotlb_free_coherent,
+	.alloc = swiotlb_alloc,
+	.free = swiotlb_free,
 	.map_page = tile_pci_dma_map_page,
 	.unmap_page = tile_pci_dma_unmap_page,
 	.map_sg = tile_pci_dma_map_sg,
@@ -554,7 +524,7 @@ static const struct dma_map_ops pci_hybrid_dma_ops = {
 	.sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
 };
 
-const struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops;
+const struct dma_map_ops *gx_legacy_pci_dma_map_ops = &swiotlb_dma_ops;
 const struct dma_map_ops *gx_hybrid_pci_dma_map_ops = &pci_hybrid_dma_ops;
 #else
 const struct dma_map_ops *gx_legacy_pci_dma_map_ops;
-- 
2.14.2

^ permalink raw reply related

* [PATCH 60/67] tile: replace ZONE_DMA with ZONE_DMA32
From: Christoph Hellwig @ 2017-12-29  8:19 UTC (permalink / raw)
  To: iommu
  Cc: linux-alpha, linux-snps-arc, linux-arm-kernel,
	adi-buildroot-devel, linux-c6x-dev, linux-cris-kernel,
	linux-hexagon, linux-ia64, linux-m68k, linux-metag, Michal Simek,
	linux-mips, linux-parisc, linuxppc-dev, patches, linux-s390,
	linux-sh, sparclinux, Guan Xuetao, x86, linux-arch, linux-kernel
In-Reply-To: <20171229081911.2802-1-hch@lst.de>

tile uses ZONE_DMA for allocations below 32-bits.  These days we
name the zone for that ZONE_DMA32, which will allow to use the
dma-direct and generic swiotlb code as-is, so rename it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/tile/Kconfig          | 2 +-
 arch/tile/kernel/pci-dma.c | 4 ++--
 arch/tile/kernel/setup.c   | 8 ++++----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 02f269cfa538..30c586686f29 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -249,7 +249,7 @@ config HIGHMEM
 
 	  If unsure, say "true".
 
-config ZONE_DMA
+config ZONE_DMA32
 	def_bool y
 
 config IOMMU_HELPER
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index 9072e2c25e59..a9b48520eeb9 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -54,7 +54,7 @@ static void *tile_dma_alloc_coherent(struct device *dev, size_t size,
 	 * which case we will return NULL.  But such devices are uncommon.
 	 */
 	if (dma_mask <= DMA_BIT_MASK(32)) {
-		gfp |= GFP_DMA;
+		gfp |= GFP_DMA32;
 		node = 0;
 	}
 
@@ -515,7 +515,7 @@ static void *tile_swiotlb_alloc_coherent(struct device *dev, size_t size,
 					 dma_addr_t *dma_handle, gfp_t gfp,
 					 unsigned long attrs)
 {
-	gfp |= GFP_DMA;
+	gfp |= GFP_DMA32;
 	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
 }
 
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index ad83c1e66dbd..eb4e198f6f93 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -814,11 +814,11 @@ static void __init zone_sizes_init(void)
 #endif
 
 		if (start < dma_end) {
-			zones_size[ZONE_DMA] = min(zones_size[ZONE_NORMAL],
+			zones_size[ZONE_DMA32] = min(zones_size[ZONE_NORMAL],
 						   dma_end - start);
-			zones_size[ZONE_NORMAL] -= zones_size[ZONE_DMA];
+			zones_size[ZONE_NORMAL] -= zones_size[ZONE_DMA32];
 		} else {
-			zones_size[ZONE_DMA] = 0;
+			zones_size[ZONE_DMA32] = 0;
 		}
 
 		/* Take zone metadata from controller 0 if we're isolnode. */
@@ -830,7 +830,7 @@ static void __init zone_sizes_init(void)
 		       PFN_UP(node_percpu[i]));
 
 		/* Track the type of memory on each node */
-		if (zones_size[ZONE_NORMAL] || zones_size[ZONE_DMA])
+		if (zones_size[ZONE_NORMAL] || zones_size[ZONE_DMA32])
 			node_set_state(i, N_NORMAL_MEMORY);
 #ifdef CONFIG_HIGHMEM
 		if (end != start)
-- 
2.14.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox