* [PATCH v5 0/2] cpuidle/pseries: cleanup of the CEDE0 latency fixup code
From: Gautham R. Shenoy @ 2021-07-19 6:33 UTC (permalink / raw)
To: Rafael J. Wysocki, Daniel Lezcano, Michael Ellerman,
Aneesh Kumar K.V, Vaidyanathan Srinivasan, Michal Suchanek
Cc: Gautham R. Shenoy, linuxppc-dev, joedecke, linux-pm
From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
Hi,
This is the v5 of the patchset to fixup CEDE0 latency only from
POWER10 onwards.
The previous versions of the patches are
v4 : https://lore.kernel.org/linux-pm/1623048014-16451-1-git-send-email-ego@linux.vnet.ibm.com/
v3 : https://lore.kernel.org/linuxppc-dev/1619697982-28461-1-git-send-email-ego@linux.vnet.ibm.com/
v2 : https://lore.kernel.org/linuxppc-dev/1619673517-10853-1-git-send-email-ego@linux.vnet.ibm.com/
v1 : https://lore.kernel.org/linuxppc-dev/1619104049-5118-1-git-send-email-ego@linux.vnet.ibm.com/
v4 --> v5 changes
* Patch 1 : Unchanged. Rebased it against the latest powerpc/merge
tree. With this patch, on processors older than POWER10, the CEDE
latency is set to the hardcoded value of 10us which is closer to the
measured value (details of the measurement in Patch 1).
* Added a Patch 2/2 titled "cpuidle/pseries: Do not cap the CEDE0
latency in fixup_cede0_latency()" which will ensure that on POWER10
onwards we simply take the latency value exposed by the firmware
without keeping an upper cap of 10us. This upper cap was previously
required to prevent regression on POWER8 which had advertized
latency values higher than 10us while the measured values were
lesser. With Patch 1, we don't need the upper cap any longer.
Tested the series on POWER8, POWER9 and POWER10 with the
cpuidle-smt-performance test case
(https://github.com/gautshen/misc/tree/master/cpuidle-smt-performance) .
This test has three classes of threads
1. Workload thread which computes fibonacci numbers (Pinned to the
primary thread CPU 8). We are interested in the throughput of this
workload thread.
2. Three irritator threads which are pinned to the secondary CPUs of
the core on which the workload thread is running (CPUs 10, 12,
14). These irritators block on a pipe until woken up by a
waker. After being woken up, they again go back to sleep by
blocking on a pipe read. We are interested in the wakeup latency of
the irritator threads.
3. A waker thread which, pinned to a different core (CPU 16) from
where the workload and the irritators are running, periodically
wakes up the three irritator threads by writing to their respective
pipes. The purpose of these periodic wakeups is to prime the
cpuidle governor on the irritator CPUs to pick the idle state the
wakeup period.
We measure the wakeup latency of the irritator threads, which tells us
the impact of entering a particular combinations of idle states. Thus
shallower the state, lower should be the wakeup latency.
We also measure the throughput of the fibonacci workload to measure
the single-thread performance in the presence of the waking irritators
on the sibling threads. Entering an idle state which performs SMT
folding should show greater throughput.
There is no observable difference in the behaviour on POWER8 and
POWER10 with and without the patch series, since the CEDE latencies on
both of them with and without the patch are 10us.
However, on POWER9, without the patch, the CEDE latency is 1us based
on the value returned by the firmware (which is not accurate), while
with the patch it is set to the default value of 10us which is closer
to the accurate measure.
The throughput, wakeup latency, throughput and the snooze, CEDE idle
percentage residency results on POWER9 with and without patch are as
follows.
We observe that for a wakeup period between 20us - 100us, the wakeup
latency of the irritator threads with the patch improves by 40-45%.
Though note that with the patch, the throughput of the fibbonacci
workload drops by 5-10% when the wakeup period of the irritator
threads is between 20us-100us. This is an acceptable tradeoff since
there are certain benchmarks on POWER9 which are very sensitive to the
wakeup latency and have a sleeping duration of less than 100us.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avg Wakeup Latency of the irritator threads
(lower the better)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Irritator | |
wakeup | Without | With
period | Patch | Patch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 us | 3.703 us | 3.632 us ( -1.91%)
2 us | 3.843 us | 3.925 us ( +2.13%)
5 us | 8.575 us | 8.656 us ( +0.94%)
10 us | 8.264 us | 8.242 us ( -0.27%)
20 us | 8.672 us | 8.256 us ( -4.80%)
50 us | 15.552 us | 8.257 us (-46.90%)
80 us | 15.603 us | 8.803 us (-43.58%)
100 us | 15.617 us | 8.328 us (-46.67%)
120 us | 15.612 us | 14.505 us ( -7.09%)
500 us | 15.957 us | 15.723 us ( -1.47%)
1000 us | 16.526 us | 16.502 us ( -0.14%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fibonacci workload throughput in Million Operations
per second (higher the better)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Irritator | |
wakeup | Without | With
period | Patch | Patch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 us | 44.234 Mops/s | 44.305 Mops/s ( +0.16%)
2 us | 44.290 Mops/s | 44.233 Mops/s ( -0.13%)
5 us | 44.757 Mops/s | 44.759 Mops/s ( -0.01%)
10 us | 46.169 Mops/s | 46.049 Mops/s ( -0.25%)
20 us | 48.263 Mops/s | 49.647 Mops/s ( +2.87%)
50 us | 52.817 Mops/s | 52.310 Mops/s ( -0.96%)
80 us | 57.338 Mops/s | 53.216 Mops/s ( -7.19%)
100 us | 58.958 Mops/s | 53.497 Mops/s ( -9.26%)
120 us | 60.060 Mops/s | 58.980 Mops/s ( -1.80%)
500 us | 64.484 Mops/s | 64.460 Mops/s ( -0.04%)
1000 us | 65.200 Mops/s | 65.188 Mops/s ( -0.02%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(snooze, CEDE Residency Percentage)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Irritator | |
wakeup | Without | With
period | Patch | Patch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 us | ( 0.40%, 0.00%) | (0.28%, 0.00%)
2 us | ( 0.42%, 0.00%) | (0.33%, 0.00%)
5 us | ( 3.94%, 0.00%) | (3.89%, 0.00%)
10 us | (21.85%, 0.00%) | (21.62%, 0.00%)
20 us | (43.44%, 0.00%) | (50.90%, 0.00%)
50 us | ( 0.03%, 76.07%) | (76.85%, 0.00%)
80 us | ( 0.07%, 84.14%) | (84.85%, 0.00%)
100 us | ( 0.03%, 87.18%) | (87.61%, 0.02%)
120 us | ( 0.02%, 89.21%) | (14.71%, 74.40%)
500 us | ( 0.00%, 97.27%) | ( 3.70%, 93.53%
1000 us | ( 0.00%, 98.57%) | ( 0.17%, 98.40%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Gautham R. Shenoy (2):
cpuidle/pseries: Fixup CEDE0 latency only for POWER10 onwards
cpuidle/pseries: Do not cap the CEDE0 latency in fixup_cede0_latency()
drivers/cpuidle/cpuidle-pseries.c | 75 +++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 30 deletions(-)
--
1.9.4
^ permalink raw reply
* Re: [PATCH 0/1] PPC32: fix ptrace() access to FPU registers
From: Radu Rendec @ 2021-07-18 18:07 UTC (permalink / raw)
To: Christophe Leroy, Daniel Axtens, Andreas Schwab
Cc: linuxppc-dev, Paul Mackerras, Oleg Nesterov
In-Reply-To: <20b6bdebae736b48814c1d600024546b7c604e3c.camel@gmail.com>
On Fri, 2021-06-11 at 10:37 -0400, Radu Rendec wrote:
>On Fri, 2021-06-11 at 08:02 +0200, Christophe Leroy wrote:
>>Le 19/06/2019 à 14:57, Radu Rendec a écrit :
>>> On Wed, 2019-06-19 at 10:36 +1000, Daniel Axtens wrote:
>>>> Andreas Schwab <
>>>> schwab@linux-m68k.org
>>>>> writes:
>>>>
>>>>> On Jun 18 2019, Radu Rendec <
>>>>> radu.rendec@gmail.com
>>>>>> wrote:
>>>>>
>>>>>> Since you already have a working setup, it would be nice if you could
>>>>>> add a printk to arch_ptrace() to print the address and confirm what I
>>>>>> believe happens (by reading the gdb source code).
>>>>>
>>>>> A ppc32 ptrace syscall goes through compat_arch_ptrace.
>>>
>>> Right. I completely overlooked that part.
>>>
>>>> Ah right, and that (in ptrace32.c) contains code that will work:
>>>>
>>>>
>>>> /*
>>>> * the user space code considers the floating point
>>>> * to be an array of unsigned int (32 bits) - the
>>>> * index passed in is based on this assumption.
>>>> */
>>>> tmp = ((unsigned int *)child->thread.fp_state.fpr)
>>>> [FPRINDEX(index)];
>>>>
>>>> FPRINDEX is defined above to deal with the various manipulations you
>>>> need to do.
>>>
>>> Correct. Basically it does the same that I did in my patch: it divides
>>> the index again by 2 (it's already divided by 4 in compat_arch_ptrace()
>>> so it ends up divided by 8), then takes the least significant bit and
>>> adds it to the index. I take bit 2 of the original address, which is the
>>> same thing (because in FPRHALF() the address is already divided by 4).
>>>
>>> So we have this in ptrace32.c:
>>>
>>> #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
>>> #define FPRHALF(i) (((i) - PT_FPR0) & 1)
>>> #define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
>>>
>>> index = (unsigned long) addr >> 2;
>>> (unsigned int *)child->thread.fp_state.fpr)[FPRINDEX(index)]
>>>
>>>
>>> And we have this in my patch:
>>>
>>> fpidx = (addr - PT_FPR0 * sizeof(long)) / 8;
>>> (void *)&child->thread.TS_FPR(fpidx) + (addr & 4)
>>>
>>>> Radu: I think we want to copy that working code back into ptrace.c.
>>>
>>> I'm not sure that would work. There's a subtle difference: the code in
>>> ptrace32.c is always compiled on a 64-bit kernel and the user space
>>> calling it is always 32-bit; on the other hand, the code in ptrace.c can
>>> be compiled on either a 64-bit kernel or a 32-bit kernel and the user
>>> space calling it always has the same "bitness" as the kernel.
>>>
>>> One difference is the size of the CPU registers. On 64-bit they are 8
>>> byte long and user space knows that and generates 8-byte aligned
>>> addresses. So you have to divide the address by 8 to calculate the CPU
>>> register index correctly, which compat_arch_ptrace() currently doesn't.
>>>
>>> Another difference is that on 64-bit `long` is 8 bytes, so user space
>>> can read a whole FPU register in a single ptrace call.
>>>
>>> Now that we are all aware of compat_arch_ptrace() (which handles the
>>> special case of a 32-bit process running on a 64-bit kernel) I would say
>>> the patch is correct and does the right thing for both 32-bit and 64-bit
>>> kernels and processes.
>>>
>>>> The challenge will be unpicking the awful mess of ifdefs in ptrace.c
>>>> and making it somewhat more comprehensible.
>>>
>>> I'm not sure what ifdefs you're thinking about. The only that are used
>>> inside arch_ptrace() are PT_FPR0, PT_FPSCR and TS_FPR, which seem to be
>>> correct.
>>>
>>> But perhaps it would be useful to change my patch and add a comment just
>>> before arch_ptrace() that explains how the math is done and that the
>>> code must work on both 32-bit and 64-bit, the user space address
>>> assumptions, etc.
>>>
>>> By the way, I'm not sure the code in compat_arch_ptrace() handles
>>> PT_FPSCR correctly. It might (just because fpscr is right next to fpr[]
>>> in memory - and that's a hack), but I can't figure out if it accesses
>>> the right half.
>>>
>>
>>Does the issue still exists ? If yes, the patch has to be rebased.
>
>Hard to say. I'm still using 4.9 (stable) on the systems that I created
>the patch for. I tried to rebase, and the patch no longer applies. It
>looks like there have been some changes around that area, notably your
>commit e009fa433542, so it could actually be fixed now.
>
>It's been exactly two years since I sent the patch and I don't remember
>all the details. I will have to go back and look. Also, running a recent
>kernel on my PPC32 systems is not an option because there are a bunch of
>custom patches that would have to be ported. I will try in a VM and get
>back to you, hopefully early next week.
I finally had time to test everything properly. I can now confirm that
the original problem no longer exists, so the patch doesn't need to be
rebased.
I tested all three variants: 32-bit program on 32-bit kernel, 32-bit
program on 64-bit kernel and 64-bit program on 64-bit kernel.
Best regards,
Radu
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Oliver O'Halloran @ 2021-07-18 16:13 UTC (permalink / raw)
To: Guenter Roeck
Cc: Linux Kernel Mailing List, Geert Uytterhoeven, Paul Mackerras,
linuxppc-dev
In-Reply-To: <20210717161438.GA3038659@roeck-us.net>
On Sun, Jul 18, 2021 at 2:14 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Sun, Jul 18, 2021 at 01:54:23AM +1000, Oliver O'Halloran wrote:
> > On Sat, Jul 17, 2021 at 8:12 AM Guenter Roeck <linux@roeck-us.net> wrote:
> > >
> > > This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> > > discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> > > static").
> > >
> > > Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> > > results in a variety of backtraces such as
> >
> > ...and actually using it appears to require both manually enabling it
> > in the qemu config and finding a random bios blob that is no longer
> > distributed by the manufacturer. Cool.
> >
> That is absolutely wrong. vof.bin provided by qemu in the linux root
> directory works just fine, plus chrp32_defconfig minus SMP.
It looks like I forgot to actually merge the current HEAD into my
local qemu branch which was a few weeks old. VOF support was merged on
the 13th so I didn't see it. My apologies.
Oliver
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Oliver O'Halloran @ 2021-07-18 16:09 UTC (permalink / raw)
To: Guenter Roeck
Cc: Linux Kernel Mailing List, Paul Mackerras, Geert Uytterhoeven,
linuxppc-dev
In-Reply-To: <20210717162359.GA3130272@roeck-us.net>
On Sun, Jul 18, 2021 at 2:24 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> On Sat, Jul 17, 2021 at 05:57:50PM +0200, Christophe Leroy wrote:
> > Guenter Roeck <linux@roeck-us.net> a écrit :
> >
> > > This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> > > discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> > > static").
> > >
> > > Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> > > results in a variety of backtraces such as
> > >
> > > Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
> > > ------------[ cut here ]------------
> > > Bug: Write fault blocked by KUAP!
> > > WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230
> > > do_page_fault+0x4f4/0x920
> > > CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
> > > NIP: c0021824 LR: c0021824 CTR: 00000000
> > > REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
> > > MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
> > >
> > > GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60 c1085c58
> > > 00000000
> > > GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000 00000000
> > > 00000004
> > > GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000 00000001
> > > 40b14000
> > > GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1 00000000
> > > c1085e60
> > > NIP [c0021824] do_page_fault+0x4f4/0x920
> > > LR [c0021824] do_page_fault+0x4f4/0x920
> > > Call Trace:
> > > [c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
> > > [c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
> > >
> > > and the system fails to boot. Bisect points to commit 407d418f2fd4
> > > ("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
> > > commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
> > > the problem.
> >
> > Isn't there more than that in the backtrace ? If there is a fault blocked by
> > Kuap, it means there is a fault. It should be visible in the traces.
> >
> > Should we fix the problem instead of reverting the commit that made the
> > problem visible ?
> >
>
> I do not think the patch reverted here made the problem visible. I am
> quite sure that it introduced it. AFAIS the problem is that the new code
> initializes and remaps PCI much later, after it is being used.
Right. The bug is that on 32bit platforms the PHB setup also maps one
of the PHB's IO space as "ISA IO space" as a side effect. There's a
handful of platforms (pegasos2 is one) which use an i8259 interrupt
controller and configuring that requires access to IO / ISA space. The
KUAP faults we're setting are because isa_io_base is still set to zero
so outb() and friends are accessing the zero page.
I don't think there's any real reason why we need to have PCI fully
set up to handle that situation. A few platforms already have early
fixup code which parses the DT directly rather than using the fields
of pci_controller (which are parsed from the DT anyway) and I'm pretty
sure we can do something similar.
> Also, the
> patch introducing the problem was never tested on real hardware (it even
> says so in the patch comments). That by itself seems to be quite
> problematic for such an invasive patch, and makes me wonder if some of
> the other PHB discovery related patches introduced similar problems.
The legacy platforms are maintained on a best-effort basis. Ellerman's
CI farm covers most of the powerpc CPU types, but there's no real way
to test the bulk of the platforms in the tree since most of the
hardware is currently in landfill.
> Anyway, I do not use or have that hardware. I was just playing with the
> latest version of qemu and ended up tracking down why its brand new
> pegasos2 emulation no longer boots with the latest Linux kernel.
> I personally don't care too much if ppc/chrp support is broken in the
> upstream kernel or not. Please take this patch as problem report,
> and feel free to do with it whatever you like, including ignoring it.
Problem reports are fine and appreciated. I'd be less cranky if you
included the kernel config you used in the initial report since I
wasted an hour of my saturday trying to replicate it with various
kernel configs that had SMP enabled since that's what the
chrp_defconfig uses.
Oliver
^ permalink raw reply
* [powerpc:merge] BUILD SUCCESS bcc9472087d0a15f82c79ecd4e1bc2c18b045a7a
From: kernel test robot @ 2021-07-18 6:03 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git merge
branch HEAD: bcc9472087d0a15f82c79ecd4e1bc2c18b045a7a Automatic merge of 'master' into merge (2021-07-15 20:45)
elapsed time: 3916m
configs tested: 170
configs skipped: 4
The following configs have been built successfully.
More configs may be tested in the coming days.
gcc tested configs:
arm defconfig
arm64 allyesconfig
arm64 defconfig
arm allyesconfig
arm allmodconfig
powerpc mpc885_ads_defconfig
powerpc ge_imp3a_defconfig
riscv allnoconfig
powerpc stx_gp3_defconfig
arm sunxi_defconfig
sh se7705_defconfig
arc axs101_defconfig
sh rts7751r2d1_defconfig
arm gemini_defconfig
powerpc asp8347_defconfig
riscv nommu_virt_defconfig
powerpc mpc832x_mds_defconfig
ia64 tiger_defconfig
m68k mac_defconfig
arm mps2_defconfig
m68k mvme16x_defconfig
x86_64 alldefconfig
mips mpc30x_defconfig
parisc generic-32bit_defconfig
x86_64 defconfig
arm pxa910_defconfig
xtensa cadence_csp_defconfig
sh se7722_defconfig
arc defconfig
powerpc mpc834x_itxgp_defconfig
mips loongson1c_defconfig
s390 alldefconfig
nios2 3c120_defconfig
arc vdk_hs38_defconfig
sh shmin_defconfig
powerpc canyonlands_defconfig
powerpc cell_defconfig
microblaze mmu_defconfig
powerpc amigaone_defconfig
arm pcm027_defconfig
csky alldefconfig
powerpc mpc83xx_defconfig
sh se7619_defconfig
powerpc ppc44x_defconfig
sh rsk7264_defconfig
arc axs103_smp_defconfig
powerpc mpc8560_ads_defconfig
powerpc wii_defconfig
arm versatile_defconfig
sh rsk7201_defconfig
arm imx_v4_v5_defconfig
sh landisk_defconfig
sh alldefconfig
arm mvebu_v7_defconfig
arm nhk8815_defconfig
arm tct_hammer_defconfig
arm sama5_defconfig
mips cu1000-neo_defconfig
h8300 defconfig
arm alldefconfig
arm vt8500_v6_v7_defconfig
arm shannon_defconfig
mips loongson2k_defconfig
m68k q40_defconfig
powerpc cm5200_defconfig
arm cns3420vb_defconfig
mips rb532_defconfig
powerpc mpc837x_mds_defconfig
parisc allyesconfig
sh ap325rxa_defconfig
powerpc pasemi_defconfig
mips allyesconfig
ia64 generic_defconfig
arm exynos_defconfig
sh magicpanelr2_defconfig
sh defconfig
arm lart_defconfig
powerpc klondike_defconfig
arm shmobile_defconfig
powerpc kmeter1_defconfig
nios2 defconfig
arm mainstone_defconfig
arm pleb_defconfig
sh se7712_defconfig
arm integrator_defconfig
ia64 allmodconfig
ia64 defconfig
ia64 allyesconfig
x86_64 allnoconfig
m68k allmodconfig
m68k defconfig
m68k allyesconfig
arc allyesconfig
nds32 allnoconfig
nds32 defconfig
nios2 allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
sh allmodconfig
parisc defconfig
s390 allyesconfig
s390 allmodconfig
s390 defconfig
i386 allyesconfig
sparc allyesconfig
sparc defconfig
i386 defconfig
mips allmodconfig
powerpc allyesconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a005-20210715
i386 randconfig-a006-20210715
i386 randconfig-a004-20210715
i386 randconfig-a001-20210715
i386 randconfig-a003-20210715
i386 randconfig-a002-20210715
i386 randconfig-a005-20210716
i386 randconfig-a006-20210716
i386 randconfig-a004-20210716
i386 randconfig-a001-20210716
i386 randconfig-a002-20210716
i386 randconfig-a003-20210716
x86_64 randconfig-a013-20210715
x86_64 randconfig-a012-20210715
x86_64 randconfig-a015-20210715
x86_64 randconfig-a014-20210715
x86_64 randconfig-a016-20210715
x86_64 randconfig-a011-20210715
i386 randconfig-a014-20210715
i386 randconfig-a015-20210715
i386 randconfig-a011-20210715
i386 randconfig-a013-20210715
i386 randconfig-a012-20210715
i386 randconfig-a016-20210715
i386 randconfig-a014-20210718
i386 randconfig-a015-20210718
i386 randconfig-a011-20210718
i386 randconfig-a013-20210718
i386 randconfig-a016-20210718
i386 randconfig-a012-20210718
x86_64 randconfig-a005-20210716
x86_64 randconfig-a004-20210716
x86_64 randconfig-a003-20210716
x86_64 randconfig-a002-20210716
x86_64 randconfig-a006-20210716
x86_64 randconfig-a001-20210716
riscv nommu_k210_defconfig
riscv allyesconfig
riscv defconfig
riscv rv32_defconfig
riscv allmodconfig
x86_64 rhel-8.3-kselftests
um x86_64_defconfig
um i386_defconfig
x86_64 allyesconfig
x86_64 rhel-8.3
x86_64 rhel-8.3-kbuiltin
x86_64 kexec
clang tested configs:
x86_64 randconfig-b001-20210716
x86_64 randconfig-b001-20210715
x86_64 randconfig-a005-20210715
x86_64 randconfig-a004-20210715
x86_64 randconfig-a002-20210715
x86_64 randconfig-a003-20210715
x86_64 randconfig-a006-20210715
x86_64 randconfig-a001-20210715
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* Re: [PATCH v3 1/2] net/ps3_gelic: Add gelic_descr structures
From: Geoff Levand @ 2021-07-17 22:36 UTC (permalink / raw)
To: Christophe Leroy; +Cc: netdev, linuxppc-dev, David S. Miller, Jakub Kicinski
In-Reply-To: <20210711160330.Horde.YmbaUrNaGLYM4ADZvVr_gA1@messagerie.c-s.fr>
Hi Christophe,
On 7/11/21 7:03 AM, Christophe Leroy wrote:
>
> Your patch has a lot of cosmetic changes. Several of them are just wrong. The other ones belong to another patch. This patch should focus only on the changes it targets.
>
> Your patch is way too big and addresses several different topics. Should be split in several patches.
>
> I suggest you run checkpatch.pl --strict on your patch
>
Thanks for the review. I'll create a follow up patch set with
your comments in mind.
-Geoff
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Guenter Roeck @ 2021-07-17 16:23 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-kernel, Geert Uytterhoeven, Paul Mackerras,
Oliver O'Halloran, linuxppc-dev
In-Reply-To: <20210717175750.Horde.TLZWyADKWFGAyFWIYtmglA2@messagerie.c-s.fr>
On Sat, Jul 17, 2021 at 05:57:50PM +0200, Christophe Leroy wrote:
> Guenter Roeck <linux@roeck-us.net> a écrit :
>
> > This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> > discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> > static").
> >
> > Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> > results in a variety of backtraces such as
> >
> > Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
> > ------------[ cut here ]------------
> > Bug: Write fault blocked by KUAP!
> > WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230
> > do_page_fault+0x4f4/0x920
> > CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
> > NIP: c0021824 LR: c0021824 CTR: 00000000
> > REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
> > MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
> >
> > GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60 c1085c58
> > 00000000
> > GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000 00000000
> > 00000004
> > GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000 00000001
> > 40b14000
> > GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1 00000000
> > c1085e60
> > NIP [c0021824] do_page_fault+0x4f4/0x920
> > LR [c0021824] do_page_fault+0x4f4/0x920
> > Call Trace:
> > [c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
> > [c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
> >
> > and the system fails to boot. Bisect points to commit 407d418f2fd4
> > ("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
> > commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
> > the problem.
>
> Isn't there more than that in the backtrace ? If there is a fault blocked by
> Kuap, it means there is a fault. It should be visible in the traces.
>
> Should we fix the problem instead of reverting the commit that made the
> problem visible ?
>
I do not think the patch reverted here made the problem visible. I am
quite sure that it introduced it. AFAIS the problem is that the new code
initializes and remaps PCI much later, after it is being used. Also, the
patch introducing the problem was never tested on real hardware (it even
says so in the patch comments). That by itself seems to be quite
problematic for such an invasive patch, and makes me wonder if some of
the other PHB discovery related patches introduced similar problems.
Anyway, I do not use or have that hardware. I was just playing with the
latest version of qemu and ended up tracking down why its brand new
pegasos2 emulation no longer boots with the latest Linux kernel.
I personally don't care too much if ppc/chrp support is broken in the
upstream kernel or not. Please take this patch as problem report,
and feel free to do with it whatever you like, including ignoring it.
For completeness, please see a complete log below.
Thanks,
Guenter
---
Total memory = 512MB; using 1024kB for hash table
Activating Kernel Userspace Execution Prevention
Activating Kernel Userspace Access Protection
Linux version 5.14.0-rc1-00353-gd980cc0620ae (groeck@server.roeck-us.net) (powerpc64-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34) #3 Sat Jul 17 09:20:08 PDT 2021
Using CHRP machine description
-----------------------------------------------------
phys_mem_size = 0x20000000
dcache_bsize = 0x20
icache_bsize = 0x20
cpu_features = 0x000000000401a00a
possible = 0x00000000277de14a
always = 0x0000000000000000
cpu_user_features = 0x9c000001 0x00000000
mmu_features = 0x00000001
Hash_size = 0x100000
Hash_mask = 0x3fff
-----------------------------------------------------
chrp type = 6 [Genesi Pegasos]
Pegasos l2cr : L2 cache was not active, activating
Zone ranges:
DMA [mem 0x0000000000000000-0x000000001fffffff]
Normal empty
HighMem empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000000000000-0x000000001fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000001fffffff]
Built 1 zonelists, mobility grouping on. Total pages: 130048
Kernel command line: console=ttyS0 root=/dev/sda noreboot
Unknown command line parameters: noreboot
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Kernel virtual memory layout:
* 0xffbcf000..0xfffff000 : fixmap
* 0xff400000..0xff800000 : highmem PTEs
* 0xe1000000..0xff400000 : vmalloc & ioremap
* 0xb0000000..0xc0000000 : modules
Memory: 497660K/524288K available (11600K kernel code, 1328K rwdata, 2288K rodata, 1252K init, 346K bss, 26628K reserved, 0K cma-reserved, 0K highmem)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16
Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Not tainted (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a1 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x48/0x274
NIP: c002e3f8 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Not tainted (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a1 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000003 000000a1 000000ff 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e3f8] i8259_init+0x48/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
random: get_random_bytes called from print_oops_end_marker+0x34/0x6c with crng_init=0
---[ end trace 0000000000000000 ]---
Kernel attempted to write user page (21) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000021 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x5c/0x274
NIP: c002e40c LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000021 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000003 00000021 000000ff 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e40c] i8259_init+0x5c/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887f6 ]---
Kernel attempted to write user page (20) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000020 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x74/0x274
NIP: c002e424 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000020 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000011 00000020 000000ff 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e424] i8259_init+0x74/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887f7 ]---
Kernel attempted to write user page (21) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000021 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x8c/0x274
NIP: c002e43c LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000021 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000011 00000021 00000000 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e43c] i8259_init+0x8c/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887f8 ]---
Kernel attempted to write user page (21) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000021 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0xa4/0x274
NIP: c002e454 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000021 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000011 00000021 00000004 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e454] i8259_init+0xa4/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887f9 ]---
Kernel attempted to write user page (21) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000021 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0xbc/0x274
NIP: c002e46c LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000021 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000011 00000021 00000001 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e46c] i8259_init+0xbc/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887fa ]---
Kernel attempted to write user page (a0) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a0 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0xd0/0x274
NIP: c002e480 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a0 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000011 000000a0 00000001 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e480] i8259_init+0xd0/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887fb ]---
Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a1 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0xe8/0x274
NIP: c002e498 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a1 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000008 000000a1 00000001 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e498] i8259_init+0xe8/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887fc ]---
Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a1 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x100/0x274
NIP: c002e4b0 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a1 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000002 000000a1 00000001 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e4b0] i8259_init+0x100/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887fd ]---
Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a1 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x114/0x274
NIP: c002e4c4 LR: c0da001c CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a1 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00000000 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000002 000000a1 00000001 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e4c4] i8259_init+0x114/0x274
LR [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887fe ]---
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000020 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x134/0x274
NIP: c002e4e4 LR: c002e4d4 CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000020 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00002710 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000002 00000020 0000000b 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e4e4] i8259_init+0x134/0x274
LR [c002e4d4] i8259_init+0x124/0x274
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a02887ff ]---
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a0 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x148/0x274
NIP: c002e4f8 LR: c002e4d4 CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a0 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00002710 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 00000002 000000a0 0000000b 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 dfffc6e0 c1010000
NIP [c002e4f8] i8259_init+0x148/0x274
LR [c002e4d4] i8259_init+0x124/0x274
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a0288800 ]---
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 000000a1 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x174/0x274
NIP: c002e524 LR: c002e4d4 CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 000000a1 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00002710 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 000000ff 000000a1 000000fb 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 c0ecc8b8 c1010000
NIP [c002e524] i8259_init+0x174/0x274
LR [c002e4d4] i8259_init+0x124/0x274
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a0288801 ]---
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:228 do_page_fault+0x914/0x9e0
CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0022c54 LR: c0022c54 CTR: 00000000
REGS: c0ff9d40 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00021032 <ME,IR,DR,RI> CR: 24f42244 XER: 00000000
GPR00: c0022c54 c0ff9e00 c0ec9520 00000021 3fffefff c0ff9c50 c0ff9c48 00000000
GPR08: 00001032 00000000 00000000 c0f3846c 44f42244 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 00000300 02000000 00000000 00000021 00000000 42000000 c0ff9e50
NIP [c0022c54] do_page_fault+0x914/0x9e0
LR [c0022c54] do_page_fault+0x914/0x9e0
Call Trace:
[c0ff9e00] [c0022c54] do_page_fault+0x914/0x9e0 (unreliable)
[c0ff9e40] [c0004254] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at i8259_init+0x18c/0x274
NIP: c002e53c LR: c002e4d4 CTR: 00000000
REGS: c0ff9e50 TRAP: 0300 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00001032 <ME,IR,DR,RI> CR: 24000422 XER: 00000000
DAR: 00000021 DSISR: 42000000
GPR00: c0da001c c0ff9f10 c0ec9520 00002710 f1000cb4 00000000 00000000 c0ff9ef8
GPR08: 000000ff 00000021 000000fb 00000100 84000422 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 017e2b7c 00a8bf40 c0ec9014 c0d66c20
GPR24: 00000000 dfffb0a9 dfffb0a0 00001032 00000000 f1000cb4 c0ecc8b8 c1010000
NIP [c002e53c] i8259_init+0x18c/0x274
LR [c002e4d4] i8259_init+0x124/0x274
--- interrupt: 300
[c0ff9f10] [c081de84] of_bus_n_addr_cells+0x5c/0xb8 (unreliable)
[c0ff9f40] [c0da001c] chrp_init_IRQ+0x2ec/0x3e0
[c0ff9fa0] [c0d936d8] start_kernel+0x4dc/0x688
[c0ff9ff0] [00003540] 0x3540
Instruction dump:
48b17b4d 2c030000 408200bc 807f0080 48047519 2c030000 41a2fde4 3c80c0cd
3c60c0cd 3884bb78 3863bb80 480249a1 <0fe00000> 80010044 3860000b 7c0803a6
---[ end trace 523b05d3a0288802 ]---
i8259 legacy interrupt controller initialized
Persistent clock returned invalid value
clocksource: timebase: mask: 0xffffffffffffffff max_cycles: 0x7b00c4bad, max_idle_ns: 440795202744 ns
clocksource: timebase mult[1e000005] shift[24] registered
Console: colour dummy device 80x25
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
devtmpfs: initialized
PCI bus 0
controlled by /pci@80000000
at 80000000
PCI host bridge /pci@80000000 (primary) ranges:
IO 0x00000000fe000000..0x00000000fe00ffff -> 0x0000000000000000
MEM 0x0000000080000000..0x00000000bfffffff -> 0x0000000080000000
PCI bus 0
controlled by /pci@c0000000
at c0000000
PCI host bridge /pci@c0000000 ranges:
IO 0x00000000f8000000..0x00000000f800ffff -> 0x0000000000000000
MEM 0x00000000c0000000..0x00000000dfffffff -> 0x00000000c0000000
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1 at mm/memblock.c:1450 memblock_alloc_internal+0x34/0x108
CPU: 0 PID: 1 Comm: swapper Tainted: G W 5.14.0-rc1-00353-gd980cc0620ae #3
NIP: c0dab064 LR: c0dab05c CTR: 00000005
REGS: e100dc60 TRAP: 0700 Tainted: G W (5.14.0-rc1-00353-gd980cc0620ae)
MSR: 00029032 <EE,ME,IR,DR,RI> CR: 44042222 XER: 00000000
GPR00: c0dab3c8 e100dd20 c14c0000 00000001 00000020 00000000 00000000 ffffffff
GPR08: 00000000 ffffffff dfffb3ec c0f3846c 84042228 00000000 c0007730 c0cce9bc
GPR16: c0ecd7f4 c0cc7584 c0cfd728 c0ccb3e8 c0cce9e4 c0ccea28 c0cc74bc c0ce4a20
GPR24: dfffb3ec 00000000 00000000 ffffffff 00000000 00000020 00000130 00000000
NIP [c0dab064] memblock_alloc_internal+0x34/0x108
LR [c0dab05c] memblock_alloc_internal+0x2c/0x108
Call Trace:
[e100dd20] [c081e0a0] of_find_property+0x20/0x38 (unreliable)
[e100dd50] [c0dab3c8] memblock_alloc_try_nid+0x8c/0xc0
[e100dd80] [c0d98d68] pci_create_OF_bus_map+0x28/0xc4
[e100dda0] [c0da0ea0] chrp_find_bridges+0x5c8/0x640
[e100de50] [c0d98e28] discover_phbs+0x24/0x40
[e100de60] [c0d93900] do_one_initcall+0x7c/0x198
[e100ded0] [c0d93c78] kernel_init_freeable+0x1e0/0x290
[e100df10] [c0007758] kernel_init+0x28/0x120
[e100df30] [c001d148] ret_from_kernel_thread+0x14/0x1c
Instruction dump:
7c0802a6 bf210014 7c7e1b78 90010034 7c9d2378 7cbf2b78 7cd93378 7cfb3b78
7d1a4378 4b3ad415 2c030000 41a2003c <0fe00000> 80010034 7fc3f378 83210014
---[ end trace 523b05d3a0288803 ]---
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
futex hash table entries: 256 (order: -1, 3072 bytes, linear)
NET: Registered PF_NETLINK/PF_ROUTE protocol family
PCI: Probing PCI hardware
PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
pci_bus 0000:00: root bus resource [mem 0x80000000-0xbfffffff]
pci_bus 0000:00: root bus resource [bus 00-ff]
pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to ff
pci 0000:00:00.0: [11ab:6460] type 00 class 0x060000
pci 0000:00:01.0: [1234:1111] type 00 class 0x030000
pci 0000:00:01.0: reg 0x10: [mem 0x00000000-0x00ffffff pref]
pci 0000:00:01.0: reg 0x18: [mem 0x00000000-0x00000fff]
pci 0000:00:01.0: reg 0x30: [mem 0x00000000-0x0000ffff pref]
pci 0000:00:0c.0: [1106:8231] type 00 class 0x060100
pci 0000:00:0c.1: [1106:0571] type 00 class 0x01018f
pci 0000:00:0c.1: reg 0x10: [io 0x0000-0x0007]
pci 0000:00:0c.1: reg 0x14: [io 0x0000-0x0003]
pci 0000:00:0c.1: reg 0x18: [io 0x0000-0x0007]
pci 0000:00:0c.1: reg 0x1c: [io 0x0000-0x0003]
pci 0000:00:0c.1: reg 0x20: [io 0x0000-0x000f]
pci 0000:00:0c.2: [1106:3038] type 00 class 0x0c0300
pci 0000:00:0c.2: reg 0x20: [io 0x0000-0x001f]
pci 0000:00:0c.3: [1106:3038] type 00 class 0x0c0300
pci 0000:00:0c.3: reg 0x20: [io 0x0000-0x001f]
pci 0000:00:0c.4: [1106:8235] type 00 class 0x068000
pci 0000:00:0c.5: [1106:3058] type 00 class 0x040100
pci 0000:00:0c.6: [1106:3068] type 00 class 0x078000
pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 00
pci 0000:00:0c.1: of_irq_parse_pci: failed with rc=-22
pci 0000:00:0c.2: of_irq_parse_pci: failed with rc=-22
pci 0000:00:0c.3: of_irq_parse_pci: failed with rc=-22
pci 0000:00:0c.5: of_irq_parse_pci: failed with rc=-22
pci 0000:00:0c.6: of_irq_parse_pci: failed with rc=-22
PCI host bridge to bus 0001:01
pci_bus 0001:01: root bus resource [io 0x20000-0x2ffff] (bus address [0x0000-0xffff])
pci_bus 0001:01: root bus resource [mem 0xc0000000-0xdfffffff]
pci_bus 0001:01: root bus resource [bus 01-ff]
pci_bus 0001:01: busn_res: [bus 01-ff] end is updated to ff
pci 0001:01:00.0: [11ab:6460] type 00 class 0x060000
pci_bus 0001:01: busn_res: [bus 01-ff] end is updated to 01
pci 0000:00:01.0: BAR 0: assigned [mem 0x80000000-0x80ffffff pref]
pci 0000:00:01.0: BAR 6: assigned [mem 0x81000000-0x8100ffff pref]
pci 0000:00:01.0: BAR 2: assigned [mem 0x81010000-0x81010fff]
pci 0000:00:0c.2: BAR 4: assigned [io 0x1000-0x101f]
pci 0000:00:0c.3: BAR 4: assigned [io 0x1020-0x103f]
pci 0000:00:0c.1: BAR 4: assigned [io 0x1040-0x104f]
pci 0000:00:0c.1: BAR 0: assigned [io 0x1050-0x1057]
pci 0000:00:0c.1: BAR 2: assigned [io 0x1058-0x105f]
pci 0000:00:0c.1: BAR 1: assigned [io 0x1060-0x1063]
pci 0000:00:0c.1: BAR 3: assigned [io 0x1064-0x1067]
pci_bus 0000:00: resource 4 [io 0x0000-0xffff]
pci_bus 0000:00: resource 5 [mem 0x80000000-0xbfffffff]
pci_bus 0001:01: resource 4 [io 0x20000-0x2ffff]
pci_bus 0001:01: resource 5 [mem 0xc0000000-0xdfffffff]
pci 0000:00:01.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
pci 0000:00:01.0: vgaarb: bridge control possible
pci 0000:00:01.0: vgaarb: setting as boot device (VGA legacy resources not available)
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Advanced Linux Sound Architecture Driver Initialized.
clocksource: Switched to clocksource timebase
NET: Registered PF_INET protocol family
IP idents hash table entries: 8192 (order: 4, 65536 bytes, linear)
tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
TCP established hash table entries: 4096 (order: 2, 16384 bytes, linear)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes, linear)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 256 (order: 0, 4096 bytes, linear)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear)
NET: Registered PF_UNIX/PF_LOCAL protocol family
pci 0000:00:0c.1: Fixing VIA IDE, force legacy mode on
pci 0000:00:0c.2: enabling device (0000 -> 0001)
pci 0000:00:0c.3: enabling device (0000 -> 0001)
PCI: CLS 0 bytes, default 32
Thermal assist unit using workqueue, shrink_timer: 2000 ms
workingset: timestamp_bits=30 max_order=17 bucket_order=0
efs: 1.0a - http://aeschi.ch.eu.org/efs/
QNX4 filesystem 0.2.3 registered.
befs: version: 0.9.3
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
io scheduler mq-deadline registered
io scheduler kyber registered
IPMI message handler: version 39.2
ipmi device interface
ipmi_si: IPMI System Interface driver
ipmi_si: Unable to find any System Interface(s)
IPMI Watchdog: driver initialized
IPMI poweroff: Copyright (C) 2004 MontaVista Software - IPMI Powerdown via sys_reboot
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
printk: console [ttyS0] disabled
serial8250.0: ttyS0 at I/O 0x2f8 (irq = 0, base_baud = 115200) is a 16550A
printk: console [ttyS0] enabled
pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)
Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $
ac.o: No PCI boards found.
ac.o: For an ISA board you must supply memory and irq parameters.
Linux agpgart interface v0.103
SyncLink PC Card driver $Revision: 4.34 $, tty major#249
[drm] radeon kernel modesetting enabled.
Floppy drive(s): fd0 is 2.88M
loop: module loaded
apm_emu: PMU APM Emulation initialized.
Warning: no ADB interface detected
scsi host0: pata_via
scsi host1: pata_via
ata1: PATA max UDMA/100 cmd 0x1050 ctl 0x1060 bmdma 0x1040 irq 14
ata2: PATA max UDMA/100 cmd 0x1058 ctl 0x1064 bmdma 0x1048 irq 15
e1000: Intel(R) PRO/1000 Network Driver
e1000: Copyright (c) 1999-2006 Intel Corporation.
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-pci: OHCI PCI platform driver
uhci_hcd: USB Universal Host Controller Interface driver
uhci_hcd 0000:00:0c.2: UHCI Host Controller
uhci_hcd 0000:00:0c.2: new USB bus registered, assigned bus number 1
uhci_hcd 0000:00:0c.2: irq 9, io base 0x00001000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
uhci_hcd 0000:00:0c.3: UHCI Host Controller
uhci_hcd 0000:00:0c.3: new USB bus registered, assigned bus number 2
uhci_hcd 0000:00:0c.3: irq 9, io base 0x00001020
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
usbcore: registered new interface driver usblp
usbcore: registered new interface driver mdc800
mdc800: v0.7.5 (30/10/2000):USB Driver for Mustek MDC800 Digital Camera
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver cytherm
usbcore: registered new interface driver idmouse
usbcore: registered new interface driver usblcd
usbcore: registered new interface driver legousbtower
usbcore: registered new interface driver usbtest
usbcore: registered new interface driver sisusb
ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
ata1.00: 32768 sectors, multi 16: LBA48
usb 2-1: new full-speed USB device number 2 using uhci_hcd
serio: i8042 KBD port at 0x60,0x64 irq 1
mousedev: PS/2 mouse device common for all mice
usbcore: registered new interface driver iforce
input: ICS MicroClock MK712 TouchScreen as /devices/virtual/input/input0
rtc-generic rtc-generic: registered as rtc0
rtc-generic rtc-generic: hctosys: unable to read the hardware clock
i2c /dev entries driver
vt596_smbus 0000:00:0c.4: SMBUS: Error: Host SMBus controller not enabled! - upgrade BIOS or use force=1
Driver for 1-wire Dallas network protocol.
usbcore: registered new interface driver pcwd_usb
softdog: initialized. soft_noboot=0 soft_margin=60 sec soft_panic=0 (nowayout=0)
softdog: soft_reboot_cmd=<not set> soft_active_on_boot=0
wbsd: Winbond W83L51xD SD/MMC card interface driver
wbsd: Copyright(c) Pierre Ossman
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
snd_via82xx 0000:00:0c.5: codec_read: codec 0 is not valid [0x0]
snd_via82xx 0000:00:0c.5: codec_read: codec 0 is not valid [0x0]
atkbd serio0: keyboard reset failed on isa0060/serio0
snd_via82xx 0000:00:0c.5: codec_read: codec 0 is not valid [0x0]
snd_via82xx 0000:00:0c.5: codec_read: codec 0 is not valid [0x0]
snd_via82xx 0000:00:0c.5: AC'97 0 access is not valid [0xffffffff], removing mixer.
snd_via82xx: probe of 0000:00:0c.5 failed with error -5
floppy0: no floppy controllers found
work still pending
scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 32768 512-byte logical blocks: (16.8 MB/16.0 MiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
snd_via82xx_modem 0000:00:0c.6: codec_read: codec 0 is not valid [0x0]
snd_via82xx_modem 0000:00:0c.6: codec_read: codec 0 is not valid [0x0]
ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
snd_via82xx_modem 0000:00:0c.6: codec_read: codec 0 is not valid [0x0]
snd_via82xx_modem 0000:00:0c.6: codec_read: codec 0 is not valid [0x0]
snd_via82xx_modem 0000:00:0c.6: AC'97 0 access is not valid [0xffffffff], removing mixer.
snd_via82xx_modem: probe of 0000:00:0c.6 failed with error -5
usbcore: registered new interface driver snd-usb-audio
usbcore: registered new interface driver snd-usb-usx2y
NET: Registered PF_INET6 protocol family
Segment Routing with IPv6
sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
NET: Registered PF_PACKET protocol family
drmem: No dynamic reconfiguration memory found
ALSA device list:
No soundcards found.
ata2.00: qc timeout (cmd 0xa0)
ata2.00: TEST_UNIT_READY failed (err_mask=0x5)
ata2.00: qc timeout (cmd 0xa0)
ata2.00: TEST_UNIT_READY failed (err_mask=0x5)
ata2.00: limiting speed to UDMA/100:PIO3
ata2.00: qc timeout (cmd 0xa0)
ata2.00: TEST_UNIT_READY failed (err_mask=0x5)
ata2.00: disabled
ata1: lost interrupt (Status 0x50)
ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
ata1.00: failed command: READ DMA
ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0 dma 4096 in
res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout)
ata1.00: status: { DRDY }
ata1: soft resetting link
ata1.00: configured for UDMA/100
ata1.00: device reported invalid CHS sector 0
ata1: EH complete
ata1: lost interrupt (Status 0x50)
ata1.00: limiting speed to UDMA/66:PIO4
ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
ata1.00: failed command: READ DMA
ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0 dma 4096 in
res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout)
ata1.00: status: { DRDY }
ata1: soft resetting link
ata1.00: configured for UDMA/66
ata1.00: device reported invalid CHS sector 0
ata1: EH complete
...
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Guenter Roeck @ 2021-07-17 16:14 UTC (permalink / raw)
To: Oliver O'Halloran
Cc: Linux Kernel Mailing List, Geert Uytterhoeven, Paul Mackerras,
linuxppc-dev
In-Reply-To: <CAOSf1CHuLhYO1rXiAhPz6xyQ-GgrjE-dj=Af6v7CWSH6QroEtQ@mail.gmail.com>
On Sun, Jul 18, 2021 at 01:54:23AM +1000, Oliver O'Halloran wrote:
> On Sat, Jul 17, 2021 at 8:12 AM Guenter Roeck <linux@roeck-us.net> wrote:
> >
> > This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> > discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> > static").
> >
> > Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> > results in a variety of backtraces such as
>
> ...and actually using it appears to require both manually enabling it
> in the qemu config and finding a random bios blob that is no longer
> distributed by the manufacturer. Cool.
>
That is absolutely wrong. vof.bin provided by qemu in the linux root
directory works just fine, plus chrp32_defconfig minus SMP.
Guenter
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Christophe Leroy @ 2021-07-17 16:01 UTC (permalink / raw)
To: Guenter Roeck
Cc: Oliver O'Halloran, linuxppc-dev, linux-kernel, Paul Mackerras,
Geert Uytterhoeven
In-Reply-To: <20210717175750.Horde.TLZWyADKWFGAyFWIYtmglA2@messagerie.c-s.fr>
Christophe Leroy <christophe.leroy@csgroup.eu> a écrit :
> Guenter Roeck <linux@roeck-us.net> a écrit :
>
>> This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
>> discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
>> static").
>>
>> Running the upstream kernel on Qemu's brand new "pegasos2" emulation
>> results in a variety of backtraces such as
>>
>> Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
>> ------------[ cut here ]------------
>> Bug: Write fault blocked by KUAP!
>> WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230
>> do_page_fault+0x4f4/0x920
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
>> NIP: c0021824 LR: c0021824 CTR: 00000000
>> REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
>> MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
>>
>> GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60
>> c1085c58 00000000
>> GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000
>> 00000000 00000004
>> GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000
>> 00000001 40b14000
>> GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1
>> 00000000 c1085e60
>> NIP [c0021824] do_page_fault+0x4f4/0x920
>> LR [c0021824] do_page_fault+0x4f4/0x920
>> Call Trace:
>> [c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
>> [c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
>>
>> and the system fails to boot. Bisect points to commit 407d418f2fd4
>> ("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
>> commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
>> the problem.
>
> Isn't there more than that in the backtrace ? If there is a fault
> blocked by Kuap, it means there is a fault. It should be visible in
> the traces.
>
> Should we fix the problem instead of reverting the commit that made
> the problem visible ?
>
Also, as it is a KUAP fault, did you test without CONFIG_PPC_KUAP ?
Does it boot ?
>
>>
>> Cc: Oliver O'Halloran <oohall@gmail.com>
>> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
>> Fixes: 407d418f2fd4 ("powerpc/chrp: Move PHB discovery")
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> ---
>> arch/powerpc/include/asm/hydra.h | 2 ++
>> arch/powerpc/platforms/chrp/pci.c | 11 ++---------
>> arch/powerpc/platforms/chrp/setup.c | 12 +++++++++++-
>> 3 files changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/hydra.h
>> b/arch/powerpc/include/asm/hydra.h
>> index d024447283a0..ae02eb53d6ef 100644
>> --- a/arch/powerpc/include/asm/hydra.h
>> +++ b/arch/powerpc/include/asm/hydra.h
>> @@ -94,6 +94,8 @@ extern volatile struct Hydra __iomem *Hydra;
>> #define HYDRA_INT_EXT7 18 /* Power Off Request */
>> #define HYDRA_INT_SPARE 19
>>
>> +extern int hydra_init(void);
>> +
>> #endif /* __KERNEL__ */
>>
>> #endif /* _ASMPPC_HYDRA_H */
>> diff --git a/arch/powerpc/platforms/chrp/pci.c
>> b/arch/powerpc/platforms/chrp/pci.c
>> index 76e6256cb0a7..b2c2bf35b76c 100644
>> --- a/arch/powerpc/platforms/chrp/pci.c
>> +++ b/arch/powerpc/platforms/chrp/pci.c
>> @@ -131,7 +131,8 @@ static struct pci_ops rtas_pci_ops =
>>
>> volatile struct Hydra __iomem *Hydra = NULL;
>>
>> -static int __init hydra_init(void)
>> +int __init
>> +hydra_init(void)
>> {
>> struct device_node *np;
>> struct resource r;
>> @@ -313,14 +314,6 @@ chrp_find_bridges(void)
>> }
>> }
>> of_node_put(root);
>> -
>> - /*
>> - * "Temporary" fixes for PCI devices.
>> - * -- Geert
>> - */
>> - hydra_init(); /* Mac I/O */
>> -
>> - pci_create_OF_bus_map();
>> }
>>
>> /* SL82C105 IDE Control/Status Register */
>> diff --git a/arch/powerpc/platforms/chrp/setup.c
>> b/arch/powerpc/platforms/chrp/setup.c
>> index 3cfc382841e5..c45435aa5e36 100644
>> --- a/arch/powerpc/platforms/chrp/setup.c
>> +++ b/arch/powerpc/platforms/chrp/setup.c
>> @@ -334,11 +334,22 @@ static void __init chrp_setup_arch(void)
>> /* On pegasos, enable the L2 cache if not already done by OF */
>> pegasos_set_l2cr();
>>
>> + /* Lookup PCI host bridges */
>> + chrp_find_bridges();
>> +
>> + /*
>> + * Temporary fixes for PCI devices.
>> + * -- Geert
>> + */
>> + hydra_init(); /* Mac I/O */
>> +
>> /*
>> * Fix the Super I/O configuration
>> */
>> sio_init();
>>
>> + pci_create_OF_bus_map();
>> +
>> /*
>> * Print the banner, then scroll down so boot progress
>> * can be printed. -- Cort
>> @@ -571,7 +582,6 @@ define_machine(chrp) {
>> .name = "CHRP",
>> .probe = chrp_probe,
>> .setup_arch = chrp_setup_arch,
>> - .discover_phbs = chrp_find_bridges,
>> .init = chrp_init2,
>> .show_cpuinfo = chrp_show_cpuinfo,
>> .init_IRQ = chrp_init_IRQ,
>> --
>> 2.25.1
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Oliver O'Halloran @ 2021-07-17 15:54 UTC (permalink / raw)
To: Guenter Roeck
Cc: Linux Kernel Mailing List, Geert Uytterhoeven, Paul Mackerras,
linuxppc-dev
In-Reply-To: <20210716221159.3587039-1-linux@roeck-us.net>
On Sat, Jul 17, 2021 at 8:12 AM Guenter Roeck <linux@roeck-us.net> wrote:
>
> This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> static").
>
> Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> results in a variety of backtraces such as
...and actually using it appears to require both manually enabling it
in the qemu config and finding a random bios blob that is no longer
distributed by the manufacturer. Cool.
> Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
> ------------[ cut here ]------------
> Bug: Write fault blocked by KUAP!
> WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230 do_page_fault+0x4f4/0x920
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
> NIP: c0021824 LR: c0021824 CTR: 00000000
> REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
> MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
>
> GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60 c1085c58 00000000
> GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000 00000000 00000004
> GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000 00000001 40b14000
> GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1 00000000 c1085e60
> NIP [c0021824] do_page_fault+0x4f4/0x920
> LR [c0021824] do_page_fault+0x4f4/0x920
> Call Trace:
> [c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
> [c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
>
> and the system fails to boot. Bisect points to commit 407d418f2fd4
> ("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
> commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
> the problem.
The rationale for adding ppc_md.discover_phbs() and shifting all the
platforms over to using it is in commit 5537fcb319d0 ("powerpc/pci:
Add ppc_md.discover_phbs()"). I'd rather not go back to having random
platforms doing their PCI init before the kernel has setup the page
allocator. You need to either debug the problem fully, or provide
enough replication details so that someone who isn't invested in
emulating ancient hardware (i.e. me) with enough information to
actually replicate the problem.
Oliver
^ permalink raw reply
* Re: [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Christophe Leroy @ 2021-07-17 15:57 UTC (permalink / raw)
To: Guenter Roeck
Cc: linux-kernel, Geert Uytterhoeven, Paul Mackerras,
Oliver O'Halloran, linuxppc-dev
In-Reply-To: <20210716221159.3587039-1-linux@roeck-us.net>
Guenter Roeck <linux@roeck-us.net> a écrit :
> This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
> discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
> static").
>
> Running the upstream kernel on Qemu's brand new "pegasos2" emulation
> results in a variety of backtraces such as
>
> Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
> ------------[ cut here ]------------
> Bug: Write fault blocked by KUAP!
> WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230
> do_page_fault+0x4f4/0x920
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
> NIP: c0021824 LR: c0021824 CTR: 00000000
> REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
> MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
>
> GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60
> c1085c58 00000000
> GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000
> 00000000 00000004
> GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000
> 00000001 40b14000
> GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1
> 00000000 c1085e60
> NIP [c0021824] do_page_fault+0x4f4/0x920
> LR [c0021824] do_page_fault+0x4f4/0x920
> Call Trace:
> [c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
> [c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
>
> and the system fails to boot. Bisect points to commit 407d418f2fd4
> ("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
> commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
> the problem.
Isn't there more than that in the backtrace ? If there is a fault
blocked by Kuap, it means there is a fault. It should be visible in
the traces.
Should we fix the problem instead of reverting the commit that made
the problem visible ?
>
> Cc: Oliver O'Halloran <oohall@gmail.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Fixes: 407d418f2fd4 ("powerpc/chrp: Move PHB discovery")
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> arch/powerpc/include/asm/hydra.h | 2 ++
> arch/powerpc/platforms/chrp/pci.c | 11 ++---------
> arch/powerpc/platforms/chrp/setup.c | 12 +++++++++++-
> 3 files changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/hydra.h
> b/arch/powerpc/include/asm/hydra.h
> index d024447283a0..ae02eb53d6ef 100644
> --- a/arch/powerpc/include/asm/hydra.h
> +++ b/arch/powerpc/include/asm/hydra.h
> @@ -94,6 +94,8 @@ extern volatile struct Hydra __iomem *Hydra;
> #define HYDRA_INT_EXT7 18 /* Power Off Request */
> #define HYDRA_INT_SPARE 19
>
> +extern int hydra_init(void);
> +
> #endif /* __KERNEL__ */
>
> #endif /* _ASMPPC_HYDRA_H */
> diff --git a/arch/powerpc/platforms/chrp/pci.c
> b/arch/powerpc/platforms/chrp/pci.c
> index 76e6256cb0a7..b2c2bf35b76c 100644
> --- a/arch/powerpc/platforms/chrp/pci.c
> +++ b/arch/powerpc/platforms/chrp/pci.c
> @@ -131,7 +131,8 @@ static struct pci_ops rtas_pci_ops =
>
> volatile struct Hydra __iomem *Hydra = NULL;
>
> -static int __init hydra_init(void)
> +int __init
> +hydra_init(void)
> {
> struct device_node *np;
> struct resource r;
> @@ -313,14 +314,6 @@ chrp_find_bridges(void)
> }
> }
> of_node_put(root);
> -
> - /*
> - * "Temporary" fixes for PCI devices.
> - * -- Geert
> - */
> - hydra_init(); /* Mac I/O */
> -
> - pci_create_OF_bus_map();
> }
>
> /* SL82C105 IDE Control/Status Register */
> diff --git a/arch/powerpc/platforms/chrp/setup.c
> b/arch/powerpc/platforms/chrp/setup.c
> index 3cfc382841e5..c45435aa5e36 100644
> --- a/arch/powerpc/platforms/chrp/setup.c
> +++ b/arch/powerpc/platforms/chrp/setup.c
> @@ -334,11 +334,22 @@ static void __init chrp_setup_arch(void)
> /* On pegasos, enable the L2 cache if not already done by OF */
> pegasos_set_l2cr();
>
> + /* Lookup PCI host bridges */
> + chrp_find_bridges();
> +
> + /*
> + * Temporary fixes for PCI devices.
> + * -- Geert
> + */
> + hydra_init(); /* Mac I/O */
> +
> /*
> * Fix the Super I/O configuration
> */
> sio_init();
>
> + pci_create_OF_bus_map();
> +
> /*
> * Print the banner, then scroll down so boot progress
> * can be printed. -- Cort
> @@ -571,7 +582,6 @@ define_machine(chrp) {
> .name = "CHRP",
> .probe = chrp_probe,
> .setup_arch = chrp_setup_arch,
> - .discover_phbs = chrp_find_bridges,
> .init = chrp_init2,
> .show_cpuinfo = chrp_show_cpuinfo,
> .init_IRQ = chrp_init_IRQ,
> --
> 2.25.1
^ permalink raw reply
* Re: [PATCH] ibmvfc: fix command state accounting and stale response detection
From: Christophe Leroy @ 2021-07-17 15:34 UTC (permalink / raw)
To: Tyrel Datwyler
Cc: linux-scsi, martin.petersen, linux-kernel, stable,
james.bottomley, brking, linuxppc-dev
In-Reply-To: <20210716205220.1101150-1-tyreld@linux.ibm.com>
Tyrel Datwyler <tyreld@linux.ibm.com> a écrit :
> Prior to commit 1f4a4a19508d ("scsi: ibmvfc: Complete commands outside
> the host/queue lock") responses to commands were completed sequentially
> with the host lock held such that a command had a basic binary state of
> active or free. It was therefore a simple affair of ensuring the
> assocaiated ibmvfc_event to a VIOS response was valid by testing that it
> was not already free. The lock relexation work to complete commands
> outside the lock inadverdently made it a trinary command state such that
> a command is either in flight, received and being completed, or
> completed and now free. This breaks the stale command detection logic as
> a command may be still marked active and been placed on the delayed
> completion list when a second stale response for the same command
> arrives. This can lead to double completions and list corruption. This
> issue was exposed by a recent VIOS regression were a missing memory
> barrier could occasionally result in the ibmvfc client receiveing a
> duplicate response for the same command.
>
> Fix the issue by introducing the atomic ibmvfc_event.active to track the
> trinary state of a command. The state is explicitly set to 1 when a
> command is successfully sent. The CRQ response handlers use
> atomic_dec_if_positive() to test for stale responses and correctly
> transition to the completion state when a active command is received.
> Finally, atomic_dec_and_test() is used to sanity check transistions
> when commands are freed as a result of a completion, or moved to the
> purge list as a result of error handling or adapter reset.
>
> Cc: stable@vger.kernel.org
> Fixes: 1f4a4a19508d ("scsi: ibmvfc: Complete commands outside the
> host/queue lock")
> Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
> ---
> drivers/scsi/ibmvscsi/ibmvfc.c | 19 +++++++++++++++++--
> drivers/scsi/ibmvscsi/ibmvfc.h | 1 +
> 2 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
> index bee1bec49c09..935b01ee44b7 100644
> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
> @@ -807,6 +807,13 @@ static int ibmvfc_init_event_pool(struct
> ibmvfc_host *vhost,
> for (i = 0; i < size; ++i) {
> struct ibmvfc_event *evt = &pool->events[i];
>
> + /*
> + * evt->active states
> + * 1 = in flight
> + * 0 = being completed
> + * -1 = free/freed
> + */
> + atomic_set(&evt->active, -1);
> atomic_set(&evt->free, 1);
> evt->crq.valid = 0x80;
> evt->crq.ioba = cpu_to_be64(pool->iu_token + (sizeof(*evt->xfer_iu) * i));
> @@ -1017,6 +1024,7 @@ static void ibmvfc_free_event(struct ibmvfc_event *evt)
>
> BUG_ON(!ibmvfc_valid_event(pool, evt));
> BUG_ON(atomic_inc_return(&evt->free) != 1);
> + BUG_ON(atomic_dec_and_test(&evt->active));
Avoid new BUG_ONs. See
https://www.kernel.org/doc/html/latest/process/deprecated.html
>
> spin_lock_irqsave(&evt->queue->l_lock, flags);
> list_add_tail(&evt->queue_list, &evt->queue->free);
> @@ -1072,6 +1080,12 @@ static void ibmvfc_complete_purge(struct
> list_head *purge_list)
> **/
> static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
> {
> + /*
> + * Anything we are failing should still be active. Otherwise, it
> + * implies we already got a response for the command and are doing
> + * something bad like double completing it.
> + */
> + BUG_ON(!atomic_dec_and_test(&evt->active));
Same
^ permalink raw reply
* Re: [PATCH v4 1/1] powerpc/pseries: Interface to represent PAPR firmware attributes
From: Pratik Sampat @ 2021-07-17 6:52 UTC (permalink / raw)
To: Fabiano Rosas, mpe, benh, paulus, linuxppc-dev, kvm-ppc,
linux-kernel, pratik.r.sampat
In-Reply-To: <87im1a2i5k.fsf@linux.ibm.com>
On 17/07/21 12:35 am, Fabiano Rosas wrote:
> "Pratik R. Sampat" <psampat@linux.ibm.com> writes:
>
>> +#include <linux/module.h>
>> +#include <linux/types.h>
>> +#include <linux/errno.h>
>> +#include <linux/init.h>
>> +#include <linux/seq_file.h>
>> +#include <linux/slab.h>
>> +#include <linux/uaccess.h>
>> +#include <linux/hugetlb.h>
>> +#include <asm/lppaca.h>
>> +#include <asm/hvcall.h>
>> +#include <asm/firmware.h>
>> +#include <asm/time.h>
>> +#include <asm/prom.h>
>> +#include <asm/vdso_datapage.h>
>> +#include <asm/vio.h>
>> +#include <asm/mmu.h>
>> +#include <asm/machdep.h>
>> +#include <asm/drmem.h>
> Do you need all of these headers? Sorry to mention just now, I seem to have
> dropped this comment from a previous review.
Ah yes, that was a TODO on my part I had missed as cleanups.
I'll verify if I do need all of them and get back to you.
>> +
>> +#include "pseries.h"
>> +
>> +/*
>> + * Flag attributes to fetch either all or one attribute from the HCALL
>> + * flag = BE(0) => fetch all attributes with firstAttributeId = 0
>> + * flag = BE(1) => fetch a single attribute with firstAttributeId = id
>> + */
>> +#define ESI_FLAGS_ALL 0
>> +#define ESI_FLAGS_SINGLE PPC_BIT(0)
>> +
>> +#define MAX_ATTRS 3
>> +
>> +struct papr_attr {
>> + u64 id;
>> + struct kobj_attribute kobj_attr;
>> +};
>> +struct papr_group {
>> + struct attribute_group pg;
>> + struct papr_attr pgattrs[MAX_ATTRS];
>> +} *pgs;
>> +
>> +/* /sys/firmware/papr */
>> +struct kobject *papr_kobj;
>> +/* /sys/firmware/papr/energy_scale_info */
>> +struct kobject *esi_kobj;
>> +
>> +/*
>> + * Extract and export the description of the energy scale attribute
>> + *
> Extra line here.
ack.
>> + */
>> +static ssize_t papr_show_desc(struct kobject *kobj,
>> + struct kobj_attribute *kobj_attr,
>> + char *buf)
>> +{
>> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
>> + kobj_attr);
>> + struct h_energy_scale_info_hdr *t_hdr;
>> + struct energy_scale_attribute *t_esi;
>> + char *t_buf;
>> + int ret = 0;
>> +
>> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
>> + if (t_buf == NULL)
>> + return -ENOMEM;
>> +
>> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
>> + pattr->id, virt_to_phys(t_buf),
>> + MAX_BUF_SZ);
>> +
>> + if (ret != H_SUCCESS) {
>> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
>> + goto out;
>> + }
>> +
>> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
>> + t_esi = (struct energy_scale_attribute *)
>> + (t_buf + be64_to_cpu(t_hdr->array_offset));
>> +
>> + ret = snprintf(buf, sizeof(t_esi->desc), "%s\n", t_esi->desc);
>> + if (ret < 0)
>> + ret = -EIO;
>> +out:
>> + kfree(t_buf);
>> +
>> + return ret;
>> +}
>> +
>> +/*
>> + * Extract and export the numeric value of the energy scale attributes
>> + */
>> +static ssize_t papr_show_value(struct kobject *kobj,
>> + struct kobj_attribute *kobj_attr,
>> + char *buf)
>> +{
>> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
>> + kobj_attr);
>> + struct h_energy_scale_info_hdr *t_hdr;
>> + struct energy_scale_attribute *t_esi;
>> + char *t_buf;
>> + int ret = 0;
>> +
>> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
>> + if (t_buf == NULL)
>> + return -ENOMEM;
>> +
>> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
>> + pattr->id, virt_to_phys(t_buf),
>> + MAX_BUF_SZ);
>> +
>> + if (ret != H_SUCCESS) {
>> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
>> + goto out;
>> + }
>> +
>> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
>> + t_esi = (struct energy_scale_attribute *)
>> + (t_buf + be64_to_cpu(t_hdr->array_offset));
>> +
>> + ret = snprintf(buf, sizeof(t_esi->value), "%llu\n",
>> + be64_to_cpu(t_esi->value));
>> + if (ret < 0)
>> + ret = -EIO;
>> +out:
>> + kfree(t_buf);
>> +
>> + return ret;
>> +}
>> +
>> +/*
>> + * Extract and export the value description in string format of the energy
>> + * scale attributes
>> + */
>> +static ssize_t papr_show_value_desc(struct kobject *kobj,
>> + struct kobj_attribute *kobj_attr,
>> + char *buf)
>> +{
>> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
>> + kobj_attr);
>> + struct h_energy_scale_info_hdr *t_hdr;
>> + struct energy_scale_attribute *t_esi;
>> + char *t_buf;
>> + int ret = 0;
>> +
>> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
>> + if (t_buf == NULL)
>> + return -ENOMEM;
>> +
>> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
>> + pattr->id, virt_to_phys(t_buf),
>> + MAX_BUF_SZ);
>> +
>> + if (ret != H_SUCCESS) {
>> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
>> + goto out;
>> + }
>> +
>> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
>> + t_esi = (struct energy_scale_attribute *)
>> + (t_buf + be64_to_cpu(t_hdr->array_offset));
>> +
>> + ret = snprintf(buf, sizeof(t_esi->value_desc), "%s\n",
>> + t_esi->value_desc);
>> + if (ret < 0)
>> + ret = -EIO;
>> +out:
>> + kfree(t_buf);
>> +
>> + return ret;
>> +}
>> +
>> +static struct papr_ops_info {
>> + const char *attr_name;
>> + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *kobj_attr,
>> + char *buf);
>> +} ops_info[MAX_ATTRS] = {
>> + { "desc", papr_show_desc },
>> + { "value", papr_show_value },
>> + { "value_desc", papr_show_value_desc },
>> +};
>> +
>> +static void add_attr(u64 id, int index, struct papr_attr *attr)
>> +{
>> + attr->id = id;
>> + sysfs_attr_init(&attr->kobj_attr.attr);
>> + attr->kobj_attr.attr.name = ops_info[index].attr_name;
>> + attr->kobj_attr.attr.mode = 0444;
>> + attr->kobj_attr.show = ops_info[index].show;
>> +}
>> +
>> +static int add_attr_group(u64 id, int len, struct papr_group *pg,
>> + bool show_val_desc)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < len; i++) {
> Could use MAX_ATTRS directly.
Sure, while writing this initially I wasn't sure how many attrs we'd have so it
passed as param, now I see that's not needed so I can remove that and use
MAX_ATTRS itself
>> + if (!strcmp(ops_info[i].attr_name, "value_desc") &&
>> + !show_val_desc) {
>> + continue;
>> + }
>> + add_attr(id, i, &pg->pgattrs[i]);
>> + pg->pg.attrs[i] = &pg->pgattrs[i].kobj_attr.attr;
>> + }
>> +
>> + return sysfs_create_group(esi_kobj, &pg->pg);
>> +}
>> +
>> +static int __init papr_init(void)
>> +{
>> + struct h_energy_scale_info_hdr *esi_hdr;
>> + struct energy_scale_attribute *esi_attrs;
>> + uint64_t num_attrs;
>> + int ret, idx, i;
>> + char *esi_buf;
>> +
>> + if (!firmware_has_feature(FW_FEATURE_LPAR))
>> + return -ENXIO;
>> +
>> + esi_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
>> + if (esi_buf == NULL)
>> + return -ENOMEM;
>> + /*
>> + * hcall(
>> + * uint64 H_GET_ENERGY_SCALE_INFO, // Get energy scale info
>> + * uint64 flags, // Per the flag request
>> + * uint64 firstAttributeId, // The attribute id
>> + * uint64 bufferAddress, // Guest physical address of the output buffer
>> + * uint64 bufferSize); // The size in bytes of the output buffer
>> + */
>> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_ALL, 0,
>> + virt_to_phys(esi_buf), MAX_BUF_SZ);
>> + if (ret != H_SUCCESS) {
>> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
>> + goto out;
>> + }
>> +
>> + esi_hdr = (struct h_energy_scale_info_hdr *) esi_buf;
>> + if (esi_hdr->data_header_version != ESI_VERSION) {
>> + pr_warn("H_GET_ENERGY_SCALE_INFO VER MISMATCH - EXP: 0x%x, REC: 0x%x",
>> + ESI_VERSION, esi_hdr->data_header_version);
>> + }
>> +
>> + num_attrs = be64_to_cpu(esi_hdr->num_attrs);
>> + esi_attrs = (struct energy_scale_attribute *)
>> + (esi_buf + be64_to_cpu(esi_hdr->array_offset));
>> +
>> + pgs = kcalloc(num_attrs, sizeof(*pgs), GFP_KERNEL);
>> + if (!pgs)
>> + goto out;
>> +
>> + papr_kobj = kobject_create_and_add("papr", firmware_kobj);
>> + if (!papr_kobj) {
>> + pr_warn("kobject_create_and_add papr failed\n");
>> + goto out_pgs;
>> + }
>> +
>> + esi_kobj = kobject_create_and_add("energy_scale_info", papr_kobj);
>> + if (!esi_kobj) {
>> + pr_warn("kobject_create_and_add energy_scale_info failed\n");
>> + goto out_kobj;
>> + }
>> +
>> + for (idx = 0; idx < num_attrs; idx++) {
>> + bool show_val_desc = true;
>> +
>> + pgs[idx].pg.attrs = kcalloc(MAX_ATTRS + 1,
>> + sizeof(*pgs[idx].pg.attrs),
>> + GFP_KERNEL);
>> + if (!pgs[idx].pg.attrs)
>> + goto out_ekobj;
> What about the attrs allocated during the previous iterations?
Yes, you're right that needs cleanups.
I could write the following to clean up old entries like I did when space for
name couldn't be allocated:
for (i = idx - 1; i >= 0; i++)
kfree(pgs[i].pg.attrs);
Thanks for pointing that out.
>> +
>> + pgs[idx].pg.name = kasprintf(GFP_KERNEL, "%lld",
>> + be64_to_cpu(esi_attrs[idx].id));
>> + if (pgs[idx].pg.name == NULL) {
>> + for (i = idx; i >= 0; i--)
>> + kfree(pgs[i].pg.attrs);
>> + goto out_ekobj;
>> + }
>> + /* Do not add the value description if it does not exist */
>> + if (strlen(esi_attrs[idx].value_desc) == 0)
> strnlen
ack
>
>> + show_val_desc = false;
>> +
>> + if (add_attr_group(be64_to_cpu(esi_attrs[idx].id),
>> + MAX_ATTRS, &pgs[idx], show_val_desc)) {
>> + pr_warn("Failed to create papr attribute group %s\n",
>> + pgs[idx].pg.name);
>> + goto out_pgattrs;
>> + }
>> + }
>> +
>> + kfree(esi_buf);
>> + return 0;
>> +
>> +out_pgattrs:
>> + for (i = 0; i < MAX_ATTRS ; i++) {
> pgs is num_attrs long
Ah yes, you're right. It should loop over num_attrs
>
>> + kfree(pgs[i].pg.attrs);
>> + kfree(pgs[i].pg.name);
>> + }
>> +out_ekobj:
>> + kobject_put(esi_kobj);
>> +out_kobj:
>> + kobject_put(papr_kobj);
>> +out_pgs:
>> + kfree(pgs);
>> +out:
>> + kfree(esi_buf);
>> +
>> + return -ENOMEM;
>> +}
>> +
>> +machine_device_initcall(pseries, papr_init);
^ permalink raw reply
* [PATCH] powerpc/chrp: Revert "Move PHB discovery" and "Make hydra_init() static"
From: Guenter Roeck @ 2021-07-16 22:11 UTC (permalink / raw)
To: Michael Ellerman
Cc: linux-kernel, Geert Uytterhoeven, Oliver O'Halloran,
Paul Mackerras, linuxppc-dev, Guenter Roeck
This patch reverts commit 407d418f2fd4 ("powerpc/chrp: Move PHB
discovery") and commit 9634afa67bfd ("powerpc/chrp: Make hydra_init()
static").
Running the upstream kernel on Qemu's brand new "pegasos2" emulation
results in a variety of backtraces such as
Kernel attempted to write user page (a1) - exploit attempt? (uid: 0)
------------[ cut here ]------------
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 0 at arch/powerpc/mm/fault.c:230 do_page_fault+0x4f4/0x920
CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.2 #40
NIP: c0021824 LR: c0021824 CTR: 00000000
REGS: c1085d50 TRAP: 0700 Not tainted (5.13.2)
MSR: 00021032 <ME,IR,DR,RI> CR: 24042254 XER: 00000000
GPR00: c0021824 c1085e10 c0f8c520 00000021 3fffefff c1085c60 c1085c58 00000000
GPR08: 00001032 00000000 00000000 c0ffb3ec 44042254 00000000 00000000 00000004
GPR16: 00000000 ffffffff 000000c4 000000d0 0188c6e0 01006000 00000001 40b14000
GPR24: c0ec000c 00000300 02000000 00000000 42000000 000000a1 00000000 c1085e60
NIP [c0021824] do_page_fault+0x4f4/0x920
LR [c0021824] do_page_fault+0x4f4/0x920
Call Trace:
[c1085e10] [c0021824] do_page_fault+0x4f4/0x920 (unreliable)
[c1085e50] [c0004254] DataAccess_virt+0xd4/0xe4
and the system fails to boot. Bisect points to commit 407d418f2fd4
("powerpc/chrp: Move PHB discovery"). Reverting this patch together with
commit 9634afa67bfd ("powerpc/chrp: Make hydra_init() static") fixes
the problem.
Cc: Oliver O'Halloran <oohall@gmail.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Fixes: 407d418f2fd4 ("powerpc/chrp: Move PHB discovery")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
arch/powerpc/include/asm/hydra.h | 2 ++
arch/powerpc/platforms/chrp/pci.c | 11 ++---------
arch/powerpc/platforms/chrp/setup.c | 12 +++++++++++-
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h
index d024447283a0..ae02eb53d6ef 100644
--- a/arch/powerpc/include/asm/hydra.h
+++ b/arch/powerpc/include/asm/hydra.h
@@ -94,6 +94,8 @@ extern volatile struct Hydra __iomem *Hydra;
#define HYDRA_INT_EXT7 18 /* Power Off Request */
#define HYDRA_INT_SPARE 19
+extern int hydra_init(void);
+
#endif /* __KERNEL__ */
#endif /* _ASMPPC_HYDRA_H */
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 76e6256cb0a7..b2c2bf35b76c 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -131,7 +131,8 @@ static struct pci_ops rtas_pci_ops =
volatile struct Hydra __iomem *Hydra = NULL;
-static int __init hydra_init(void)
+int __init
+hydra_init(void)
{
struct device_node *np;
struct resource r;
@@ -313,14 +314,6 @@ chrp_find_bridges(void)
}
}
of_node_put(root);
-
- /*
- * "Temporary" fixes for PCI devices.
- * -- Geert
- */
- hydra_init(); /* Mac I/O */
-
- pci_create_OF_bus_map();
}
/* SL82C105 IDE Control/Status Register */
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 3cfc382841e5..c45435aa5e36 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -334,11 +334,22 @@ static void __init chrp_setup_arch(void)
/* On pegasos, enable the L2 cache if not already done by OF */
pegasos_set_l2cr();
+ /* Lookup PCI host bridges */
+ chrp_find_bridges();
+
+ /*
+ * Temporary fixes for PCI devices.
+ * -- Geert
+ */
+ hydra_init(); /* Mac I/O */
+
/*
* Fix the Super I/O configuration
*/
sio_init();
+ pci_create_OF_bus_map();
+
/*
* Print the banner, then scroll down so boot progress
* can be printed. -- Cort
@@ -571,7 +582,6 @@ define_machine(chrp) {
.name = "CHRP",
.probe = chrp_probe,
.setup_arch = chrp_setup_arch,
- .discover_phbs = chrp_find_bridges,
.init = chrp_init2,
.show_cpuinfo = chrp_show_cpuinfo,
.init_IRQ = chrp_init_IRQ,
--
2.25.1
^ permalink raw reply related
* [PATCH] ibmvfc: fix command state accounting and stale response detection
From: Tyrel Datwyler @ 2021-07-16 20:52 UTC (permalink / raw)
To: james.bottomley
Cc: Tyrel Datwyler, martin.petersen, linux-scsi, linux-kernel, stable,
brking, linuxppc-dev
Prior to commit 1f4a4a19508d ("scsi: ibmvfc: Complete commands outside
the host/queue lock") responses to commands were completed sequentially
with the host lock held such that a command had a basic binary state of
active or free. It was therefore a simple affair of ensuring the
assocaiated ibmvfc_event to a VIOS response was valid by testing that it
was not already free. The lock relexation work to complete commands
outside the lock inadverdently made it a trinary command state such that
a command is either in flight, received and being completed, or
completed and now free. This breaks the stale command detection logic as
a command may be still marked active and been placed on the delayed
completion list when a second stale response for the same command
arrives. This can lead to double completions and list corruption. This
issue was exposed by a recent VIOS regression were a missing memory
barrier could occasionally result in the ibmvfc client receiveing a
duplicate response for the same command.
Fix the issue by introducing the atomic ibmvfc_event.active to track the
trinary state of a command. The state is explicitly set to 1 when a
command is successfully sent. The CRQ response handlers use
atomic_dec_if_positive() to test for stale responses and correctly
transition to the completion state when a active command is received.
Finally, atomic_dec_and_test() is used to sanity check transistions
when commands are freed as a result of a completion, or moved to the
purge list as a result of error handling or adapter reset.
Cc: stable@vger.kernel.org
Fixes: 1f4a4a19508d ("scsi: ibmvfc: Complete commands outside the host/queue lock")
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 19 +++++++++++++++++--
drivers/scsi/ibmvscsi/ibmvfc.h | 1 +
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index bee1bec49c09..935b01ee44b7 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -807,6 +807,13 @@ static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost,
for (i = 0; i < size; ++i) {
struct ibmvfc_event *evt = &pool->events[i];
+ /*
+ * evt->active states
+ * 1 = in flight
+ * 0 = being completed
+ * -1 = free/freed
+ */
+ atomic_set(&evt->active, -1);
atomic_set(&evt->free, 1);
evt->crq.valid = 0x80;
evt->crq.ioba = cpu_to_be64(pool->iu_token + (sizeof(*evt->xfer_iu) * i));
@@ -1017,6 +1024,7 @@ static void ibmvfc_free_event(struct ibmvfc_event *evt)
BUG_ON(!ibmvfc_valid_event(pool, evt));
BUG_ON(atomic_inc_return(&evt->free) != 1);
+ BUG_ON(atomic_dec_and_test(&evt->active));
spin_lock_irqsave(&evt->queue->l_lock, flags);
list_add_tail(&evt->queue_list, &evt->queue->free);
@@ -1072,6 +1080,12 @@ static void ibmvfc_complete_purge(struct list_head *purge_list)
**/
static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
{
+ /*
+ * Anything we are failing should still be active. Otherwise, it
+ * implies we already got a response for the command and are doing
+ * something bad like double completing it.
+ */
+ BUG_ON(!atomic_dec_and_test(&evt->active));
if (evt->cmnd) {
evt->cmnd->result = (error_code << 16);
evt->done = ibmvfc_scsi_eh_done;
@@ -1723,6 +1737,7 @@ static int ibmvfc_send_event(struct ibmvfc_event *evt,
evt->done(evt);
} else {
+ atomic_set(&evt->active, 1);
spin_unlock_irqrestore(&evt->queue->l_lock, flags);
ibmvfc_trc_start(evt);
}
@@ -3251,7 +3266,7 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost,
return;
}
- if (unlikely(atomic_read(&evt->free))) {
+ if (unlikely(atomic_dec_if_positive(&evt->active))) {
dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n",
crq->ioba);
return;
@@ -3778,7 +3793,7 @@ static void ibmvfc_handle_scrq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost
return;
}
- if (unlikely(atomic_read(&evt->free))) {
+ if (unlikely(atomic_dec_if_positive(&evt->active))) {
dev_err(vhost->dev, "Received duplicate correlation_token 0x%08llx!\n",
crq->ioba);
return;
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 4f0f3baefae4..92fb889d7eb0 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -745,6 +745,7 @@ struct ibmvfc_event {
struct ibmvfc_target *tgt;
struct scsi_cmnd *cmnd;
atomic_t free;
+ atomic_t active;
union ibmvfc_iu *xfer_iu;
void (*done)(struct ibmvfc_event *evt);
void (*_done)(struct ibmvfc_event *evt);
--
2.27.0
^ permalink raw reply related
* Re: [PATCH v4 1/1] powerpc/pseries: Interface to represent PAPR firmware attributes
From: Fabiano Rosas @ 2021-07-16 19:05 UTC (permalink / raw)
To: Pratik R. Sampat, mpe, benh, paulus, linuxppc-dev, kvm-ppc,
linux-kernel, psampat, pratik.r.sampat
In-Reply-To: <20210716152133.72455-2-psampat@linux.ibm.com>
"Pratik R. Sampat" <psampat@linux.ibm.com> writes:
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/seq_file.h>
> +#include <linux/slab.h>
> +#include <linux/uaccess.h>
> +#include <linux/hugetlb.h>
> +#include <asm/lppaca.h>
> +#include <asm/hvcall.h>
> +#include <asm/firmware.h>
> +#include <asm/time.h>
> +#include <asm/prom.h>
> +#include <asm/vdso_datapage.h>
> +#include <asm/vio.h>
> +#include <asm/mmu.h>
> +#include <asm/machdep.h>
> +#include <asm/drmem.h>
Do you need all of these headers? Sorry to mention just now, I seem to have
dropped this comment from a previous review.
> +
> +#include "pseries.h"
> +
> +/*
> + * Flag attributes to fetch either all or one attribute from the HCALL
> + * flag = BE(0) => fetch all attributes with firstAttributeId = 0
> + * flag = BE(1) => fetch a single attribute with firstAttributeId = id
> + */
> +#define ESI_FLAGS_ALL 0
> +#define ESI_FLAGS_SINGLE PPC_BIT(0)
> +
> +#define MAX_ATTRS 3
> +
> +struct papr_attr {
> + u64 id;
> + struct kobj_attribute kobj_attr;
> +};
> +struct papr_group {
> + struct attribute_group pg;
> + struct papr_attr pgattrs[MAX_ATTRS];
> +} *pgs;
> +
> +/* /sys/firmware/papr */
> +struct kobject *papr_kobj;
> +/* /sys/firmware/papr/energy_scale_info */
> +struct kobject *esi_kobj;
> +
> +/*
> + * Extract and export the description of the energy scale attribute
> + *
Extra line here.
> + */
> +static ssize_t papr_show_desc(struct kobject *kobj,
> + struct kobj_attribute *kobj_attr,
> + char *buf)
> +{
> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
> + kobj_attr);
> + struct h_energy_scale_info_hdr *t_hdr;
> + struct energy_scale_attribute *t_esi;
> + char *t_buf;
> + int ret = 0;
> +
> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
> + if (t_buf == NULL)
> + return -ENOMEM;
> +
> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
> + pattr->id, virt_to_phys(t_buf),
> + MAX_BUF_SZ);
> +
> + if (ret != H_SUCCESS) {
> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
> + goto out;
> + }
> +
> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
> + t_esi = (struct energy_scale_attribute *)
> + (t_buf + be64_to_cpu(t_hdr->array_offset));
> +
> + ret = snprintf(buf, sizeof(t_esi->desc), "%s\n", t_esi->desc);
> + if (ret < 0)
> + ret = -EIO;
> +out:
> + kfree(t_buf);
> +
> + return ret;
> +}
> +
> +/*
> + * Extract and export the numeric value of the energy scale attributes
> + */
> +static ssize_t papr_show_value(struct kobject *kobj,
> + struct kobj_attribute *kobj_attr,
> + char *buf)
> +{
> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
> + kobj_attr);
> + struct h_energy_scale_info_hdr *t_hdr;
> + struct energy_scale_attribute *t_esi;
> + char *t_buf;
> + int ret = 0;
> +
> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
> + if (t_buf == NULL)
> + return -ENOMEM;
> +
> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
> + pattr->id, virt_to_phys(t_buf),
> + MAX_BUF_SZ);
> +
> + if (ret != H_SUCCESS) {
> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
> + goto out;
> + }
> +
> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
> + t_esi = (struct energy_scale_attribute *)
> + (t_buf + be64_to_cpu(t_hdr->array_offset));
> +
> + ret = snprintf(buf, sizeof(t_esi->value), "%llu\n",
> + be64_to_cpu(t_esi->value));
> + if (ret < 0)
> + ret = -EIO;
> +out:
> + kfree(t_buf);
> +
> + return ret;
> +}
> +
> +/*
> + * Extract and export the value description in string format of the energy
> + * scale attributes
> + */
> +static ssize_t papr_show_value_desc(struct kobject *kobj,
> + struct kobj_attribute *kobj_attr,
> + char *buf)
> +{
> + struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
> + kobj_attr);
> + struct h_energy_scale_info_hdr *t_hdr;
> + struct energy_scale_attribute *t_esi;
> + char *t_buf;
> + int ret = 0;
> +
> + t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
> + if (t_buf == NULL)
> + return -ENOMEM;
> +
> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
> + pattr->id, virt_to_phys(t_buf),
> + MAX_BUF_SZ);
> +
> + if (ret != H_SUCCESS) {
> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
> + goto out;
> + }
> +
> + t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
> + t_esi = (struct energy_scale_attribute *)
> + (t_buf + be64_to_cpu(t_hdr->array_offset));
> +
> + ret = snprintf(buf, sizeof(t_esi->value_desc), "%s\n",
> + t_esi->value_desc);
> + if (ret < 0)
> + ret = -EIO;
> +out:
> + kfree(t_buf);
> +
> + return ret;
> +}
> +
> +static struct papr_ops_info {
> + const char *attr_name;
> + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *kobj_attr,
> + char *buf);
> +} ops_info[MAX_ATTRS] = {
> + { "desc", papr_show_desc },
> + { "value", papr_show_value },
> + { "value_desc", papr_show_value_desc },
> +};
> +
> +static void add_attr(u64 id, int index, struct papr_attr *attr)
> +{
> + attr->id = id;
> + sysfs_attr_init(&attr->kobj_attr.attr);
> + attr->kobj_attr.attr.name = ops_info[index].attr_name;
> + attr->kobj_attr.attr.mode = 0444;
> + attr->kobj_attr.show = ops_info[index].show;
> +}
> +
> +static int add_attr_group(u64 id, int len, struct papr_group *pg,
> + bool show_val_desc)
> +{
> + int i;
> +
> + for (i = 0; i < len; i++) {
Could use MAX_ATTRS directly.
> + if (!strcmp(ops_info[i].attr_name, "value_desc") &&
> + !show_val_desc) {
> + continue;
> + }
> + add_attr(id, i, &pg->pgattrs[i]);
> + pg->pg.attrs[i] = &pg->pgattrs[i].kobj_attr.attr;
> + }
> +
> + return sysfs_create_group(esi_kobj, &pg->pg);
> +}
> +
> +static int __init papr_init(void)
> +{
> + struct h_energy_scale_info_hdr *esi_hdr;
> + struct energy_scale_attribute *esi_attrs;
> + uint64_t num_attrs;
> + int ret, idx, i;
> + char *esi_buf;
> +
> + if (!firmware_has_feature(FW_FEATURE_LPAR))
> + return -ENXIO;
> +
> + esi_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
> + if (esi_buf == NULL)
> + return -ENOMEM;
> + /*
> + * hcall(
> + * uint64 H_GET_ENERGY_SCALE_INFO, // Get energy scale info
> + * uint64 flags, // Per the flag request
> + * uint64 firstAttributeId, // The attribute id
> + * uint64 bufferAddress, // Guest physical address of the output buffer
> + * uint64 bufferSize); // The size in bytes of the output buffer
> + */
> + ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_ALL, 0,
> + virt_to_phys(esi_buf), MAX_BUF_SZ);
> + if (ret != H_SUCCESS) {
> + pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
> + goto out;
> + }
> +
> + esi_hdr = (struct h_energy_scale_info_hdr *) esi_buf;
> + if (esi_hdr->data_header_version != ESI_VERSION) {
> + pr_warn("H_GET_ENERGY_SCALE_INFO VER MISMATCH - EXP: 0x%x, REC: 0x%x",
> + ESI_VERSION, esi_hdr->data_header_version);
> + }
> +
> + num_attrs = be64_to_cpu(esi_hdr->num_attrs);
> + esi_attrs = (struct energy_scale_attribute *)
> + (esi_buf + be64_to_cpu(esi_hdr->array_offset));
> +
> + pgs = kcalloc(num_attrs, sizeof(*pgs), GFP_KERNEL);
> + if (!pgs)
> + goto out;
> +
> + papr_kobj = kobject_create_and_add("papr", firmware_kobj);
> + if (!papr_kobj) {
> + pr_warn("kobject_create_and_add papr failed\n");
> + goto out_pgs;
> + }
> +
> + esi_kobj = kobject_create_and_add("energy_scale_info", papr_kobj);
> + if (!esi_kobj) {
> + pr_warn("kobject_create_and_add energy_scale_info failed\n");
> + goto out_kobj;
> + }
> +
> + for (idx = 0; idx < num_attrs; idx++) {
> + bool show_val_desc = true;
> +
> + pgs[idx].pg.attrs = kcalloc(MAX_ATTRS + 1,
> + sizeof(*pgs[idx].pg.attrs),
> + GFP_KERNEL);
> + if (!pgs[idx].pg.attrs)
> + goto out_ekobj;
What about the attrs allocated during the previous iterations?
> +
> + pgs[idx].pg.name = kasprintf(GFP_KERNEL, "%lld",
> + be64_to_cpu(esi_attrs[idx].id));
> + if (pgs[idx].pg.name == NULL) {
> + for (i = idx; i >= 0; i--)
> + kfree(pgs[i].pg.attrs);
> + goto out_ekobj;
> + }
> + /* Do not add the value description if it does not exist */
> + if (strlen(esi_attrs[idx].value_desc) == 0)
strnlen
> + show_val_desc = false;
> +
> + if (add_attr_group(be64_to_cpu(esi_attrs[idx].id),
> + MAX_ATTRS, &pgs[idx], show_val_desc)) {
> + pr_warn("Failed to create papr attribute group %s\n",
> + pgs[idx].pg.name);
> + goto out_pgattrs;
> + }
> + }
> +
> + kfree(esi_buf);
> + return 0;
> +
> +out_pgattrs:
> + for (i = 0; i < MAX_ATTRS ; i++) {
pgs is num_attrs long
> + kfree(pgs[i].pg.attrs);
> + kfree(pgs[i].pg.name);
> + }
> +out_ekobj:
> + kobject_put(esi_kobj);
> +out_kobj:
> + kobject_put(papr_kobj);
> +out_pgs:
> + kfree(pgs);
> +out:
> + kfree(esi_buf);
> +
> + return -ENOMEM;
> +}
> +
> +machine_device_initcall(pseries, papr_init);
^ permalink raw reply
* Re: [PATCH v1 16/16] dma-mapping: Disallow .map_sg operations from returning zero on error
From: Logan Gunthorpe @ 2021-07-16 16:17 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-s390, linux-ia64, linux-parisc, Robin Murphy, linux-mips,
linux-kernel, iommu, linux-alpha, sparclinux, xen-devel,
Stephen Bates, linuxppc-dev, Martin Oliveira, linux-arm-kernel,
Marek Szyprowski
In-Reply-To: <20210716063332.GD13345@lst.de>
On 2021-07-16 12:33 a.m., Christoph Hellwig wrote:
> On Thu, Jul 15, 2021 at 10:45:44AM -0600, Logan Gunthorpe wrote:
>> @@ -194,6 +194,8 @@ static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>> else
>> ents = ops->map_sg(dev, sg, nents, dir, attrs);
>>
>> + WARN_ON_ONCE(ents == 0);
>
> Turns this into a negative error code while we're at it, just to keep
> the callers sane?
>
Sure thing. All the feedback makes sense, we'll fix it up and send a v2
in due course.
Thanks,
Logan
^ permalink raw reply
* [PATCH v4 1/1] powerpc/pseries: Interface to represent PAPR firmware attributes
From: Pratik R. Sampat @ 2021-07-16 15:21 UTC (permalink / raw)
To: mpe, benh, paulus, linuxppc-dev, kvm-ppc, linux-kernel, psampat,
pratik.r.sampat
In-Reply-To: <20210716152133.72455-1-psampat@linux.ibm.com>
Adds a generic interface to represent the energy and frequency related
PAPR attributes on the system using the new H_CALL
"H_GET_ENERGY_SCALE_INFO".
H_GET_EM_PARMS H_CALL was previously responsible for exporting this
information in the lparcfg, however the H_GET_EM_PARMS H_CALL
will be deprecated P10 onwards.
The H_GET_ENERGY_SCALE_INFO H_CALL is of the following call format:
hcall(
uint64 H_GET_ENERGY_SCALE_INFO, // Get energy scale info
uint64 flags, // Per the flag request
uint64 firstAttributeId,// The attribute id
uint64 bufferAddress, // Guest physical address of the output buffer
uint64 bufferSize // The size in bytes of the output buffer
);
This H_CALL can query either all the attributes at once with
firstAttributeId = 0, flags = 0 as well as query only one attribute
at a time with firstAttributeId = id, flags = 1.
The output buffer consists of the following
1. number of attributes - 8 bytes
2. array offset to the data location - 8 bytes
3. version info - 1 byte
4. A data array of size num attributes, which contains the following:
a. attribute ID - 8 bytes
b. attribute value in number - 8 bytes
c. attribute name in string - 64 bytes
d. attribute value in string - 64 bytes
The new H_CALL exports information in direct string value format, hence
a new interface has been introduced in
/sys/firmware/papr/energy_scale_info to export this information to
userspace in an extensible pass-through format.
The H_CALL returns the name, numeric value and string value (if exists)
The format of exposing the sysfs information is as follows:
/sys/firmware/papr/energy_scale_info/
|-- <id>/
|-- desc
|-- value
|-- value_desc (if exists)
|-- <id>/
|-- desc
|-- value
|-- value_desc (if exists)
...
The energy information that is exported is useful for userspace tools
such as powerpc-utils. Currently these tools infer the
"power_mode_data" value in the lparcfg, which in turn is obtained from
the to be deprecated H_GET_EM_PARMS H_CALL.
On future platforms, such userspace utilities will have to look at the
data returned from the new H_CALL being populated in this new sysfs
interface and report this information directly without the need of
interpretation.
Signed-off-by: Pratik R. Sampat <psampat@linux.ibm.com>
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
---
.../sysfs-firmware-papr-energy-scale-info | 26 ++
arch/powerpc/include/asm/hvcall.h | 24 +-
arch/powerpc/kvm/trace_hv.h | 1 +
arch/powerpc/platforms/pseries/Makefile | 3 +-
.../pseries/papr_platform_attributes.c | 331 ++++++++++++++++++
5 files changed, 383 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-firmware-papr-energy-scale-info
create mode 100644 arch/powerpc/platforms/pseries/papr_platform_attributes.c
diff --git a/Documentation/ABI/testing/sysfs-firmware-papr-energy-scale-info b/Documentation/ABI/testing/sysfs-firmware-papr-energy-scale-info
new file mode 100644
index 000000000000..139a576c7c9d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-papr-energy-scale-info
@@ -0,0 +1,26 @@
+What: /sys/firmware/papr/energy_scale_info
+Date: June 2021
+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: Directory hosting a set of platform attributes like
+ energy/frequency on Linux running as a PAPR guest.
+
+ Each file in a directory contains a platform
+ attribute hierarchy pertaining to performance/
+ energy-savings mode and processor frequency.
+
+What: /sys/firmware/papr/energy_scale_info/<id>
+ /sys/firmware/papr/energy_scale_info/<id>/desc
+ /sys/firmware/papr/energy_scale_info/<id>/value
+ /sys/firmware/papr/energy_scale_info/<id>/value_desc
+Date: June 2021
+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: Energy, frequency attributes directory for POWERVM servers
+
+ This directory provides energy, frequency, folding information. It
+ contains below sysfs attributes:
+
+ - desc: String description of the attribute <id>
+
+ - value: Numeric value of attribute <id>
+
+ - value_desc: String value of attribute <id>
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index e3b29eda8074..c91714ea6719 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -316,7 +316,8 @@
#define H_SCM_PERFORMANCE_STATS 0x418
#define H_RPT_INVALIDATE 0x448
#define H_SCM_FLUSH 0x44C
-#define MAX_HCALL_OPCODE H_SCM_FLUSH
+#define H_GET_ENERGY_SCALE_INFO 0x450
+#define MAX_HCALL_OPCODE H_GET_ENERGY_SCALE_INFO
/* Scope args for H_SCM_UNBIND_ALL */
#define H_UNBIND_SCOPE_ALL (0x1)
@@ -631,6 +632,27 @@ struct hv_gpci_request_buffer {
uint8_t bytes[HGPCI_MAX_DATA_BYTES];
} __packed;
+#define ESI_VERSION 0x1
+#define MAX_ESI_ATTRS 10
+#define MAX_BUF_SZ (sizeof(struct h_energy_scale_info_hdr) + \
+ (sizeof(struct energy_scale_attribute) * MAX_ESI_ATTRS))
+
+struct energy_scale_attribute {
+ __be64 id;
+ __be64 value;
+ unsigned char desc[64];
+ unsigned char value_desc[64];
+} __packed;
+
+struct h_energy_scale_info_hdr {
+ __be64 num_attrs;
+ __be64 array_offset;
+ __u8 data_header_version;
+} __packed;
+
+/* /sys/firmware/papr */
+extern struct kobject *papr_kobj;
+
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HVCALL_H */
diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h
index 830a126e095d..38cd0ed0a617 100644
--- a/arch/powerpc/kvm/trace_hv.h
+++ b/arch/powerpc/kvm/trace_hv.h
@@ -115,6 +115,7 @@
{H_VASI_STATE, "H_VASI_STATE"}, \
{H_ENABLE_CRQ, "H_ENABLE_CRQ"}, \
{H_GET_EM_PARMS, "H_GET_EM_PARMS"}, \
+ {H_GET_ENERGY_SCALE_INFO, "H_GET_ENERGY_SCALE_INFO"}, \
{H_SET_MPP, "H_SET_MPP"}, \
{H_GET_MPP, "H_GET_MPP"}, \
{H_HOME_NODE_ASSOCIATIVITY, "H_HOME_NODE_ASSOCIATIVITY"}, \
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index c8a2b0b05ac0..d14fca89ac25 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -6,7 +6,8 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
of_helpers.o \
setup.o iommu.o event_sources.o ras.o \
firmware.o power.o dlpar.o mobility.o rng.o \
- pci.o pci_dlpar.o eeh_pseries.o msi.o
+ pci.o pci_dlpar.o eeh_pseries.o msi.o \
+ papr_platform_attributes.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_KEXEC_CORE) += kexec.o
diff --git a/arch/powerpc/platforms/pseries/papr_platform_attributes.c b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
new file mode 100644
index 000000000000..32262038dbf4
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Platform energy and frequency attributes driver
+ *
+ * This driver creates a sys file at /sys/firmware/papr/ which encapsulates a
+ * directory structure containing files in keyword - value pairs that specify
+ * energy and frequency configuration of the system.
+ *
+ * The format of exposing the sysfs information is as follows:
+ * /sys/firmware/papr/energy_scale_info/
+ * |-- <id>/
+ * |-- desc
+ * |-- value
+ * |-- value_desc (if exists)
+ * |-- <id>/
+ * |-- desc
+ * |-- value
+ * |-- value_desc (if exists)
+ *
+ * Copyright 2021 IBM Corp.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/hugetlb.h>
+#include <asm/lppaca.h>
+#include <asm/hvcall.h>
+#include <asm/firmware.h>
+#include <asm/time.h>
+#include <asm/prom.h>
+#include <asm/vdso_datapage.h>
+#include <asm/vio.h>
+#include <asm/mmu.h>
+#include <asm/machdep.h>
+#include <asm/drmem.h>
+
+#include "pseries.h"
+
+/*
+ * Flag attributes to fetch either all or one attribute from the HCALL
+ * flag = BE(0) => fetch all attributes with firstAttributeId = 0
+ * flag = BE(1) => fetch a single attribute with firstAttributeId = id
+ */
+#define ESI_FLAGS_ALL 0
+#define ESI_FLAGS_SINGLE PPC_BIT(0)
+
+#define MAX_ATTRS 3
+
+struct papr_attr {
+ u64 id;
+ struct kobj_attribute kobj_attr;
+};
+struct papr_group {
+ struct attribute_group pg;
+ struct papr_attr pgattrs[MAX_ATTRS];
+} *pgs;
+
+/* /sys/firmware/papr */
+struct kobject *papr_kobj;
+/* /sys/firmware/papr/energy_scale_info */
+struct kobject *esi_kobj;
+
+/*
+ * Extract and export the description of the energy scale attribute
+ *
+ */
+static ssize_t papr_show_desc(struct kobject *kobj,
+ struct kobj_attribute *kobj_attr,
+ char *buf)
+{
+ struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
+ kobj_attr);
+ struct h_energy_scale_info_hdr *t_hdr;
+ struct energy_scale_attribute *t_esi;
+ char *t_buf;
+ int ret = 0;
+
+ t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
+ if (t_buf == NULL)
+ return -ENOMEM;
+
+ ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
+ pattr->id, virt_to_phys(t_buf),
+ MAX_BUF_SZ);
+
+ if (ret != H_SUCCESS) {
+ pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
+ goto out;
+ }
+
+ t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
+ t_esi = (struct energy_scale_attribute *)
+ (t_buf + be64_to_cpu(t_hdr->array_offset));
+
+ ret = snprintf(buf, sizeof(t_esi->desc), "%s\n", t_esi->desc);
+ if (ret < 0)
+ ret = -EIO;
+out:
+ kfree(t_buf);
+
+ return ret;
+}
+
+/*
+ * Extract and export the numeric value of the energy scale attributes
+ */
+static ssize_t papr_show_value(struct kobject *kobj,
+ struct kobj_attribute *kobj_attr,
+ char *buf)
+{
+ struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
+ kobj_attr);
+ struct h_energy_scale_info_hdr *t_hdr;
+ struct energy_scale_attribute *t_esi;
+ char *t_buf;
+ int ret = 0;
+
+ t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
+ if (t_buf == NULL)
+ return -ENOMEM;
+
+ ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
+ pattr->id, virt_to_phys(t_buf),
+ MAX_BUF_SZ);
+
+ if (ret != H_SUCCESS) {
+ pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
+ goto out;
+ }
+
+ t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
+ t_esi = (struct energy_scale_attribute *)
+ (t_buf + be64_to_cpu(t_hdr->array_offset));
+
+ ret = snprintf(buf, sizeof(t_esi->value), "%llu\n",
+ be64_to_cpu(t_esi->value));
+ if (ret < 0)
+ ret = -EIO;
+out:
+ kfree(t_buf);
+
+ return ret;
+}
+
+/*
+ * Extract and export the value description in string format of the energy
+ * scale attributes
+ */
+static ssize_t papr_show_value_desc(struct kobject *kobj,
+ struct kobj_attribute *kobj_attr,
+ char *buf)
+{
+ struct papr_attr *pattr = container_of(kobj_attr, struct papr_attr,
+ kobj_attr);
+ struct h_energy_scale_info_hdr *t_hdr;
+ struct energy_scale_attribute *t_esi;
+ char *t_buf;
+ int ret = 0;
+
+ t_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
+ if (t_buf == NULL)
+ return -ENOMEM;
+
+ ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_SINGLE,
+ pattr->id, virt_to_phys(t_buf),
+ MAX_BUF_SZ);
+
+ if (ret != H_SUCCESS) {
+ pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
+ goto out;
+ }
+
+ t_hdr = (struct h_energy_scale_info_hdr *) t_buf;
+ t_esi = (struct energy_scale_attribute *)
+ (t_buf + be64_to_cpu(t_hdr->array_offset));
+
+ ret = snprintf(buf, sizeof(t_esi->value_desc), "%s\n",
+ t_esi->value_desc);
+ if (ret < 0)
+ ret = -EIO;
+out:
+ kfree(t_buf);
+
+ return ret;
+}
+
+static struct papr_ops_info {
+ const char *attr_name;
+ ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *kobj_attr,
+ char *buf);
+} ops_info[MAX_ATTRS] = {
+ { "desc", papr_show_desc },
+ { "value", papr_show_value },
+ { "value_desc", papr_show_value_desc },
+};
+
+static void add_attr(u64 id, int index, struct papr_attr *attr)
+{
+ attr->id = id;
+ sysfs_attr_init(&attr->kobj_attr.attr);
+ attr->kobj_attr.attr.name = ops_info[index].attr_name;
+ attr->kobj_attr.attr.mode = 0444;
+ attr->kobj_attr.show = ops_info[index].show;
+}
+
+static int add_attr_group(u64 id, int len, struct papr_group *pg,
+ bool show_val_desc)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (!strcmp(ops_info[i].attr_name, "value_desc") &&
+ !show_val_desc) {
+ continue;
+ }
+ add_attr(id, i, &pg->pgattrs[i]);
+ pg->pg.attrs[i] = &pg->pgattrs[i].kobj_attr.attr;
+ }
+
+ return sysfs_create_group(esi_kobj, &pg->pg);
+}
+
+static int __init papr_init(void)
+{
+ struct h_energy_scale_info_hdr *esi_hdr;
+ struct energy_scale_attribute *esi_attrs;
+ uint64_t num_attrs;
+ int ret, idx, i;
+ char *esi_buf;
+
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
+ return -ENXIO;
+
+ esi_buf = kmalloc(MAX_BUF_SZ, GFP_KERNEL);
+ if (esi_buf == NULL)
+ return -ENOMEM;
+ /*
+ * hcall(
+ * uint64 H_GET_ENERGY_SCALE_INFO, // Get energy scale info
+ * uint64 flags, // Per the flag request
+ * uint64 firstAttributeId, // The attribute id
+ * uint64 bufferAddress, // Guest physical address of the output buffer
+ * uint64 bufferSize); // The size in bytes of the output buffer
+ */
+ ret = plpar_hcall_norets(H_GET_ENERGY_SCALE_INFO, ESI_FLAGS_ALL, 0,
+ virt_to_phys(esi_buf), MAX_BUF_SZ);
+ if (ret != H_SUCCESS) {
+ pr_warn("hcall failed: H_GET_ENERGY_SCALE_INFO");
+ goto out;
+ }
+
+ esi_hdr = (struct h_energy_scale_info_hdr *) esi_buf;
+ if (esi_hdr->data_header_version != ESI_VERSION) {
+ pr_warn("H_GET_ENERGY_SCALE_INFO VER MISMATCH - EXP: 0x%x, REC: 0x%x",
+ ESI_VERSION, esi_hdr->data_header_version);
+ }
+
+ num_attrs = be64_to_cpu(esi_hdr->num_attrs);
+ esi_attrs = (struct energy_scale_attribute *)
+ (esi_buf + be64_to_cpu(esi_hdr->array_offset));
+
+ pgs = kcalloc(num_attrs, sizeof(*pgs), GFP_KERNEL);
+ if (!pgs)
+ goto out;
+
+ papr_kobj = kobject_create_and_add("papr", firmware_kobj);
+ if (!papr_kobj) {
+ pr_warn("kobject_create_and_add papr failed\n");
+ goto out_pgs;
+ }
+
+ esi_kobj = kobject_create_and_add("energy_scale_info", papr_kobj);
+ if (!esi_kobj) {
+ pr_warn("kobject_create_and_add energy_scale_info failed\n");
+ goto out_kobj;
+ }
+
+ for (idx = 0; idx < num_attrs; idx++) {
+ bool show_val_desc = true;
+
+ pgs[idx].pg.attrs = kcalloc(MAX_ATTRS + 1,
+ sizeof(*pgs[idx].pg.attrs),
+ GFP_KERNEL);
+ if (!pgs[idx].pg.attrs)
+ goto out_ekobj;
+
+ pgs[idx].pg.name = kasprintf(GFP_KERNEL, "%lld",
+ be64_to_cpu(esi_attrs[idx].id));
+ if (pgs[idx].pg.name == NULL) {
+ for (i = idx; i >= 0; i--)
+ kfree(pgs[i].pg.attrs);
+ goto out_ekobj;
+ }
+ /* Do not add the value description if it does not exist */
+ if (strlen(esi_attrs[idx].value_desc) == 0)
+ show_val_desc = false;
+
+ if (add_attr_group(be64_to_cpu(esi_attrs[idx].id),
+ MAX_ATTRS, &pgs[idx], show_val_desc)) {
+ pr_warn("Failed to create papr attribute group %s\n",
+ pgs[idx].pg.name);
+ goto out_pgattrs;
+ }
+ }
+
+ kfree(esi_buf);
+ return 0;
+
+out_pgattrs:
+ for (i = 0; i < MAX_ATTRS ; i++) {
+ kfree(pgs[i].pg.attrs);
+ kfree(pgs[i].pg.name);
+ }
+out_ekobj:
+ kobject_put(esi_kobj);
+out_kobj:
+ kobject_put(papr_kobj);
+out_pgs:
+ kfree(pgs);
+out:
+ kfree(esi_buf);
+
+ return -ENOMEM;
+}
+
+machine_device_initcall(pseries, papr_init);
--
2.31.1
^ permalink raw reply related
* [PATCH v4 0/1] Interface to represent PAPR firmware attributes
From: Pratik R. Sampat @ 2021-07-16 15:21 UTC (permalink / raw)
To: mpe, benh, paulus, linuxppc-dev, kvm-ppc, linux-kernel, psampat,
pratik.r.sampat
RFC: https://lkml.org/lkml/2021/6/4/791
PATCH v1: https://lkml.org/lkml/2021/6/16/805
PATCH v2: https://lkml.org/lkml/2021/7/6/138
PATCH v3: https://lkml.org/lkml/2021/7/12/2799
Changelog v3 --> v4
Based on a comment from Fabiano:
1. Resolved typo in documentation
2. Statically allocate "pgattrs" instead of kmalloc as size known at
compile time
3. Converted sprintf calls to snprintf as size of buffer is known
4. Changed the implementation of "papr_show_desc" function to make an
extra H_CALL as a result of making the scope of esi_hdr and
esi_attrs local
5. Removed bailing out on version mismatch as the documentation states
that the attribute structure can never change, only the data and that
will not break the implementation. Hence just a warning is issued on
version mismatch
6. Avoid passing a statically allocated buf to "pgs[idx].pg.name",
instead used kasprintf to allocate and pass the data through
Also, have implemented a POC using this interface for the powerpc-utils'
ppc64_cpu --frequency command-line tool to utilize this information
in userspace.
The POC for the new interface has been hosted here:
https://github.com/pratiksampat/powerpc-utils/tree/H_GET_ENERGY_SCALE_INFO_v2
Sample output from the powerpc-utils tool is as follows:
# ppc64_cpu --frequency
Power and Performance Mode: XXXX
Idle Power Saver Status : XXXX
Processor Folding Status : XXXX --> Printed if Idle power save status is supported
Platform reported frequencies --> Frequencies reported from the platform's H_CALL i.e PAPR interface
min : NNNN GHz
max : NNNN GHz
static : NNNN GHz
Tool Computed frequencies
min : NNNN GHz (cpu XX)
max : NNNN GHz (cpu XX)
avg : NNNN GHz
Pratik R. Sampat (1):
powerpc/pseries: Interface to represent PAPR firmware attributes
.../sysfs-firmware-papr-energy-scale-info | 26 ++
arch/powerpc/include/asm/hvcall.h | 24 +-
arch/powerpc/kvm/trace_hv.h | 1 +
arch/powerpc/platforms/pseries/Makefile | 3 +-
.../pseries/papr_platform_attributes.c | 331 ++++++++++++++++++
5 files changed, 383 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-firmware-papr-energy-scale-info
create mode 100644 arch/powerpc/platforms/pseries/papr_platform_attributes.c
--
2.31.1
^ permalink raw reply
* Re: [PATCH v1 16/16] dma-mapping: Disallow .map_sg operations from returning zero on error
From: Robin Murphy @ 2021-07-16 12:19 UTC (permalink / raw)
To: Christoph Hellwig, Logan Gunthorpe
Cc: linux-s390, linux-ia64, linux-parisc, linux-kernel,
Martin Oliveira, Stephen Bates, iommu, linux-alpha, sparclinux,
xen-devel, linux-mips, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20210716063332.GD13345@lst.de>
On 2021-07-16 07:33, Christoph Hellwig wrote:
> On Thu, Jul 15, 2021 at 10:45:44AM -0600, Logan Gunthorpe wrote:
>> @@ -194,6 +194,8 @@ static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
>> else
>> ents = ops->map_sg(dev, sg, nents, dir, attrs);
>>
>> + WARN_ON_ONCE(ents == 0);
>
> Turns this into a negative error code while we're at it, just to keep
> the callers sane?
Right, by this point returning the 0 would pass through
dma_map_sg_attrs() OK, but AFAICS dma_map_sgtable() would now get
confused and return success but with sgt->nents = 0. Coercing it to an
error code (which dma_map_sg_attrs() would then just change right back)
seems sensible for the sake of easy robustness.
Robin.
^ permalink raw reply
* Re: [PATCH v1 14/16] x86/amd_gart: return error code from gart_map_sg()
From: Robin Murphy @ 2021-07-16 12:11 UTC (permalink / raw)
To: Christoph Hellwig, Logan Gunthorpe
Cc: linux-s390, Thomas Bogendoerfer, linux-ia64, linux-parisc,
Niklas Schnelle, H. Peter Anvin, linux-mips, linux-kernel, iommu,
Ingo Molnar, Borislav Petkov, linux-alpha, sparclinux, xen-devel,
Thomas Gleixner, Stephen Bates, linuxppc-dev, Martin Oliveira,
linux-arm-kernel, Marek Szyprowski
In-Reply-To: <20210716063241.GC13345@lst.de>
On 2021-07-16 07:32, Christoph Hellwig wrote:
> On Thu, Jul 15, 2021 at 10:45:42AM -0600, Logan Gunthorpe wrote:
>> @@ -458,7 +460,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
>> iommu_full(dev, pages << PAGE_SHIFT, dir);
>> for_each_sg(sg, s, nents, i)
>> s->dma_address = DMA_MAPPING_ERROR;
>> - return 0;
>> + return ret;
>
> While we're at it - setting the ->dma_address to DMA_MAPPING_ERROR is
> not part of the ->map_sg calling convention. Might be worth to fix
> up while we're at it.
Especially since it's not even zeroing dma_length, which at least is a
documented indicator of validity (even if it's not strictly defined for
failure cases either).
Robin.
^ permalink raw reply
* [PATCH v5 11/11] powerpc/pseries/iommu: Rename "direct window" to "dma window"
From: Leonardo Bras @ 2021-07-16 8:27 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Leonardo Bras, Alexey Kardashevskiy, David Gibson,
kernel test robot, Nicolin Chen, Frederic Barrat
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20210716082755.428187-1-leobras.c@gmail.com>
A previous change introduced the usage of DDW as a bigger indirect DMA
mapping when the DDW available size does not map the whole partition.
As most of the code that manipulates direct mappings was reused for
indirect mappings, it's necessary to rename all names and debug/info
messages to reflect that it can be used for both kinds of mapping.
This should cause no behavioural change, just adjust naming.
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
---
arch/powerpc/platforms/pseries/iommu.c | 91 +++++++++++++-------------
1 file changed, 47 insertions(+), 44 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index a67e71c49aeb..52548dfb8b45 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -349,7 +349,7 @@ struct dynamic_dma_window_prop {
__be32 window_shift; /* ilog2(tce_window_size) */
};
-struct direct_window {
+struct dma_win {
struct device_node *device;
const struct dynamic_dma_window_prop *prop;
struct list_head list;
@@ -369,11 +369,11 @@ struct ddw_create_response {
u32 addr_lo;
};
-static LIST_HEAD(direct_window_list);
+static LIST_HEAD(dma_win_list);
/* prevents races between memory on/offline and window creation */
-static DEFINE_SPINLOCK(direct_window_list_lock);
+static DEFINE_SPINLOCK(dma_win_list_lock);
/* protects initializing window twice for same device */
-static DEFINE_MUTEX(direct_window_init_mutex);
+static DEFINE_MUTEX(dma_win_init_mutex);
#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info"
#define DMA64_PROPNAME "linux,dma64-ddr-window-info"
@@ -713,7 +713,10 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n",
dn);
- /* Find nearest ibm,dma-window, walking up the device tree */
+ /*
+ * Find nearest ibm,dma-window (default DMA window), walking up the
+ * device tree
+ */
for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
if (dma_window != NULL)
@@ -822,11 +825,11 @@ static void remove_dma_window(struct device_node *np, u32 *ddw_avail,
ret = rtas_call(ddw_avail[DDW_REMOVE_PE_DMA_WIN], 1, 1, NULL, liobn);
if (ret)
- pr_warn("%pOF: failed to remove direct window: rtas returned "
+ pr_warn("%pOF: failed to remove DMA window: rtas returned "
"%d to ibm,remove-pe-dma-window(%x) %llx\n",
np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], liobn);
else
- pr_debug("%pOF: successfully removed direct window: rtas returned "
+ pr_debug("%pOF: successfully removed DMA window: rtas returned "
"%d to ibm,remove-pe-dma-window(%x) %llx\n",
np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], liobn);
}
@@ -854,37 +857,37 @@ static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_
ret = of_remove_property(np, win);
if (ret)
- pr_warn("%pOF: failed to remove direct window property: %d\n",
+ pr_warn("%pOF: failed to remove DMA window property: %d\n",
np, ret);
return 0;
}
static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift)
{
- struct direct_window *window;
- const struct dynamic_dma_window_prop *direct64;
+ struct dma_win *window;
+ const struct dynamic_dma_window_prop *dma64;
bool found = false;
- spin_lock(&direct_window_list_lock);
+ spin_lock(&dma_win_list_lock);
/* check if we already created a window and dupe that config if so */
- list_for_each_entry(window, &direct_window_list, list) {
+ list_for_each_entry(window, &dma_win_list, list) {
if (window->device == pdn) {
- direct64 = window->prop;
- *dma_addr = be64_to_cpu(direct64->dma_base);
- *window_shift = be32_to_cpu(direct64->window_shift);
+ dma64 = window->prop;
+ *dma_addr = be64_to_cpu(dma64->dma_base);
+ *window_shift = be32_to_cpu(dma64->window_shift);
found = true;
break;
}
}
- spin_unlock(&direct_window_list_lock);
+ spin_unlock(&dma_win_list_lock);
return found;
}
-static struct direct_window *ddw_list_new_entry(struct device_node *pdn,
- const struct dynamic_dma_window_prop *dma64)
+static struct dma_win *ddw_list_new_entry(struct device_node *pdn,
+ const struct dynamic_dma_window_prop *dma64)
{
- struct direct_window *window;
+ struct dma_win *window;
window = kzalloc(sizeof(*window), GFP_KERNEL);
if (!window)
@@ -900,7 +903,7 @@ static void find_existing_ddw_windows_named(const char *name)
{
int len;
struct device_node *pdn;
- struct direct_window *window;
+ struct dma_win *window;
const struct dynamic_dma_window_prop *dma64;
for_each_node_with_property(pdn, name) {
@@ -914,9 +917,9 @@ static void find_existing_ddw_windows_named(const char *name)
if (!window)
break;
- spin_lock(&direct_window_list_lock);
- list_add(&window->list, &direct_window_list);
- spin_unlock(&direct_window_list_lock);
+ spin_lock(&dma_win_list_lock);
+ list_add(&window->list, &dma_win_list);
+ spin_unlock(&dma_win_list_lock);
}
}
@@ -1216,7 +1219,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
const char *win_name;
struct device_node *dn;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
- struct direct_window *window;
+ struct dma_win *window;
struct property *win64;
bool ddw_enabled = false;
struct failed_ddw_pdn *fpdn;
@@ -1229,7 +1232,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
pmem_present = dn != NULL;
of_node_put(dn);
- mutex_lock(&direct_window_init_mutex);
+ mutex_lock(&dma_win_init_mutex);
if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
direct_mapping = (len >= max_ram_len);
@@ -1309,8 +1312,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
page_shift = iommu_get_page_shift(query.page_size);
if (!page_shift) {
- dev_dbg(&dev->dev, "no supported direct page size in mask %x",
- query.page_size);
+ dev_dbg(&dev->dev, "no supported page size in mask %x",
+ query.page_size);
goto out_failed;
}
@@ -1367,7 +1370,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
ret = of_add_property(pdn, win64);
if (ret) {
- dev_err(&dev->dev, "unable to add dma window property for %pOF: %d",
+ dev_err(&dev->dev, "unable to add DMA window property for %pOF: %d",
pdn, ret);
goto out_free_prop;
}
@@ -1381,7 +1384,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
win64->value, tce_setrange_multi_pSeriesLP_walk);
if (ret) {
- dev_info(&dev->dev, "failed to map direct window for %pOF: %d\n",
+ dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n",
dn, ret);
goto out_del_list;
}
@@ -1423,9 +1426,9 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
set_iommu_table_base(&dev->dev, newtbl);
}
- spin_lock(&direct_window_list_lock);
- list_add(&window->list, &direct_window_list);
- spin_unlock(&direct_window_list_lock);
+ spin_lock(&dma_win_list_lock);
+ list_add(&window->list, &dma_win_list);
+ spin_unlock(&dma_win_list_lock);
dev->dev.archdata.dma_offset = win_addr;
ddw_enabled = true;
@@ -1456,7 +1459,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
list_add(&fpdn->list, &failed_ddw_pdn_list);
out_unlock:
- mutex_unlock(&direct_window_init_mutex);
+ mutex_unlock(&dma_win_init_mutex);
/*
* If we have persistent memory and the window size is only as big
@@ -1554,29 +1557,29 @@ static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 dma_mask)
static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
- struct direct_window *window;
+ struct dma_win *window;
struct memory_notify *arg = data;
int ret = 0;
switch (action) {
case MEM_GOING_ONLINE:
- spin_lock(&direct_window_list_lock);
- list_for_each_entry(window, &direct_window_list, list) {
+ spin_lock(&dma_win_list_lock);
+ list_for_each_entry(window, &dma_win_list, list) {
ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn,
arg->nr_pages, window->prop);
/* XXX log error */
}
- spin_unlock(&direct_window_list_lock);
+ spin_unlock(&dma_win_list_lock);
break;
case MEM_CANCEL_ONLINE:
case MEM_OFFLINE:
- spin_lock(&direct_window_list_lock);
- list_for_each_entry(window, &direct_window_list, list) {
+ spin_lock(&dma_win_list_lock);
+ list_for_each_entry(window, &dma_win_list, list) {
ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn,
arg->nr_pages, window->prop);
/* XXX log error */
}
- spin_unlock(&direct_window_list_lock);
+ spin_unlock(&dma_win_list_lock);
break;
default:
break;
@@ -1597,7 +1600,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
struct of_reconfig_data *rd = data;
struct device_node *np = rd->dn;
struct pci_dn *pci = PCI_DN(np);
- struct direct_window *window;
+ struct dma_win *window;
switch (action) {
case OF_RECONFIG_DETACH_NODE:
@@ -1615,15 +1618,15 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
iommu_pseries_free_group(pci->table_group,
np->full_name);
- spin_lock(&direct_window_list_lock);
- list_for_each_entry(window, &direct_window_list, list) {
+ spin_lock(&dma_win_list_lock);
+ list_for_each_entry(window, &dma_win_list, list) {
if (window->device == np) {
list_del(&window->list);
kfree(window);
break;
}
}
- spin_unlock(&direct_window_list_lock);
+ spin_unlock(&dma_win_list_lock);
break;
default:
err = NOTIFY_DONE;
--
2.32.0
^ permalink raw reply related
* [PATCH v5 10/11] powerpc/pseries/iommu: Make use of DDW for indirect mapping
From: Leonardo Bras @ 2021-07-16 8:27 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Leonardo Bras, Alexey Kardashevskiy, David Gibson,
kernel test robot, Nicolin Chen, Frederic Barrat
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20210716082755.428187-1-leobras.c@gmail.com>
So far it's assumed possible to map the guest RAM 1:1 to the bus, which
works with a small number of devices. SRIOV changes it as the user can
configure hundreds VFs and since phyp preallocates TCEs and does not
allow IOMMU pages bigger than 64K, it has to limit the number of TCEs
per a PE to limit waste of physical pages.
As of today, if the assumed direct mapping is not possible, DDW creation
is skipped and the default DMA window "ibm,dma-window" is used instead.
By using DDW, indirect mapping can get more TCEs than available for the
default DMA window, and also get access to using much larger pagesizes
(16MB as implemented in qemu vs 4k from default DMA window), causing a
significant increase on the maximum amount of memory that can be IOMMU
mapped at the same time.
Indirect mapping will only be used if direct mapping is not a
possibility.
For indirect mapping, it's necessary to re-create the iommu_table with
the new DMA window parameters, so iommu_alloc() can use it.
Removing the default DMA window for using DDW with indirect mapping
is only allowed if there is no current IOMMU memory allocated in
the iommu_table. enable_ddw() is aborted otherwise.
Even though there won't be both direct and indirect mappings at the
same time, we can't reuse the DIRECT64_PROPNAME property name, or else
an older kexec()ed kernel can assume direct mapping, and skip
iommu_alloc(), causing undesirable behavior.
So a new property name DMA64_PROPNAME "linux,dma64-ddr-window-info"
was created to represent a DDW that does not allow direct mapping.
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
---
arch/powerpc/platforms/pseries/iommu.c | 87 +++++++++++++++++++++-----
1 file changed, 72 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 22d251e15b61..a67e71c49aeb 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -375,6 +375,7 @@ static DEFINE_SPINLOCK(direct_window_list_lock);
/* protects initializing window twice for same device */
static DEFINE_MUTEX(direct_window_init_mutex);
#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info"
+#define DMA64_PROPNAME "linux,dma64-ddr-window-info"
static int tce_clearrange_multi_pSeriesLP(unsigned long start_pfn,
unsigned long num_pfn, const void *arg)
@@ -925,6 +926,7 @@ static int find_existing_ddw_windows(void)
return 0;
find_existing_ddw_windows_named(DIRECT64_PROPNAME);
+ find_existing_ddw_windows_named(DMA64_PROPNAME);
return 0;
}
@@ -1211,14 +1213,17 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
struct ddw_create_response create;
int page_shift;
u64 win_addr;
+ const char *win_name;
struct device_node *dn;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
struct direct_window *window;
struct property *win64;
bool ddw_enabled = false;
struct failed_ddw_pdn *fpdn;
- bool default_win_removed = false;
+ bool default_win_removed = false, direct_mapping = false;
bool pmem_present;
+ struct pci_dn *pci = PCI_DN(pdn);
+ struct iommu_table *tbl = pci->table_group->tables[0];
dn = of_find_node_by_type(NULL, "ibm,pmemory");
pmem_present = dn != NULL;
@@ -1227,6 +1232,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
mutex_lock(&direct_window_init_mutex);
if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
+ direct_mapping = (len >= max_ram_len);
ddw_enabled = true;
goto out_unlock;
}
@@ -1307,8 +1313,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
query.page_size);
goto out_failed;
}
- /* verify the window * number of ptes will map the partition */
- /* check largest block * page size > max memory hotplug addr */
+
/*
* The "ibm,pmemory" can appear anywhere in the address space.
* Assuming it is still backed by page structs, try MAX_PHYSMEM_BITS
@@ -1324,13 +1329,25 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
dev_info(&dev->dev, "Skipping ibm,pmemory");
}
+ /* check if the available block * number of ptes will map everything */
if (query.largest_available_block < (1ULL << (len - page_shift))) {
dev_dbg(&dev->dev,
"can't map partition max 0x%llx with %llu %llu-sized pages\n",
1ULL << len,
query.largest_available_block,
1ULL << page_shift);
- goto out_failed;
+
+ /* DDW + IOMMU on single window may fail if there is any allocation */
+ if (default_win_removed && iommu_table_in_use(tbl)) {
+ dev_dbg(&dev->dev, "current IOMMU table in use, can't be replaced.\n");
+ goto out_failed;
+ }
+
+ len = order_base_2(query.largest_available_block << page_shift);
+ win_name = DMA64_PROPNAME;
+ } else {
+ direct_mapping = true;
+ win_name = DIRECT64_PROPNAME;
}
ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
@@ -1341,8 +1358,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
create.liobn, dn);
win_addr = ((u64)create.addr_hi << 32) | create.addr_lo;
- win64 = ddw_property_create(DIRECT64_PROPNAME, create.liobn, win_addr,
- page_shift, len);
+ win64 = ddw_property_create(win_name, create.liobn, win_addr, page_shift, len);
if (!win64) {
dev_info(&dev->dev,
"couldn't allocate property, property name, or value\n");
@@ -1360,12 +1376,51 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
if (!window)
goto out_del_prop;
- ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
- win64->value, tce_setrange_multi_pSeriesLP_walk);
- if (ret) {
- dev_info(&dev->dev, "failed to map direct window for %pOF: %d\n",
- dn, ret);
- goto out_del_list;
+ if (direct_mapping) {
+ /* DDW maps the whole partition, so enable direct DMA mapping */
+ ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
+ win64->value, tce_setrange_multi_pSeriesLP_walk);
+ if (ret) {
+ dev_info(&dev->dev, "failed to map direct window for %pOF: %d\n",
+ dn, ret);
+ goto out_del_list;
+ }
+ } else {
+ struct iommu_table *newtbl;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pci->phb->mem_resources); i++) {
+ const unsigned long mask = IORESOURCE_MEM_64 | IORESOURCE_MEM;
+
+ /* Look for MMIO32 */
+ if ((pci->phb->mem_resources[i].flags & mask) == IORESOURCE_MEM)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(pci->phb->mem_resources))
+ goto out_del_list;
+
+ /* New table for using DDW instead of the default DMA window */
+ newtbl = iommu_pseries_alloc_table(pci->phb->node);
+ if (!newtbl) {
+ dev_dbg(&dev->dev, "couldn't create new IOMMU table\n");
+ goto out_del_list;
+ }
+
+ iommu_table_setparms_common(newtbl, pci->phb->bus->number, create.liobn, win_addr,
+ 1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops);
+ iommu_init_table(newtbl, pci->phb->node, pci->phb->mem_resources[i].start,
+ pci->phb->mem_resources[i].end);
+
+ pci->table_group->tables[1] = newtbl;
+
+ /* Keep default DMA window stuct if removed */
+ if (default_win_removed) {
+ tbl->it_size = 0;
+ kfree(tbl->it_map);
+ }
+
+ set_iommu_table_base(&dev->dev, newtbl);
}
spin_lock(&direct_window_list_lock);
@@ -1408,10 +1463,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
* as RAM, then we failed to create a window to cover persistent
* memory and need to set the DMA limit.
*/
- if (pmem_present && ddw_enabled && (len == max_ram_len))
+ if (pmem_present && ddw_enabled && direct_mapping && len == max_ram_len)
dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + (1ULL << len);
- return ddw_enabled;
+ return ddw_enabled && direct_mapping;
}
static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
@@ -1553,7 +1608,9 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
* we have to remove the property when releasing
* the device node.
*/
- remove_ddw(np, false, DIRECT64_PROPNAME);
+ if (remove_ddw(np, false, DIRECT64_PROPNAME))
+ remove_ddw(np, false, DMA64_PROPNAME);
+
if (pci && pci->table_group)
iommu_pseries_free_group(pci->table_group,
np->full_name);
--
2.32.0
^ permalink raw reply related
* [PATCH v5 09/11] powerpc/pseries/iommu: Find existing DDW with given property name
From: Leonardo Bras @ 2021-07-16 8:27 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Leonardo Bras, Alexey Kardashevskiy, David Gibson,
kernel test robot, Nicolin Chen, Frederic Barrat
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20210716082755.428187-1-leobras.c@gmail.com>
At the moment pseries stores information about created directly mapped
DDW window in DIRECT64_PROPNAME.
With the objective of implementing indirect DMA mapping with DDW, it's
necessary to have another propriety name to make sure kexec'ing into older
kernels does not break, as it would if we reuse DIRECT64_PROPNAME.
In order to have this, find_existing_ddw_windows() needs to be able to
look for different property names.
Extract find_existing_ddw_windows() into find_existing_ddw_windows_named()
and calls it with current property name.
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
arch/powerpc/platforms/pseries/iommu.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 17c6f4706e76..22d251e15b61 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -895,24 +895,21 @@ static struct direct_window *ddw_list_new_entry(struct device_node *pdn,
return window;
}
-static int find_existing_ddw_windows(void)
+static void find_existing_ddw_windows_named(const char *name)
{
int len;
struct device_node *pdn;
struct direct_window *window;
- const struct dynamic_dma_window_prop *direct64;
-
- if (!firmware_has_feature(FW_FEATURE_LPAR))
- return 0;
+ const struct dynamic_dma_window_prop *dma64;
- for_each_node_with_property(pdn, DIRECT64_PROPNAME) {
- direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
- if (!direct64 || len < sizeof(*direct64)) {
- remove_ddw(pdn, true, DIRECT64_PROPNAME);
+ for_each_node_with_property(pdn, name) {
+ dma64 = of_get_property(pdn, name, &len);
+ if (!dma64 || len < sizeof(*dma64)) {
+ remove_ddw(pdn, true, name);
continue;
}
- window = ddw_list_new_entry(pdn, direct64);
+ window = ddw_list_new_entry(pdn, dma64);
if (!window)
break;
@@ -920,6 +917,14 @@ static int find_existing_ddw_windows(void)
list_add(&window->list, &direct_window_list);
spin_unlock(&direct_window_list_lock);
}
+}
+
+static int find_existing_ddw_windows(void)
+{
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
+ return 0;
+
+ find_existing_ddw_windows_named(DIRECT64_PROPNAME);
return 0;
}
--
2.32.0
^ permalink raw reply related
* [PATCH v5 08/11] powerpc/pseries/iommu: Update remove_dma_window() to accept property name
From: Leonardo Bras @ 2021-07-16 8:27 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Leonardo Bras, Alexey Kardashevskiy, David Gibson,
kernel test robot, Nicolin Chen, Frederic Barrat
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20210716082755.428187-1-leobras.c@gmail.com>
Update remove_dma_window() so it can be used to remove DDW with a given
property name.
This enables the creation of new property names for DDW, so we can
have different usage for it, like indirect mapping.
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
arch/powerpc/platforms/pseries/iommu.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 108c3dcca686..17c6f4706e76 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -830,31 +830,32 @@ static void remove_dma_window(struct device_node *np, u32 *ddw_avail,
np, ret, ddw_avail[DDW_REMOVE_PE_DMA_WIN], liobn);
}
-static void remove_ddw(struct device_node *np, bool remove_prop)
+static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_name)
{
struct property *win;
u32 ddw_avail[DDW_APPLICABLE_SIZE];
int ret = 0;
+ win = of_find_property(np, win_name, NULL);
+ if (!win)
+ return -EINVAL;
+
ret = of_property_read_u32_array(np, "ibm,ddw-applicable",
&ddw_avail[0], DDW_APPLICABLE_SIZE);
if (ret)
- return;
-
- win = of_find_property(np, DIRECT64_PROPNAME, NULL);
- if (!win)
- return;
+ return 0;
if (win->length >= sizeof(struct dynamic_dma_window_prop))
remove_dma_window(np, ddw_avail, win);
if (!remove_prop)
- return;
+ return 0;
ret = of_remove_property(np, win);
if (ret)
pr_warn("%pOF: failed to remove direct window property: %d\n",
np, ret);
+ return 0;
}
static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift)
@@ -907,7 +908,7 @@ static int find_existing_ddw_windows(void)
for_each_node_with_property(pdn, DIRECT64_PROPNAME) {
direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
if (!direct64 || len < sizeof(*direct64)) {
- remove_ddw(pdn, true);
+ remove_ddw(pdn, true, DIRECT64_PROPNAME);
continue;
}
@@ -1382,7 +1383,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
kfree(win64);
out_remove_win:
- remove_ddw(pdn, true);
+ remove_ddw(pdn, true, DIRECT64_PROPNAME);
out_failed:
if (default_win_removed)
@@ -1547,7 +1548,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
* we have to remove the property when releasing
* the device node.
*/
- remove_ddw(np, false);
+ remove_ddw(np, false, DIRECT64_PROPNAME);
if (pci && pci->table_group)
iommu_pseries_free_group(pci->table_group,
np->full_name);
--
2.32.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox