* Re: [PATCH 4/4] KVM: PPC: Bookehv: Get vcpu's last instruction for emulation
From: Alexander Graf @ 2014-04-01 17:11 UTC (permalink / raw)
To: Scott Wood
Cc: Mihai Caraman, <linuxppc-dev@lists.ozlabs.org>,
<kvm@vger.kernel.org>, <kvm-ppc@vger.kernel.org>
In-Reply-To: <1396371496.20849.51.camel@snotra.buserror.net>
On 04/01/2014 06:58 PM, Scott Wood wrote:
> On Tue, 2014-04-01 at 07:47 +0200, Alexander Graf wrote:
>>> Am 01.04.2014 um 01:03 schrieb Scott Wood <scottwood@freescale.com>:
>>>
>>>> On Mon, 2014-03-31 at 15:41 +0200, Alexander Graf wrote:
>>>>> On 03/26/2014 10:17 PM, Scott Wood wrote:
>>>>>> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
>>>>>> + /*
>>>>>> + * Another thread may rewrite the TLB entry in parallel, don't
>>>>>> + * execute from the address if the execute permission is not set
>>>>>> + */
>>>> What happens when another thread rewrites the TLB entry in parallel?
>>>> Does tlbsx succeed? Does it fail? Do we see failure indicated somehow?
>>>> Are the contents of the MAS registers consistent at this point or
>>>> inconsistent?
>>> If another thread rewrites the TLB entry, then we use the new TLB entry,
>>> just as if it had raced in hardware. This check ensures that we don't
>>> execute from the new TLB entry if it doesn't have execute permissions
>>> (just as hardware would).
>>>
>>> What happens if the new TLB entry is valid and executable, and the
>>> instruction pointed to is valid, but doesn't trap (and thus we don't
>>> have emulation for it)?
>>>
>>>> There has to be a good way to detect such a race and deal with it, no?
>>> How would you detect it? We don't get any information from the trap
>>> about what physical address the instruction was fetched from, or what
>>> the instruction was.
>> Ah, this is a guest race where the guest modifies exactly the TLB in question. I see.
>>
>> Why would this ever happen in practice (in a case where we're not executing malicious code)?
> I don't know. It probably wouldn't. But it seems wrong to not check
> the exec bit.
Right, I'm just saying that a program interrupt is not too bad of an
answer in case the guest does something as stupid as this in kernel
space :). It's definitely good practice to check for the exec bit.
Alex
^ permalink raw reply
* Re: [PATCH 2/2] Make the diu driver work without board level initilization
From: Scott Wood @ 2014-04-01 21:38 UTC (permalink / raw)
To: Jin Zhengxiong-R64188
Cc: linux-fbdev@vger.kernel.org, Xiubo Li-B47053,
linuxppc-dev@lists.ozlabs.org, timur@tabi.org
In-Reply-To: <57b9d96d00f64eff90ae6c109c9dec90@BLUPR03MB373.namprd03.prod.outlook.com>
On Tue, 2014-04-01 at 02:28 -0500, Jin Zhengxiong-R64188 wrote:
> > > + if (!diu_ops.set_pixel_clock) {
> > > + data->pixelclk_reg = of_iomap(np, 1);
> > > + if (!data->pixelclk_reg) {
> > > + dev_err(&pdev->dev, "Cannot map pixelclk registers,
> > please \
> > > + provide the diu_ops for pixclk setting
> > instead.\n");
> >
> > The error message should be in one line if possible, or it will hard to
> > grep.
> > If cannot, should split it into two or more lines, like:
> > + dev_err(&pdev->dev, "Cannot map pixelclk registers,\n"
> > + "please provide the diu_ops for pixclk setting
> > instead.\n");
> Thanks, This has been fixed in the update version, please help to review it at:
> http://patchwork.ozlabs.org/patch/335225/
> I forgot to add the V2 information in the subject in the update patch so this may confuse the reviewer, sorry for that.
It is not fixed in that patch (or did you link the wrong version?). You
should never use \ to continue a line in C, other than in macros.
Further, it is not permitted to wrap kernel output strings. This is an
exception to the 80-column rule. Checkpatch should have told you this.
-Scott
^ permalink raw reply
* Re: [PATCH 1/3] powerpc/fsl-booke: Add support for T2080/T2081 SoC
From: Scott Wood @ 2014-04-01 21:42 UTC (permalink / raw)
To: Shengzhou Liu; +Cc: linuxppc-dev
In-Reply-To: <1393840220-31086-1-git-send-email-Shengzhou.Liu@freescale.com>
On Mon, 2014-03-03 at 17:50 +0800, Shengzhou Liu wrote:
> + corenet-cf@18000 {
> + compatible = "fsl,corenet-cf";
> + reg = <0x18000 0x1000>;
> + interrupts = <16 2 1 31>;
> + fsl,ccf-num-csdids = <32>;
> + fsl,ccf-num-snoopids = <32>;
> + };
This is not compatible with "fsl,corenet-cf".
> + clockgen: global-utilities@e1000 {
> + compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0";
> + reg = <0xe1000 0x1000>;
> + };
See Documentation/devicetree/bindings/clock/corenet-clock.txt
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + /*
> + * Temporarily add next-level-cache info in each cpu node so
> + * that uboot can do L2 cache fixup. This can be removed once
> + * u-boot can create cpu node with cache info.
> + */
Is there a reason why this is temporary? What do we gain from U-Boot
doing the fixup? Is U-Boot doing the rest of the fixup (adding ePAPR
properties to the L2 cache nodes)?
-Scott
^ permalink raw reply
* Re: [PATCH REPOST v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Rafael J. Wysocki @ 2014-04-01 22:03 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Gautham R. Shenoy, Linux PM list, Viresh Kumar, linux-kernel,
cpufreq, linuxppc-dev, Anton Blanchard, srivatsa.bhat
In-Reply-To: <1396345609.28055.7.camel@pasglop>
On Tuesday, April 01, 2014 08:46:49 PM Benjamin Herrenschmidt wrote:
> On Tue, 2014-04-01 at 12:43 +0530, Gautham R. Shenoy wrote:
> > From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
> >
> > Enable CPUFreq for PowerNV. Select "performance", "powersave",
> > "userspace" and "ondemand" governors. Choose "ondemand" to be the
> > default governor.
>
> Rafael, are you going to take these or should I send them to Linus ?
>
> (I'd rather you take them :-)
I can do that, but the timing is pretty bad. How urgent are they?
Rafael
^ permalink raw reply
* Re: [PATCH 2/3] powerpc/fsl-booke: Add initial T208x QDS board support
From: Scott Wood @ 2014-04-01 21:47 UTC (permalink / raw)
To: Shengzhou Liu; +Cc: linuxppc-dev
In-Reply-To: <1393840220-31086-2-git-send-email-Shengzhou.Liu@freescale.com>
On Mon, 2014-03-03 at 17:50 +0800, Shengzhou Liu wrote:
> + dcsr: dcsr@f00000000 {
> + ranges = <0x00000000 0xf 0x00000000 0x01072000>;
> + };
This is a very odd size -- where did it come from?
-Scott
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-04-01 23:34 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
This time around, the powerpc merges are going to be a little bit
more complicated than usual.
This is the main pull request with most of the work for this merge
window. I will describe it a bit more further down.
There is some additional cpuidle driver work, however I haven't included
it in this tree as it depends on some work in tip/timer-core which
Thomas accidentally forgot to put in a topic branch. Since I didn't want
to carry all of that tip timer stuff in powerpc -next, I setup a
separate branch on top of Thomas tree with just that cpuidle driver in
it, and Stephen has been carrying that in next separately for a while
now. I'll send a separate pull request for it.
Additionally, two new pieces in this tree add users for a sysfs API
that Tejun and Greg have been deprecating in drivers-core-next.
Thankfully Greg reverted the patch that removes the old API so this
merge can happen cleanly, but once merged, I will send a patch adjusting
our new code to the new API so that Greg can send you the removal patch.
Now as for the content of this branch, we have a lot of perf work for
power8 new counters including support for our new "nest" counters
(also called 24x7) under pHyp (not natively yet).
We have new functionality when running under the OPAL firmware
(non-virtualized or KVM host), such as access to the firmware error logs
and service processor dumps, system parameters and sensors, along with
a hwmon driver for the latter.
There's also a bunch of bug fixes accross the board, some LE fixes,
and a nice set of selftests for validating our various types of
copy loops.
On the Freescale side, we see mostly new chip/board revisions, some
clock updates, better support for machine checks and debug exceptions,
etc...
Cheers,
Ben.
The following changes since commit a5b2cf5b1af424ee3dd9e3ce6d5cea18cb927e67:
powerpc: Align p_dyn, p_rela and p_st symbols (2014-03-07 13:50:19 +1100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
for you to fetch changes up to cd427485357c0c4b99f69719251baacf25946e11:
Merge remote-tracking branch 'scott/next' into next (2014-03-24 10:26:10 +1100)
----------------------------------------------------------------
Aneesh Kumar K.V (2):
powerpc/mm: Make sure a local_irq_disable prevent a parallel THP split
powerpc/defconfigs: Enable THP in pseries defconfig
Anshuman Khandual (2):
powerpc/perf: Make some new raw event codes available in sysfs
powerpc/perf: Define perf_event_print_debug() to print PMU register values
Anton Blanchard (2):
powerpc: Use default set of netfilter modules (CONFIG_NETFILTER_ADVANCED=n)
powerpc/compat: 32-bit little endian machine name is ppcle, not ppc
Benjamin Herrenschmidt (2):
powerpc/pseries: Don't try to register pseries cpu hotplug on non-pseries
Merge remote-tracking branch 'scott/next' into next
Benjamin Krill (1):
powerpc/book3e: Fix check for linear mapping in TLB miss handler
Brandon Stewart (1):
macintosh/adb: Fixed some coding style problems
Cody P Schafer (10):
sysfs: create bin_attributes under the requested group
powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info)
powerpc/perf: Add hv_gpci interface header
powerpc/perf: Add 24x7 interface headers
powerpc/perf: Add a shared interface to get gpci version and capabilities
powerpc/perf: Add macros for defining event fields & formats
powerpc/perf: Add support for the hv gpci (get performance counter info) interface
powerpc/perf: Add support for the hv 24x7 interface
powerpc/perf: Add kconfig option for hypervisor provided counters
powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes
Greg Kurz (1):
powerpc/le: Big endian arguments for ppc_rtas()
Haren Myneni (2):
powerpc/pseries: Device tree should only be updated once after suspend/migrate
powerpc/pseries: Update dynamic cache nodes for suspend/resume operation
Josh Boyer (1):
powerpc: Update ppc4xx maintainer
Li Zhong (1):
powerpc: Revert c6102609 and replace it with the correct fix for vio dma mask setting
Luis Henriques (1):
powerpc/kconfig: Remove TSI108_BRIDGE duplicates
Mahesh Salgaonkar (2):
powerpc/book3s: Recover from MC in sapphire on SCOM read via MMIO.
powerpc/book3s: Fix CFAR clobbering issue in machine check handler.
Michael Ellerman (9):
selftests/powerpc: Import Anton's memcpy / copy_tofrom_user tests
powerpc: Add a cpu feature CPU_FTR_PMAO_BUG
powerpc/perf: Add lost exception workaround
powerpc/perf: Reject EBB events which specify a sample_type
powerpc/perf: Clean up the EBB hash defines a little
powerpc/perf: Avoid mutating event in power8_get_constraint()
powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
powerpc/perf: Enable BHRB access for EBB events
powerpc/perf: Fix handling of L3 events with bank == 1
Michael Neuling (1):
powerpc: Rate-limit users spamming kernel log buffer
Minghuan Lian (1):
powerpc/pci: Fix IMMRBAR address
Nathan Fontenot (1):
powerpc/pseries: Use remove_memory() to remove memory
Neelesh Gupta (3):
powerpc/powernv: Infrastructure to support OPAL async completion
powerpc/powernv: Enable reading and updating of system parameters
powerpc/powernv: Enable fetching of platform sensor data
Paul Gortmaker (1):
powerpc: Delete old PrPMC 280/2800 support
Philippe Bergheaud (1):
powerpc: Fix xmon disassembler for little-endian
Prabhakar Kushwaha (1):
powerpc/config: Remove unnecssary CONFIG_FSL_IFC
Scott Wood (8):
powerpc/booke64: Fix exception numbers
powerpc/e6500: Make TLB lock recursive
powerpc/booke64: Use SPRG7 for VDSO
powerpc/booke64: Use SPRG_TLB_EXFRAME on bolted handlers
powerpc/booke64: Remove ints from EXCEPTION_COMMON
powerpc/booke64: Add crit/mc/debug support to EXCEPTION_COMMON
powerpc/booke64: Critical and machine check exception support
Revert "powerpc/watchdog: Don't enable interrupt on PPC64 BookE"
Sebastian Siewior (2):
powerpc: Add "force config cmd line" Kconfig option
powerpc: 85xx rdb: move np pointer to avoid builderror
Shivaprasad G Bhat (1):
powerpc/powernv: hwmon driver for power values, fan rpm and temperature
Shuah Khan (1):
macintosh/adb: Change platform power management to use dev_pm_ops
Stewart Smith (2):
powerpc/powernv: Read OPAL error log and export it through sysfs
powerpc/powernv Platform dump interface
Tang Yuantian (2):
powerpc/mpc85xx: Update clock nodes in device tree
powerpc: T4240: Add ina220 node in dts
Tiejun Chen (2):
powerpc/book3e: initialize crit/mc/dbg kernel stack pointers
powerpc/book3e: store crit/mc/dbg exception thread info
Tyrel Datwyler (1):
powerpc/pseries: Expose in kernel device tree update to drmgr
Wang Dongsheng (2):
powerpc/fsl: add PVR definition for E500MC and E5500
fsl/pci: The new pci suspend/resume implementation
Zhao Qiang (2):
QE: split function mpc85xx_qe_init() into two functions.
Corenet: Add QE platform support for Corenet
harninder rai (1):
powerpc/fsl: Add/update miscellaneous missing binding
송은봉 (1):
powerpc: : Kill CONFIG_MTD_PARTITIONS
Documentation/ABI/stable/sysfs-firmware-opal-dump | 41 ++
Documentation/ABI/stable/sysfs-firmware-opal-elog | 60 +++
.../testing/sysfs-bus-event_source-devices-events | 517 ++++++++++++++++++++
.../testing/sysfs-bus-event_source-devices-hv_24x7 | 23 +
.../testing/sysfs-bus-event_source-devices-hv_gpci | 43 ++
.../devicetree/bindings/powerpc/fsl/l2cache.txt | 23 +
.../devicetree/bindings/powerpc/fsl/mem-ctrlr.txt | 27 ++
Documentation/devicetree/bindings/usb/fsl-usb.txt | 4 +-
MAINTAINERS | 3 +-
arch/powerpc/Kconfig | 9 +
arch/powerpc/boot/Makefile | 5 +-
arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | 36 ++
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi | 2 +
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | 36 ++
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | 60 +++
arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | 61 +++
arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | 113 +++++
arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi | 8 +
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 43 ++
arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 2 +
arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | 61 +++
arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 86 ++++
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | 12 +
arch/powerpc/boot/dts/t4240qds.dts | 42 ++
arch/powerpc/configs/40x/acadia_defconfig | 1 -
arch/powerpc/configs/40x/ep405_defconfig | 1 -
arch/powerpc/configs/40x/kilauea_defconfig | 1 -
arch/powerpc/configs/40x/makalu_defconfig | 1 -
arch/powerpc/configs/40x/walnut_defconfig | 1 -
arch/powerpc/configs/44x/arches_defconfig | 1 -
arch/powerpc/configs/44x/bluestone_defconfig | 1 -
arch/powerpc/configs/44x/canyonlands_defconfig | 1 -
arch/powerpc/configs/44x/ebony_defconfig | 1 -
arch/powerpc/configs/44x/eiger_defconfig | 1 -
arch/powerpc/configs/44x/icon_defconfig | 1 -
arch/powerpc/configs/44x/iss476-smp_defconfig | 1 -
arch/powerpc/configs/44x/katmai_defconfig | 1 -
arch/powerpc/configs/44x/rainier_defconfig | 1 -
arch/powerpc/configs/44x/redwood_defconfig | 1 -
arch/powerpc/configs/44x/sequoia_defconfig | 1 -
arch/powerpc/configs/44x/taishan_defconfig | 1 -
arch/powerpc/configs/44x/warp_defconfig | 1 -
arch/powerpc/configs/52xx/cm5200_defconfig | 1 -
arch/powerpc/configs/52xx/motionpro_defconfig | 1 -
arch/powerpc/configs/52xx/pcm030_defconfig | 1 -
arch/powerpc/configs/52xx/tqm5200_defconfig | 1 -
arch/powerpc/configs/83xx/asp8347_defconfig | 1 -
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig | 1 -
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig | 1 -
arch/powerpc/configs/83xx/mpc836x_mds_defconfig | 1 -
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig | 1 -
arch/powerpc/configs/83xx/sbc834x_defconfig | 1 -
arch/powerpc/configs/85xx/ksi8560_defconfig | 1 -
arch/powerpc/configs/85xx/ppa8548_defconfig | 1 -
arch/powerpc/configs/85xx/socrates_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8540_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8541_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8548_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8555_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8560_defconfig | 1 -
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 1 -
arch/powerpc/configs/86xx/gef_ppc9a_defconfig | 1 -
arch/powerpc/configs/86xx/gef_sbc310_defconfig | 1 -
arch/powerpc/configs/86xx/gef_sbc610_defconfig | 1 -
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig | 1 -
arch/powerpc/configs/86xx/sbc8641d_defconfig | 1 -
arch/powerpc/configs/c2k_defconfig | 1 -
arch/powerpc/configs/corenet64_smp_defconfig | 2 -
arch/powerpc/configs/linkstation_defconfig | 1 -
arch/powerpc/configs/mpc85xx_defconfig | 2 -
arch/powerpc/configs/mpc85xx_smp_defconfig | 2 -
arch/powerpc/configs/ppc40x_defconfig | 1 -
arch/powerpc/configs/ppc44x_defconfig | 1 -
arch/powerpc/configs/ppc64_defconfig | 70 +--
arch/powerpc/configs/ppc64e_defconfig | 70 +--
arch/powerpc/configs/prpmc2800_defconfig | 108 -----
arch/powerpc/configs/pseries_defconfig | 55 +--
arch/powerpc/configs/pseries_le_defconfig | 53 +--
arch/powerpc/configs/storcenter_defconfig | 1 -
arch/powerpc/configs/tqm8xx_defconfig | 1 -
arch/powerpc/include/asm/compat.h | 4 +
arch/powerpc/include/asm/cputable.h | 6 +-
arch/powerpc/include/asm/exception-64e.h | 15 +-
arch/powerpc/include/asm/exception-64s.h | 8 +
arch/powerpc/include/asm/hvcall.h | 5 +
arch/powerpc/include/asm/kvm_booke_hv_asm.h | 17 +-
arch/powerpc/include/asm/machdep.h | 7 +
arch/powerpc/include/asm/mce.h | 3 +-
arch/powerpc/include/asm/mmu-book3e.h | 9 +-
arch/powerpc/include/asm/opal.h | 60 ++-
arch/powerpc/include/asm/paca.h | 9 +-
arch/powerpc/include/asm/perf_event_server.h | 1 +
arch/powerpc/include/asm/reg.h | 18 +-
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/cacheinfo.c | 7 +-
arch/powerpc/kernel/cputable.c | 2 +-
arch/powerpc/kernel/exceptions-64e.S | 435 +++++++++++++----
arch/powerpc/kernel/exceptions-64s.S | 5 +
arch/powerpc/kernel/mce.c | 4 +-
arch/powerpc/kernel/mce_power.c | 37 +-
arch/powerpc/kernel/prom.c | 5 +
arch/powerpc/kernel/rtas.c | 22 +-
arch/powerpc/kernel/setup_64.c | 20 +-
arch/powerpc/kernel/traps.c | 5 +-
arch/powerpc/kernel/vdso.c | 8 +-
arch/powerpc/kernel/vdso32/getcpu.S | 2 +-
arch/powerpc/kernel/vdso64/getcpu.S | 2 +-
arch/powerpc/kernel/vio.c | 3 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 +-
arch/powerpc/kvm/book3s_interrupts.S | 4 +-
arch/powerpc/kvm/bookehv_interrupts.S | 21 +-
arch/powerpc/lib/memcpy_64.S | 2 +
arch/powerpc/mm/mem.c | 7 +-
arch/powerpc/mm/pgtable_64.c | 5 +
arch/powerpc/mm/tlb_low_64e.S | 66 ++-
arch/powerpc/mm/tlb_nohash.c | 11 +
arch/powerpc/perf/Makefile | 2 +
arch/powerpc/perf/core-book3s.c | 172 ++++++-
arch/powerpc/perf/hv-24x7-catalog.h | 33 ++
arch/powerpc/perf/hv-24x7.c | 510 ++++++++++++++++++++
arch/powerpc/perf/hv-24x7.h | 109 +++++
arch/powerpc/perf/hv-common.c | 39 ++
arch/powerpc/perf/hv-common.h | 36 ++
arch/powerpc/perf/hv-gpci.c | 294 ++++++++++++
arch/powerpc/perf/hv-gpci.h | 73 +++
arch/powerpc/perf/power7-events-list.h | 10 +
arch/powerpc/perf/power8-pmu.c | 78 ++-
arch/powerpc/platforms/85xx/c293pcie.c | 1 +
arch/powerpc/platforms/85xx/common.c | 6 +
arch/powerpc/platforms/85xx/corenet_generic.c | 17 +
arch/powerpc/platforms/85xx/ge_imp3a.c | 1 +
arch/powerpc/platforms/85xx/mpc8536_ds.c | 1 +
arch/powerpc/platforms/85xx/mpc85xx.h | 2 +
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 1 +
arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 +
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 +
arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 16 +-
arch/powerpc/platforms/85xx/p1010rdb.c | 1 +
arch/powerpc/platforms/85xx/p1022_ds.c | 1 +
arch/powerpc/platforms/85xx/p1022_rdk.c | 1 +
arch/powerpc/platforms/85xx/p1023_rds.c | 2 +
arch/powerpc/platforms/85xx/qemu_e500.c | 1 +
arch/powerpc/platforms/85xx/sbc8548.c | 1 +
arch/powerpc/platforms/85xx/twr_p102x.c | 1 +
arch/powerpc/platforms/85xx/xes_mpc85xx.c | 3 +
arch/powerpc/platforms/embedded6xx/Kconfig | 10 -
arch/powerpc/platforms/embedded6xx/Makefile | 1 -
arch/powerpc/platforms/embedded6xx/prpmc2800.c | 156 ------
arch/powerpc/platforms/powernv/Makefile | 4 +-
arch/powerpc/platforms/powernv/opal-async.c | 203 ++++++++
arch/powerpc/platforms/powernv/opal-dump.c | 525 ++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-elog.c | 313 ++++++++++++
arch/powerpc/platforms/powernv/opal-sensor.c | 64 +++
arch/powerpc/platforms/powernv/opal-sysparam.c | 290 +++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 14 +
arch/powerpc/platforms/powernv/opal.c | 106 ++++-
arch/powerpc/platforms/powernv/setup.c | 1 +
arch/powerpc/platforms/pseries/Kconfig | 12 +
arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +-
arch/powerpc/platforms/pseries/hotplug-memory.c | 83 ++--
arch/powerpc/platforms/pseries/mobility.c | 26 +-
arch/powerpc/platforms/pseries/suspend.c | 44 +-
arch/powerpc/sysdev/fsl_pci.c | 178 ++++++-
arch/powerpc/sysdev/fsl_pci.h | 8 +
arch/powerpc/xmon/xmon.c | 4 +
drivers/hwmon/Kconfig | 8 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ibmpowernv.c | 529 +++++++++++++++++++++
drivers/macintosh/adb.c | 57 ++-
drivers/watchdog/booke_wdt.c | 8 -
fs/sysfs/group.c | 7 +-
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/copyloops/Makefile | 29 ++
.../selftests/powerpc/copyloops/asm/ppc_asm.h | 86 ++++
.../selftests/powerpc/copyloops/asm/processor.h | 0
.../selftests/powerpc/copyloops/copyuser_64.S | 1 +
.../selftests/powerpc/copyloops/copyuser_power7.S | 1 +
.../selftests/powerpc/copyloops/memcpy_64.S | 1 +
.../selftests/powerpc/copyloops/memcpy_power7.S | 1 +
.../testing/selftests/powerpc/copyloops/validate.c | 99 ++++
tools/testing/selftests/powerpc/utils.h | 3 +
186 files changed, 5955 insertions(+), 926 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-dump
create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-elog
create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt
create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt
delete mode 100644 arch/powerpc/configs/prpmc2800_defconfig
create mode 100644 arch/powerpc/perf/hv-24x7-catalog.h
create mode 100644 arch/powerpc/perf/hv-24x7.c
create mode 100644 arch/powerpc/perf/hv-24x7.h
create mode 100644 arch/powerpc/perf/hv-common.c
create mode 100644 arch/powerpc/perf/hv-common.h
create mode 100644 arch/powerpc/perf/hv-gpci.c
create mode 100644 arch/powerpc/perf/hv-gpci.h
delete mode 100644 arch/powerpc/platforms/embedded6xx/prpmc2800.c
create mode 100644 arch/powerpc/platforms/powernv/opal-async.c
create mode 100644 arch/powerpc/platforms/powernv/opal-dump.c
create mode 100644 arch/powerpc/platforms/powernv/opal-elog.c
create mode 100644 arch/powerpc/platforms/powernv/opal-sensor.c
create mode 100644 arch/powerpc/platforms/powernv/opal-sysparam.c
create mode 100644 drivers/hwmon/ibmpowernv.c
create mode 100644 tools/testing/selftests/powerpc/copyloops/Makefile
create mode 100644 tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
create mode 100644 tools/testing/selftests/powerpc/copyloops/asm/processor.h
create mode 120000 tools/testing/selftests/powerpc/copyloops/copyuser_64.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/memcpy_64.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
create mode 100644 tools/testing/selftests/powerpc/copyloops/validate.c
^ permalink raw reply
* [git pull] Please pull powerpc.git next branch
From: Benjamin Herrenschmidt @ 2014-04-01 23:34 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
This time around, the powerpc merges are going to be a little bit
more complicated than usual.
This is the main pull request with most of the work for this merge
window. I will describe it a bit more further down.
There is some additional cpuidle driver work, however I haven't included
it in this tree as it depends on some work in tip/timer-core which
Thomas accidentally forgot to put in a topic branch. Since I didn't want
to carry all of that tip timer stuff in powerpc -next, I setup a
separate branch on top of Thomas tree with just that cpuidle driver in
it, and Stephen has been carrying that in next separately for a while
now. I'll send a separate pull request for it.
Additionally, two new pieces in this tree add users for a sysfs API
that Tejun and Greg have been deprecating in drivers-core-next.
Thankfully Greg reverted the patch that removes the old API so this
merge can happen cleanly, but once merged, I will send a patch adjusting
our new code to the new API so that Greg can send you the removal patch.
Now as for the content of this branch, we have a lot of perf work for
power8 new counters including support for our new "nest" counters
(also called 24x7) under pHyp (not natively yet).
We have new functionality when running under the OPAL firmware
(non-virtualized or KVM host), such as access to the firmware error logs
and service processor dumps, system parameters and sensors, along with
a hwmon driver for the latter.
There's also a bunch of bug fixes accross the board, some LE fixes,
and a nice set of selftests for validating our various types of
copy loops.
On the Freescale side, we see mostly new chip/board revisions, some
clock updates, better support for machine checks and debug exceptions,
etc...
Cheers,
Ben.
The following changes since commit a5b2cf5b1af424ee3dd9e3ce6d5cea18cb927e67:
powerpc: Align p_dyn, p_rela and p_st symbols (2014-03-07 13:50:19 +1100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next
for you to fetch changes up to cd427485357c0c4b99f69719251baacf25946e11:
Merge remote-tracking branch 'scott/next' into next (2014-03-24 10:26:10 +1100)
----------------------------------------------------------------
Aneesh Kumar K.V (2):
powerpc/mm: Make sure a local_irq_disable prevent a parallel THP split
powerpc/defconfigs: Enable THP in pseries defconfig
Anshuman Khandual (2):
powerpc/perf: Make some new raw event codes available in sysfs
powerpc/perf: Define perf_event_print_debug() to print PMU register values
Anton Blanchard (2):
powerpc: Use default set of netfilter modules (CONFIG_NETFILTER_ADVANCED=n)
powerpc/compat: 32-bit little endian machine name is ppcle, not ppc
Benjamin Herrenschmidt (2):
powerpc/pseries: Don't try to register pseries cpu hotplug on non-pseries
Merge remote-tracking branch 'scott/next' into next
Benjamin Krill (1):
powerpc/book3e: Fix check for linear mapping in TLB miss handler
Brandon Stewart (1):
macintosh/adb: Fixed some coding style problems
Cody P Schafer (10):
sysfs: create bin_attributes under the requested group
powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info)
powerpc/perf: Add hv_gpci interface header
powerpc/perf: Add 24x7 interface headers
powerpc/perf: Add a shared interface to get gpci version and capabilities
powerpc/perf: Add macros for defining event fields & formats
powerpc/perf: Add support for the hv gpci (get performance counter info) interface
powerpc/perf: Add support for the hv 24x7 interface
powerpc/perf: Add kconfig option for hypervisor provided counters
powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes
Greg Kurz (1):
powerpc/le: Big endian arguments for ppc_rtas()
Haren Myneni (2):
powerpc/pseries: Device tree should only be updated once after suspend/migrate
powerpc/pseries: Update dynamic cache nodes for suspend/resume operation
Josh Boyer (1):
powerpc: Update ppc4xx maintainer
Li Zhong (1):
powerpc: Revert c6102609 and replace it with the correct fix for vio dma mask setting
Luis Henriques (1):
powerpc/kconfig: Remove TSI108_BRIDGE duplicates
Mahesh Salgaonkar (2):
powerpc/book3s: Recover from MC in sapphire on SCOM read via MMIO.
powerpc/book3s: Fix CFAR clobbering issue in machine check handler.
Michael Ellerman (9):
selftests/powerpc: Import Anton's memcpy / copy_tofrom_user tests
powerpc: Add a cpu feature CPU_FTR_PMAO_BUG
powerpc/perf: Add lost exception workaround
powerpc/perf: Reject EBB events which specify a sample_type
powerpc/perf: Clean up the EBB hash defines a little
powerpc/perf: Avoid mutating event in power8_get_constraint()
powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
powerpc/perf: Enable BHRB access for EBB events
powerpc/perf: Fix handling of L3 events with bank == 1
Michael Neuling (1):
powerpc: Rate-limit users spamming kernel log buffer
Minghuan Lian (1):
powerpc/pci: Fix IMMRBAR address
Nathan Fontenot (1):
powerpc/pseries: Use remove_memory() to remove memory
Neelesh Gupta (3):
powerpc/powernv: Infrastructure to support OPAL async completion
powerpc/powernv: Enable reading and updating of system parameters
powerpc/powernv: Enable fetching of platform sensor data
Paul Gortmaker (1):
powerpc: Delete old PrPMC 280/2800 support
Philippe Bergheaud (1):
powerpc: Fix xmon disassembler for little-endian
Prabhakar Kushwaha (1):
powerpc/config: Remove unnecssary CONFIG_FSL_IFC
Scott Wood (8):
powerpc/booke64: Fix exception numbers
powerpc/e6500: Make TLB lock recursive
powerpc/booke64: Use SPRG7 for VDSO
powerpc/booke64: Use SPRG_TLB_EXFRAME on bolted handlers
powerpc/booke64: Remove ints from EXCEPTION_COMMON
powerpc/booke64: Add crit/mc/debug support to EXCEPTION_COMMON
powerpc/booke64: Critical and machine check exception support
Revert "powerpc/watchdog: Don't enable interrupt on PPC64 BookE"
Sebastian Siewior (2):
powerpc: Add "force config cmd line" Kconfig option
powerpc: 85xx rdb: move np pointer to avoid builderror
Shivaprasad G Bhat (1):
powerpc/powernv: hwmon driver for power values, fan rpm and temperature
Shuah Khan (1):
macintosh/adb: Change platform power management to use dev_pm_ops
Stewart Smith (2):
powerpc/powernv: Read OPAL error log and export it through sysfs
powerpc/powernv Platform dump interface
Tang Yuantian (2):
powerpc/mpc85xx: Update clock nodes in device tree
powerpc: T4240: Add ina220 node in dts
Tiejun Chen (2):
powerpc/book3e: initialize crit/mc/dbg kernel stack pointers
powerpc/book3e: store crit/mc/dbg exception thread info
Tyrel Datwyler (1):
powerpc/pseries: Expose in kernel device tree update to drmgr
Wang Dongsheng (2):
powerpc/fsl: add PVR definition for E500MC and E5500
fsl/pci: The new pci suspend/resume implementation
Zhao Qiang (2):
QE: split function mpc85xx_qe_init() into two functions.
Corenet: Add QE platform support for Corenet
harninder rai (1):
powerpc/fsl: Add/update miscellaneous missing binding
송은봉 (1):
powerpc: : Kill CONFIG_MTD_PARTITIONS
Documentation/ABI/stable/sysfs-firmware-opal-dump | 41 ++
Documentation/ABI/stable/sysfs-firmware-opal-elog | 60 +++
.../testing/sysfs-bus-event_source-devices-events | 517 ++++++++++++++++++++
.../testing/sysfs-bus-event_source-devices-hv_24x7 | 23 +
.../testing/sysfs-bus-event_source-devices-hv_gpci | 43 ++
.../devicetree/bindings/powerpc/fsl/l2cache.txt | 23 +
.../devicetree/bindings/powerpc/fsl/mem-ctrlr.txt | 27 ++
Documentation/devicetree/bindings/usb/fsl-usb.txt | 4 +-
MAINTAINERS | 3 +-
arch/powerpc/Kconfig | 9 +
arch/powerpc/boot/Makefile | 5 +-
arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | 36 ++
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi | 2 +
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | 36 ++
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | 60 +++
arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | 61 +++
arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | 113 +++++
arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi | 8 +
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 43 ++
arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 2 +
arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | 61 +++
arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | 4 +
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 86 ++++
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | 12 +
arch/powerpc/boot/dts/t4240qds.dts | 42 ++
arch/powerpc/configs/40x/acadia_defconfig | 1 -
arch/powerpc/configs/40x/ep405_defconfig | 1 -
arch/powerpc/configs/40x/kilauea_defconfig | 1 -
arch/powerpc/configs/40x/makalu_defconfig | 1 -
arch/powerpc/configs/40x/walnut_defconfig | 1 -
arch/powerpc/configs/44x/arches_defconfig | 1 -
arch/powerpc/configs/44x/bluestone_defconfig | 1 -
arch/powerpc/configs/44x/canyonlands_defconfig | 1 -
arch/powerpc/configs/44x/ebony_defconfig | 1 -
arch/powerpc/configs/44x/eiger_defconfig | 1 -
arch/powerpc/configs/44x/icon_defconfig | 1 -
arch/powerpc/configs/44x/iss476-smp_defconfig | 1 -
arch/powerpc/configs/44x/katmai_defconfig | 1 -
arch/powerpc/configs/44x/rainier_defconfig | 1 -
arch/powerpc/configs/44x/redwood_defconfig | 1 -
arch/powerpc/configs/44x/sequoia_defconfig | 1 -
arch/powerpc/configs/44x/taishan_defconfig | 1 -
arch/powerpc/configs/44x/warp_defconfig | 1 -
arch/powerpc/configs/52xx/cm5200_defconfig | 1 -
arch/powerpc/configs/52xx/motionpro_defconfig | 1 -
arch/powerpc/configs/52xx/pcm030_defconfig | 1 -
arch/powerpc/configs/52xx/tqm5200_defconfig | 1 -
arch/powerpc/configs/83xx/asp8347_defconfig | 1 -
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig | 1 -
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig | 1 -
arch/powerpc/configs/83xx/mpc836x_mds_defconfig | 1 -
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig | 1 -
arch/powerpc/configs/83xx/sbc834x_defconfig | 1 -
arch/powerpc/configs/85xx/ksi8560_defconfig | 1 -
arch/powerpc/configs/85xx/ppa8548_defconfig | 1 -
arch/powerpc/configs/85xx/socrates_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8540_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8541_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8548_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8555_defconfig | 1 -
arch/powerpc/configs/85xx/tqm8560_defconfig | 1 -
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 1 -
arch/powerpc/configs/86xx/gef_ppc9a_defconfig | 1 -
arch/powerpc/configs/86xx/gef_sbc310_defconfig | 1 -
arch/powerpc/configs/86xx/gef_sbc610_defconfig | 1 -
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig | 1 -
arch/powerpc/configs/86xx/sbc8641d_defconfig | 1 -
arch/powerpc/configs/c2k_defconfig | 1 -
arch/powerpc/configs/corenet64_smp_defconfig | 2 -
arch/powerpc/configs/linkstation_defconfig | 1 -
arch/powerpc/configs/mpc85xx_defconfig | 2 -
arch/powerpc/configs/mpc85xx_smp_defconfig | 2 -
arch/powerpc/configs/ppc40x_defconfig | 1 -
arch/powerpc/configs/ppc44x_defconfig | 1 -
arch/powerpc/configs/ppc64_defconfig | 70 +--
arch/powerpc/configs/ppc64e_defconfig | 70 +--
arch/powerpc/configs/prpmc2800_defconfig | 108 -----
arch/powerpc/configs/pseries_defconfig | 55 +--
arch/powerpc/configs/pseries_le_defconfig | 53 +--
arch/powerpc/configs/storcenter_defconfig | 1 -
arch/powerpc/configs/tqm8xx_defconfig | 1 -
arch/powerpc/include/asm/compat.h | 4 +
arch/powerpc/include/asm/cputable.h | 6 +-
arch/powerpc/include/asm/exception-64e.h | 15 +-
arch/powerpc/include/asm/exception-64s.h | 8 +
arch/powerpc/include/asm/hvcall.h | 5 +
arch/powerpc/include/asm/kvm_booke_hv_asm.h | 17 +-
arch/powerpc/include/asm/machdep.h | 7 +
arch/powerpc/include/asm/mce.h | 3 +-
arch/powerpc/include/asm/mmu-book3e.h | 9 +-
arch/powerpc/include/asm/opal.h | 60 ++-
arch/powerpc/include/asm/paca.h | 9 +-
arch/powerpc/include/asm/perf_event_server.h | 1 +
arch/powerpc/include/asm/reg.h | 18 +-
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/cacheinfo.c | 7 +-
arch/powerpc/kernel/cputable.c | 2 +-
arch/powerpc/kernel/exceptions-64e.S | 435 +++++++++++++----
arch/powerpc/kernel/exceptions-64s.S | 5 +
arch/powerpc/kernel/mce.c | 4 +-
arch/powerpc/kernel/mce_power.c | 37 +-
arch/powerpc/kernel/prom.c | 5 +
arch/powerpc/kernel/rtas.c | 22 +-
arch/powerpc/kernel/setup_64.c | 20 +-
arch/powerpc/kernel/traps.c | 5 +-
arch/powerpc/kernel/vdso.c | 8 +-
arch/powerpc/kernel/vdso32/getcpu.S | 2 +-
arch/powerpc/kernel/vdso64/getcpu.S | 2 +-
arch/powerpc/kernel/vio.c | 3 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 +-
arch/powerpc/kvm/book3s_interrupts.S | 4 +-
arch/powerpc/kvm/bookehv_interrupts.S | 21 +-
arch/powerpc/lib/memcpy_64.S | 2 +
arch/powerpc/mm/mem.c | 7 +-
arch/powerpc/mm/pgtable_64.c | 5 +
arch/powerpc/mm/tlb_low_64e.S | 66 ++-
arch/powerpc/mm/tlb_nohash.c | 11 +
arch/powerpc/perf/Makefile | 2 +
arch/powerpc/perf/core-book3s.c | 172 ++++++-
arch/powerpc/perf/hv-24x7-catalog.h | 33 ++
arch/powerpc/perf/hv-24x7.c | 510 ++++++++++++++++++++
arch/powerpc/perf/hv-24x7.h | 109 +++++
arch/powerpc/perf/hv-common.c | 39 ++
arch/powerpc/perf/hv-common.h | 36 ++
arch/powerpc/perf/hv-gpci.c | 294 ++++++++++++
arch/powerpc/perf/hv-gpci.h | 73 +++
arch/powerpc/perf/power7-events-list.h | 10 +
arch/powerpc/perf/power8-pmu.c | 78 ++-
arch/powerpc/platforms/85xx/c293pcie.c | 1 +
arch/powerpc/platforms/85xx/common.c | 6 +
arch/powerpc/platforms/85xx/corenet_generic.c | 17 +
arch/powerpc/platforms/85xx/ge_imp3a.c | 1 +
arch/powerpc/platforms/85xx/mpc8536_ds.c | 1 +
arch/powerpc/platforms/85xx/mpc85xx.h | 2 +
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 1 +
arch/powerpc/platforms/85xx/mpc85xx_ds.c | 3 +
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 +
arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 16 +-
arch/powerpc/platforms/85xx/p1010rdb.c | 1 +
arch/powerpc/platforms/85xx/p1022_ds.c | 1 +
arch/powerpc/platforms/85xx/p1022_rdk.c | 1 +
arch/powerpc/platforms/85xx/p1023_rds.c | 2 +
arch/powerpc/platforms/85xx/qemu_e500.c | 1 +
arch/powerpc/platforms/85xx/sbc8548.c | 1 +
arch/powerpc/platforms/85xx/twr_p102x.c | 1 +
arch/powerpc/platforms/85xx/xes_mpc85xx.c | 3 +
arch/powerpc/platforms/embedded6xx/Kconfig | 10 -
arch/powerpc/platforms/embedded6xx/Makefile | 1 -
arch/powerpc/platforms/embedded6xx/prpmc2800.c | 156 ------
arch/powerpc/platforms/powernv/Makefile | 4 +-
arch/powerpc/platforms/powernv/opal-async.c | 203 ++++++++
arch/powerpc/platforms/powernv/opal-dump.c | 525 ++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-elog.c | 313 ++++++++++++
arch/powerpc/platforms/powernv/opal-sensor.c | 64 +++
arch/powerpc/platforms/powernv/opal-sysparam.c | 290 +++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 14 +
arch/powerpc/platforms/powernv/opal.c | 106 ++++-
arch/powerpc/platforms/powernv/setup.c | 1 +
arch/powerpc/platforms/pseries/Kconfig | 12 +
arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +-
arch/powerpc/platforms/pseries/hotplug-memory.c | 83 ++--
arch/powerpc/platforms/pseries/mobility.c | 26 +-
arch/powerpc/platforms/pseries/suspend.c | 44 +-
arch/powerpc/sysdev/fsl_pci.c | 178 ++++++-
arch/powerpc/sysdev/fsl_pci.h | 8 +
arch/powerpc/xmon/xmon.c | 4 +
drivers/hwmon/Kconfig | 8 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ibmpowernv.c | 529 +++++++++++++++++++++
drivers/macintosh/adb.c | 57 ++-
drivers/watchdog/booke_wdt.c | 8 -
fs/sysfs/group.c | 7 +-
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/copyloops/Makefile | 29 ++
.../selftests/powerpc/copyloops/asm/ppc_asm.h | 86 ++++
.../selftests/powerpc/copyloops/asm/processor.h | 0
.../selftests/powerpc/copyloops/copyuser_64.S | 1 +
.../selftests/powerpc/copyloops/copyuser_power7.S | 1 +
.../selftests/powerpc/copyloops/memcpy_64.S | 1 +
.../selftests/powerpc/copyloops/memcpy_power7.S | 1 +
.../testing/selftests/powerpc/copyloops/validate.c | 99 ++++
tools/testing/selftests/powerpc/utils.h | 3 +
186 files changed, 5955 insertions(+), 926 deletions(-)
create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-dump
create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-elog
create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt
create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt
delete mode 100644 arch/powerpc/configs/prpmc2800_defconfig
create mode 100644 arch/powerpc/perf/hv-24x7-catalog.h
create mode 100644 arch/powerpc/perf/hv-24x7.c
create mode 100644 arch/powerpc/perf/hv-24x7.h
create mode 100644 arch/powerpc/perf/hv-common.c
create mode 100644 arch/powerpc/perf/hv-common.h
create mode 100644 arch/powerpc/perf/hv-gpci.c
create mode 100644 arch/powerpc/perf/hv-gpci.h
delete mode 100644 arch/powerpc/platforms/embedded6xx/prpmc2800.c
create mode 100644 arch/powerpc/platforms/powernv/opal-async.c
create mode 100644 arch/powerpc/platforms/powernv/opal-dump.c
create mode 100644 arch/powerpc/platforms/powernv/opal-elog.c
create mode 100644 arch/powerpc/platforms/powernv/opal-sensor.c
create mode 100644 arch/powerpc/platforms/powernv/opal-sysparam.c
create mode 100644 drivers/hwmon/ibmpowernv.c
create mode 100644 tools/testing/selftests/powerpc/copyloops/Makefile
create mode 100644 tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
create mode 100644 tools/testing/selftests/powerpc/copyloops/asm/processor.h
create mode 120000 tools/testing/selftests/powerpc/copyloops/copyuser_64.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/memcpy_64.S
create mode 120000 tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
create mode 100644 tools/testing/selftests/powerpc/copyloops/validate.c
^ permalink raw reply
* [git pull] Please pull powerpc.git powernv-cpuidle branch
From: Benjamin Herrenschmidt @ 2014-04-01 23:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
Hi Linus !
This is the branch I mentioned in my other pull request which contains
our improved cpuidle support for the "powernv" platform
(non-virtualized). It adds support for the "fast sleep" feature of the
processor which provides higher power savings than our usual "nap" mode
but at the cost of losing the timers while asleep, and thus exploits the
new timer broadcast framework to work around that limitation.
It's based on a tip timer tree that you seem to have already merged
Cheers,
Ben.
The following changes since commit 849401b66d305f3feb75b6db7459b95ad190552a:
tick: Fixup more fallout from hrtimer broadcast mode (2014-02-09 15:11:47 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git powernv-cpuidle
for you to fetch changes up to 0888839c5b62c44a55ac9d28acc273ba663c65ea:
cpuidle/powernv: Parse device tree to setup idle states (2014-03-05 15:57:08 +1100)
----------------------------------------------------------------
Preeti U Murthy (3):
powerpc: Split timer_interrupt() into timer handling and interrupt handling routines
cpuidle/powernv: Add "Fast-Sleep" CPU idle state
cpuidle/powernv: Parse device tree to setup idle states
Srivatsa S. Bhat (2):
powerpc: Free up the slot of PPC_MSG_CALL_FUNC_SINGLE IPI message
powerpc: Implement tick broadcast IPI as a fixed IPI message
Vaidyanathan Srinivasan (2):
powerpc/powernv: Add context management for Fast Sleep
powerpc/powernv: Add OPAL call to resync timebase on wakeup
arch/powerpc/Kconfig | 2 +
arch/powerpc/include/asm/opal.h | 2 +
arch/powerpc/include/asm/processor.h | 1 +
arch/powerpc/include/asm/smp.h | 2 +-
arch/powerpc/include/asm/time.h | 1 +
arch/powerpc/kernel/exceptions-64s.S | 10 ++-
arch/powerpc/kernel/idle_power7.S | 90 +++++++++++++++++-----
arch/powerpc/kernel/smp.c | 25 ++++--
arch/powerpc/kernel/time.c | 90 +++++++++++++---------
arch/powerpc/platforms/cell/interrupt.c | 2 +-
arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
arch/powerpc/platforms/ps3/smp.c | 2 +-
drivers/cpuidle/cpuidle-powernv.c | 102 ++++++++++++++++++++++---
13 files changed, 253 insertions(+), 77 deletions(-)
^ permalink raw reply
* RE: [PATCH 2/2] Make the diu driver work without board level initilization
From: Jason.Jin @ 2014-04-02 0:22 UTC (permalink / raw)
To: Scott Wood
Cc: linux-fbdev@vger.kernel.org, Li.Xiubo@freescale.com,
linuxppc-dev@lists.ozlabs.org, timur@tabi.org
In-Reply-To: <1396388317.32034.14.camel@snotra.buserror.net>
DQo+ID4gVGhhbmtzLCBUaGlzIGhhcyBiZWVuIGZpeGVkIGluIHRoZSB1cGRhdGUgdmVyc2lvbiwg
cGxlYXNlIGhlbHAgdG8NCj4gcmV2aWV3IGl0IGF0Og0KPiA+IGh0dHA6Ly9wYXRjaHdvcmsub3ps
YWJzLm9yZy9wYXRjaC8zMzUyMjUvDQo+ID4gSSBmb3Jnb3QgdG8gYWRkIHRoZSBWMiBpbmZvcm1h
dGlvbiBpbiB0aGUgc3ViamVjdCBpbiB0aGUgdXBkYXRlIHBhdGNoDQo+IHNvIHRoaXMgbWF5IGNv
bmZ1c2UgdGhlIHJldmlld2VyLCBzb3JyeSBmb3IgdGhhdC4NCj4gDQo+IEl0IGlzIG5vdCBmaXhl
ZCBpbiB0aGF0IHBhdGNoIChvciBkaWQgeW91IGxpbmsgdGhlIHdyb25nIHZlcnNpb24/KS4gIFlv
dQ0KPiBzaG91bGQgbmV2ZXIgdXNlIFwgdG8gY29udGludWUgYSBsaW5lIGluIEMsIG90aGVyIHRo
YW4gaW4gbWFjcm9zLg0KPiANCj4gRnVydGhlciwgaXQgaXMgbm90IHBlcm1pdHRlZCB0byB3cmFw
IGtlcm5lbCBvdXRwdXQgc3RyaW5ncy4gIFRoaXMgaXMgYW4NCj4gZXhjZXB0aW9uIHRvIHRoZSA4
MC1jb2x1bW4gcnVsZS4gIENoZWNrcGF0Y2ggc2hvdWxkIGhhdmUgdG9sZCB5b3UgdGhpcy4NCltK
YXNvbiBKaW4tUjY0MTg4XSBUaGFua3MgZm9yIHBvaW50aW5nIG91dCB0aGlzLCBJIGNvbmZ1c2Vk
IHRoZSBpbnRlcm5hbCB2ZXJzaW9uIGFuZCBleHRlcm5hbCB2ZXJzaW9uLiBJJ2xsIGZpeCBpdCBp
biBuZXh0IHZlcnNpb24uIFRoYW5rcy4NCg==
^ permalink raw reply
* Re: [RFC] powerpc, ptrace: Add few more ptrace request macros
From: Michael Neuling @ 2014-04-02 0:43 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1396350893-4456-1-git-send-email-khandual@linux.vnet.ibm.com>
Anshuman Khandual <khandual@linux.vnet.ibm.com> wrote:
> This patch adds few more ptrace request macros expanding
> the existing capability. These ptrace requests macros can
> be classified into two categories.
Why is this only an RFC?
Also, please share the test case that you wrote for this.
Mikey
>
> (1) Transactional memory
>
> /* TM special purpose registers */
> PTRACE_GETTM_SPRREGS
> PTRACE_SETTM_SPRREGS
>
> /* Checkpointed GPR registers */
> PTRACE_GETTM_CGPRREGS
> PTRACE_SETTM_CGPRREGS
>
> /* Checkpointed FPR registers */
> PTRACE_GETTM_CFPRREGS
> PTRACE_SETTM_CFPRREGS
>
> /* Checkpointed VMX registers */
> PTRACE_GETTM_CVMXREGS
> PTRACE_SETTM_CVMXREGS
>
> (2) Miscellaneous
>
> /* TAR, PPR, DSCR registers */
> PTRACE_GETMSCREGS
> PTRACE_SETMSCREGS
>
> This patch also adds mutliple new generic ELF core note sections in
> this regard which can be listed as follows.
>
> NT_PPC_TM_SPR /* Transactional memory specific registers */
> NT_PPC_TM_CGPR /* Transactional memory checkpointed GPR */
> NT_PPC_TM_CFPR /* Transactional memory checkpointed FPR */
> NT_PPC_TM_CVMX /* Transactional memory checkpointed VMX */
> NT_PPC_MISC /* Miscellaneous registers */
>
> Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/switch_to.h | 8 +
> arch/powerpc/include/uapi/asm/ptrace.h | 61 +++
> arch/powerpc/kernel/process.c | 24 ++
> arch/powerpc/kernel/ptrace.c | 658 +++++++++++++++++++++++++++++++--
> include/uapi/linux/elf.h | 5 +
> 5 files changed, 729 insertions(+), 27 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
> index 0e83e7d..73e2601 100644
> --- a/arch/powerpc/include/asm/switch_to.h
> +++ b/arch/powerpc/include/asm/switch_to.h
> @@ -80,6 +80,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
> }
> #endif
>
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +extern void flush_tmreg_to_thread(struct task_struct *);
> +#else
> +static inline void flush_tmreg_to_thread(struct task_struct *t)
> +{
> +}
> +#endif
> +
> static inline void clear_task_ebb(struct task_struct *t)
> {
> #ifdef CONFIG_PPC_BOOK3S_64
> diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
> index 77d2ed3..fd962d6 100644
> --- a/arch/powerpc/include/uapi/asm/ptrace.h
> +++ b/arch/powerpc/include/uapi/asm/ptrace.h
> @@ -190,6 +190,67 @@ struct pt_regs {
> #define PPC_PTRACE_SETHWDEBUG 0x88
> #define PPC_PTRACE_DELHWDEBUG 0x87
>
> +/* Transactional memory registers */
> +
> +/*
> + * SPR
> + *
> + * struct data {
> + * u64 tm_tfhar;
> + * u64 tm_texasr;
> + * u64 tm_tfiar;
> + * unsigned long tm_orig_msr;
> + * u64 tm_tar;
> + * u64 tm_ppr;
> + * u64 tm_dscr;
> + * };
> + */
> +#define PTRACE_GETTM_SPRREGS 0x70
> +#define PTRACE_SETTM_SPRREGS 0x71
> +
> +/*
> + * Checkpointed GPR
> + *
> + * struct data {
> + * struct pt_regs ckpt_regs;
> + * };
> + */
> +#define PTRACE_GETTM_CGPRREGS 0x72
> +#define PTRACE_SETTM_CGPRREGS 0x73
> +
> +/*
> + * Checkpointed FPR
> + *
> + * struct data {
> + * u64 fpr[32];
> + * u64 fpscr;
> + * };
> + */
> +#define PTRACE_GETTM_CFPRREGS 0x74
> +#define PTRACE_SETTM_CFPRREGS 0x75
> +
> +/*
> + * Checkpointed VMX
> + *
> + * struct data {
> + * vector128 vr[32];
> + * vector128 vscr;
> + * unsigned long vrsave;
> + *};
> + */
> +#define PTRACE_GETTM_CVMXREGS 0x76
> +#define PTRACE_SETTM_CVMXREGS 0x77
> +
> +/* Miscellaneous registers */
> +#define PTRACE_GETMSCREGS 0x78
> +#define PTRACE_SETMSCREGS 0x79
> +
> +/*
> + * XXX: A note to application developers. The existing data layout
> + * of the above four ptrace requests can change when new registers
> + * are available for each category in forthcoming processors.
> + */
> +
> #ifndef __ASSEMBLY__
>
> struct ppc_debug_info {
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index af064d2..e5dfd8e 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -673,6 +673,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
> }
> }
>
> +void flush_tmreg_to_thread(struct task_struct *tsk)
> +{
> + /*
> + * If task is not current, it should have been flushed
> + * already to it's thread_struct during __switch_to().
> + */
> + if (tsk != current)
> + return;
> +
> + preempt_disable();
> + if (tsk->thread.regs) {
> + /*
> + * If we are still current, the TM state need to
> + * be flushed to thread_struct as it will be still
> + * present in the current cpu
> + */
> + if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
> + __switch_to_tm(tsk);
> + tm_recheckpoint_new_task(tsk);
> + }
> + }
> + preempt_enable();
> +}
> +
> /*
> * This is called if we are on the way out to userspace and the
> * TIF_RESTORE_TM flag is set. It checks if we need to reload
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index 2e3d2bf..cb4d5bf 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -357,6 +357,17 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
> return ret;
> }
>
> +/*
> + * When any transaction is active, thread_struct->transact_fp holds
> + * the current running value of all FPR registers and thread_struct->
> + * fp_state hold the last checkpointed FPR state for the given
> + * transaction.
> + *
> + * struct data {
> + * u64 fpr[32];
> + * u64 fpscr;
> + * };
> + */
> static int fpr_get(struct task_struct *target, const struct user_regset *regset,
> unsigned int pos, unsigned int count,
> void *kbuf, void __user *ubuf)
> @@ -365,21 +376,41 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
> u64 buf[33];
> int i;
> #endif
> - flush_fp_to_thread(target);
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + } else {
> + flush_fp_to_thread(target);
> + }
>
> #ifdef CONFIG_VSX
> /* copy to local buffer then write that out */
> - for (i = 0; i < 32 ; i++)
> - buf[i] = target->thread.TS_FPR(i);
> - buf[32] = target->thread.fp_state.fpscr;
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + for (i = 0; i < 32 ; i++)
> + buf[i] = target->thread.TS_TRANS_FPR(i);
> + buf[32] = target->thread.transact_fp.fpscr;
> + } else {
> + for (i = 0; i < 32 ; i++)
> + buf[i] = target->thread.TS_FPR(i);
> + buf[32] = target->thread.fp_state.fpscr;
> + }
> return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
>
> #else
> - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> - offsetof(struct thread_fp_state, fpr[32][0]));
> + if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
> + BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
> + offsetof(struct transact_fp, fpr[32][0]));
>
> - return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.transact_fp, 0, -1);
> + } esle {
> + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> + offsetof(struct thread_fp_state, fpr[32][0]));
> +
> + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> &target->thread.fp_state, 0, -1);
> + }
> #endif
> }
>
> @@ -391,23 +422,44 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
> u64 buf[33];
> int i;
> #endif
> - flush_fp_to_thread(target);
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + } else {
> + flush_fp_to_thread(target);
> + }
>
> #ifdef CONFIG_VSX
> /* copy to local buffer then write that out */
> i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> if (i)
> return i;
> - for (i = 0; i < 32 ; i++)
> - target->thread.TS_FPR(i) = buf[i];
> - target->thread.fp_state.fpscr = buf[32];
> + for (i = 0; i < 32 ; i++) {
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + target->thread.TS_TRANS_FPR(i) = buf[i];
> + else
> + target->thread.TS_FPR(i) = buf[i];
> + }
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + target->thread.transact_fp.fpscr = buf[32];
> + else
> + target->thread.fp_state.fpscr = buf[32];
> return 0;
> #else
> - BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> - offsetof(struct thread_fp_state, fpr[32][0]));
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
> + offsetof(struct transact_fp, fpr[32][0]));
>
> - return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> - &target->thread.fp_state, 0, -1);
> + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.transact_fp, 0, -1);
> + } else {
> + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> + offsetof(struct thread_fp_state, fpr[32][0]));
> +
> + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.fp_state, 0, -1);
> + }
> #endif
> }
>
> @@ -432,20 +484,44 @@ static int vr_active(struct task_struct *target,
> return target->thread.used_vr ? regset->n : 0;
> }
>
> +/*
> + * When any transaction is active, thread_struct->transact_vr holds
> + * the current running value of all VMX registers and thread_struct->
> + * vr_state hold the last checkpointed VMX state for the given
> + * transaction.
> + *
> + * struct data {
> + * vector128 vr[32];
> + * vector128 vscr;
> + * vector128 vrsave;
> + * };
> + */
> static int vr_get(struct task_struct *target, const struct user_regset *regset,
> unsigned int pos, unsigned int count,
> void *kbuf, void __user *ubuf)
> {
> int ret;
> + struct thread_vr_state *addr;
>
> - flush_altivec_to_thread(target);
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + } else {
> + flush_altivec_to_thread(target);
> + }
>
> BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> offsetof(struct thread_vr_state, vr[32]));
>
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + addr = &target->thread.transact_vr;
> + else
> + addr = &target->thread.vr_state;
> +
> ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> - &target->thread.vr_state, 0,
> - 33 * sizeof(vector128));
> + addr, 0, 33 * sizeof(vector128));
> +
> if (!ret) {
> /*
> * Copy out only the low-order word of vrsave.
> @@ -455,11 +531,14 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
> u32 word;
> } vrsave;
> memset(&vrsave, 0, sizeof(vrsave));
> - vrsave.word = target->thread.vrsave;
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + vrsave.word = target->thread.transact_vrsave;
> + else
> + vrsave.word = target->thread.vrsave;
> +
> ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
> 33 * sizeof(vector128), -1);
> }
> -
> return ret;
> }
>
> @@ -467,16 +546,27 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
> unsigned int pos, unsigned int count,
> const void *kbuf, const void __user *ubuf)
> {
> + struct thread_vr_state *addr;
> int ret;
>
> - flush_altivec_to_thread(target);
> + if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + } else {
> + flush_altivec_to_thread(target);
> + }
>
> BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> offsetof(struct thread_vr_state, vr[32]));
>
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + addr = &target->thread.transact_vr;
> + else
> + addr = &target->thread.vr_state;
> ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> - &target->thread.vr_state, 0,
> - 33 * sizeof(vector128));
> + addr, 0, 33 * sizeof(vector128));
> +
> if (!ret && count > 0) {
> /*
> * We use only the first word of vrsave.
> @@ -486,13 +576,21 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
> u32 word;
> } vrsave;
> memset(&vrsave, 0, sizeof(vrsave));
> - vrsave.word = target->thread.vrsave;
> +
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + vrsave.word = target->thread.transact_vrsave;
> + else
> + vrsave.word = target->thread.vrsave;
> +
> ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
> 33 * sizeof(vector128), -1);
> - if (!ret)
> - target->thread.vrsave = vrsave.word;
> + if (!ret) {
> + if (MSR_TM_ACTIVE(target->thread.regs->msr))
> + target->thread.transact_vrsave = vrsave.word;
> + else
> + target->thread.vrsave = vrsave.word;
> + }
> }
> -
> return ret;
> }
> #endif /* CONFIG_ALTIVEC */
> @@ -613,6 +711,417 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
> }
> #endif /* CONFIG_SPE */
>
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> +
> +/*
> + * Transactional SPR
> + *
> + * struct {
> + * u64 tm_tfhar;
> + * u64 tm_texasr;
> + * u64 tm_tfiar;
> + * unsigned long tm_orig_msr;
> + * unsigned long tm_tar;
> + * unsigned long tm_ppr;
> + * unsigned long tm_dscr;
> + * };
> + */
> +static int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + void *kbuf, void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> + /* TFHAR register */
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tfhar, 0, sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar) +
> + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
> +
> + /* TEXASR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr) +
> + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
> +
> + /* TFIAR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar) +
> + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
> +
> + /* TM checkpointed original MSR */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_orig_msr, 3 * sizeof(u64),
> + 3 * sizeof(u64) + sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr) +
> + sizeof(unsigned long) + sizeof(struct pt_regs)
> + != offsetof(struct thread_struct, tm_tar));
> +
> + /* TM checkpointed TAR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tar, 3 * sizeof(u64) +
> + sizeof(unsigned long) , 3 * sizeof(u64) +
> + 2 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
> + + sizeof(unsigned long) !=
> + offsetof(struct thread_struct, tm_ppr));
> +
> + /* TM checkpointed PPR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_ppr, 3 * sizeof(u64) +
> + 2 * sizeof(unsigned long), 3 * sizeof(u64) +
> + 3 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
> + sizeof(unsigned long) !=
> + offsetof(struct thread_struct, tm_dscr));
> +
> + /* TM checkpointed DSCR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_dscr, 3 * sizeof(u64)
> + + 3 * sizeof(unsigned long), 3 * sizeof(u64)
> + + 4 * sizeof(unsigned long));
> + return ret;
> +}
> +
> +static int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> + /* TFHAR register */
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tfhar, 0, sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar)
> + + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
> +
> + /* TEXASR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr)
> + + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
> +
> + /* TFIAR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar)
> + + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
> +
> + /* TM checkpointed orig MSR */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_orig_msr, 3 * sizeof(u64),
> + 3 * sizeof(u64) + sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr)
> + + sizeof(unsigned long) + sizeof(struct pt_regs) !=
> + offsetof(struct thread_struct, tm_tar));
> +
> + /* TM checkpointed TAR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_tar, 3 * sizeof(u64) +
> + sizeof(unsigned long), 3 * sizeof(u64) +
> + 2 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
> + + sizeof(unsigned long) != offsetof(struct thread_struct, tm_ppr));
> +
> + /* TM checkpointed PPR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_ppr, 3 * sizeof(u64)
> + + 2 * sizeof(unsigned long), 3 * sizeof(u64)
> + + 3 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
> + sizeof(unsigned long) !=
> + offsetof(struct thread_struct, tm_dscr));
> +
> + /* TM checkpointed DSCR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tm_dscr,
> + 3 * sizeof(u64) + 3 * sizeof(unsigned long),
> + 3 * sizeof(u64) + 4 * sizeof(unsigned long));
> +
> + return ret;
> +}
> +
> +/*
> + * Checkpointed GPR
> + *
> + * struct data {
> + * struct pt_regs ckpt_regs;
> + * };
> + */
> +static int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + void *kbuf, void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.ckpt_regs, 0,
> + sizeof(struct pt_regs));
> + return ret;
> +}
> +
> +static int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.ckpt_regs, 0,
> + sizeof(struct pt_regs));
> + return ret;
> +}
> +
> +/*
> + * Checkpointed FPR
> + *
> + * struct data {
> + * u64 fpr[32];
> + * u64 fpscr;
> + * };
> + */
> +static int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + void *kbuf, void __user *ubuf)
> +{
> +#ifdef CONFIG_VSX
> + u64 buf[33];
> + int i;
> +#endif
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> +#ifdef CONFIG_VSX
> + /* copy to local buffer then write that out */
> + for (i = 0; i < 32 ; i++)
> + buf[i] = target->thread.TS_FPR(i);
> + buf[32] = target->thread.fp_state.fpscr;
> + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> +
> +#else
> + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> + offsetof(struct thread_fp_state, fpr[32][0]));
> +
> + return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.thread_fp_state, 0, -1);
> +#endif
> +}
> +
> +static int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> +#ifdef CONFIG_VSX
> + u64 buf[33];
> + int i;
> +#endif
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> +#ifdef CONFIG_VSX
> + /* copy to local buffer then write that out */
> + i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
> + if (i)
> + return i;
> + for (i = 0; i < 32 ; i++)
> + target->thread.TS_FPR(i) = buf[i];
> + target->thread.fp_state.fpscr = buf[32];
> + return 0;
> +#else
> + BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
> + offsetof(struct thread_fp_state, fpr[32][0]));
> +
> + return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.fp_state, 0, -1);
> +#endif
> +}
> +
> +/*
> + * Checkpointed VMX
> + *
> + * struct data {
> + * vector128 vr[32];
> + * vector128 vscr;
> + * vector128 vrsave;
> + *};
> + */
> +static int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + void *kbuf, void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> + offsetof(struct thread_vr_state, vr[32]));
> +
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.vr_state, 0,
> + 33 * sizeof(vector128));
> + if (!ret) {
> + /*
> + * Copy out only the low-order word of vrsave.
> + */
> + union {
> + elf_vrreg_t reg;
> + u32 word;
> + } vrsave;
> + memset(&vrsave, 0, sizeof(vrsave));
> + vrsave.word = target->thread.vrsave;
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
> + 33 * sizeof(vector128), -1);
> + }
> + return ret;
> +}
> +
> +static int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> + int ret;
> +
> + flush_fp_to_thread(target);
> + flush_altivec_to_thread(target);
> + flush_tmreg_to_thread(target);
> +
> + BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
> + offsetof(struct thread_vr_state, vr[32]));
> +
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.vr_state, 0,
> + 33 * sizeof(vector128));
> + if (!ret && count > 0) {
> + /*
> + * We use only the first word of vrsave.
> + */
> + union {
> + elf_vrreg_t reg;
> + u32 word;
> + } vrsave;
> + memset(&vrsave, 0, sizeof(vrsave));
> + vrsave.word = target->thread.vrsave;
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
> + 33 * sizeof(vector128), -1);
> + if (!ret)
> + target->thread.vrsave = vrsave.word;
> + }
> + return ret;
> +}
> +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
> +
> +/*
> + * Miscellaneous Registers
> + *
> + * struct {
> + * unsigned long dscr;
> + * unsigned long ppr;
> + * unsigned long tar;
> + * };
> + */
> +static int misc_get(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + void *kbuf, void __user *ubuf)
> +{
> + int ret;
> +
> + /* DSCR register */
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.dscr, 0,
> + sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
> + sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
> +
> + /* PPR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.ppr, sizeof(unsigned long),
> + 2 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
> + != offsetof(struct thread_struct, tar));
> + /* TAR register */
> + if (!ret)
> + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tar, 2 * sizeof(unsigned long),
> + 3 * sizeof(unsigned long));
> + return ret;
> +}
> +
> +static int misc_set(struct task_struct *target, const struct user_regset *regset,
> + unsigned int pos, unsigned int count,
> + const void *kbuf, const void __user *ubuf)
> +{
> + int ret;
> +
> + /* DSCR register */
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.dscr, 0,
> + sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
> + sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
> +
> + /* PPR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.ppr, sizeof(unsigned long),
> + 2 * sizeof(unsigned long));
> +
> + BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
> + != offsetof(struct thread_struct, tar));
> +
> + /* TAR register */
> + if (!ret)
> + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
> + &target->thread.tar, 2 * sizeof(unsigned long),
> + 3 * sizeof(unsigned long));
> + return ret;
> +}
>
> /*
> * These are our native regset flavors.
> @@ -629,6 +1138,13 @@ enum powerpc_regset {
> #ifdef CONFIG_SPE
> REGSET_SPE,
> #endif
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + REGSET_TM_SPR, /* TM generic SPR */
> + REGSET_TM_CGPR, /* TM checkpointed GPR */
> + REGSET_TM_CFPR, /* TM checkpointed FPR */
> + REGSET_TM_CVMX, /* TM checkpointed VMX */
> +#endif
> + REGSET_MISC /* Miscellaneous */
> };
>
> static const struct user_regset native_regsets[] = {
> @@ -663,6 +1179,33 @@ static const struct user_regset native_regsets[] = {
> .active = evr_active, .get = evr_get, .set = evr_set
> },
> #endif
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + [REGSET_TM_SPR] = {
> + .core_note_type = NT_PPC_TM_SPR, .n = 7,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = tm_spr_get, .set = tm_spr_set
> + },
> + [REGSET_TM_CGPR] = {
> + .core_note_type = NT_PPC_TM_CGPR, .n = 14,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = tm_cgpr_get, .set = tm_cgpr_set
> + },
> + [REGSET_TM_CFPR] = {
> + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
> + .size = sizeof(double), .align = sizeof(double),
> + .get = tm_cfpr_get, .set = tm_cfpr_set
> + },
> + [REGSET_TM_CVMX] = {
> + .core_note_type = NT_PPC_TM_CVMX, .n = 34,
> + .size = sizeof(vector128), .align = sizeof(vector128),
> + .get = tm_cvmx_get, .set = tm_cvmx_set
> + },
> +#endif
> + [REGSET_MISC] = {
> + .core_note_type = NT_PPC_MISC, .n = 3,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = misc_get, .set = misc_set
> + },
> };
>
> static const struct user_regset_view user_ppc_native_view = {
> @@ -831,6 +1374,33 @@ static const struct user_regset compat_regsets[] = {
> .active = evr_active, .get = evr_get, .set = evr_set
> },
> #endif
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + [REGSET_TM_SPR] = {
> + .core_note_type = NT_PPC_TM_SPR, .n = 7,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = tm_spr_get, .set = tm_spr_set
> + },
> + [REGSET_TM_CGPR] = {
> + .core_note_type = NT_PPC_TM_CGPR, .n = 14,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = tm_cgpr_get, .set = tm_cgpr_set
> + },
> + [REGSET_TM_CFPR] = {
> + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
> + .size = sizeof(double), .align = sizeof(double),
> + .get = tm_cfpr_get, .set = tm_cfpr_set
> + },
> + [REGSET_TM_CVMX] = {
> + .core_note_type = NT_PPC_TM_CVMX, .n = 34,
> + .size = sizeof(vector128), .align = sizeof(vector128),
> + .get = tm_cvmx_get, .set = tm_cvmx_set
> + },
> +#endif
> + [REGSET_MISC] = {
> + .core_note_type = NT_PPC_MISC, .n = 3,
> + .size = sizeof(u64), .align = sizeof(u64),
> + .get = misc_get, .set = misc_set
> + },
> };
>
> static const struct user_regset_view user_ppc_compat_view = {
> @@ -1754,7 +2324,41 @@ long arch_ptrace(struct task_struct *child, long request,
> REGSET_SPE, 0, 35 * sizeof(u32),
> datavp);
> #endif
> +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> + case PTRACE_GETTM_SPRREGS:
> + return copy_regset_to_user(child, &user_ppc_native_view,
> + REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
> + case PTRACE_SETTM_SPRREGS:
> + return copy_regset_from_user(child, &user_ppc_native_view,
> + REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
> + case PTRACE_GETTM_CGPRREGS:
> + return copy_regset_to_user(child, &user_ppc_native_view,
> + REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
> + case PTRACE_SETTM_CGPRREGS:
> + return copy_regset_from_user(child, &user_ppc_native_view,
> + REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
> + case PTRACE_GETTM_CFPRREGS:
> + return copy_regset_to_user(child, &user_ppc_native_view,
> + REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
> + case PTRACE_SETTM_CFPRREGS:
> + return copy_regset_from_user(child, &user_ppc_native_view,
> + REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
> + case PTRACE_GETTM_CVMXREGS:
> + return copy_regset_to_user(child, &user_ppc_native_view,
> + REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
> + case PTRACE_SETTM_CVMXREGS:
> + return copy_regset_from_user(child, &user_ppc_native_view,
> + REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
> +#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
>
> + case PTRACE_GETMSCREGS:
> + return copy_regset_to_user(child, &user_ppc_native_view,
> + REGSET_MISC, 0, 3 * sizeof(u64),
> + datavp);
> + case PTRACE_SETMSCREGS:
> + return copy_regset_from_user(child, &user_ppc_native_view,
> + REGSET_MISC, 0, 3 * sizeof(u64),
> + datavp);
> default:
> ret = ptrace_request(child, request, addr, data);
> break;
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index ef6103b..13090e3 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -379,6 +379,11 @@ typedef struct elf64_shdr {
> #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
> #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
> #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
> +#define NT_PPC_TM_SPR 0x103 /* PowerPC transactional memory specific registers */
> +#define NT_PPC_TM_CGPR 0x104 /* PowerpC transactional memory checkpointed GPR */
> +#define NT_PPC_TM_CFPR 0x105 /* PowerPC transactional memory checkpointed FPR */
> +#define NT_PPC_TM_CVMX 0x106 /* PowerPC transactional memory checkpointed VMX */
> +#define NT_PPC_MISC 0x107 /* PowerPC miscellaneous registers */
> #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
> #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
> #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
> --
> 1.7.11.7
>
^ permalink raw reply
* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Nicolin Chen @ 2014-04-02 2:18 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401164254.GA2269@sirena.org.uk>
On Tue, Apr 01, 2014 at 05:42:54PM +0100, Mark Brown wrote:
> On Tue, Apr 01, 2014 at 09:21:57PM +0800, Nicolin Chen wrote:
>
> > Sir, I just rebased my for-next branch again and found that it's missing
> > two applied patches: "ASoC: fsl_sai: Add isr to deal with error flag" and
> > "ASoC: fsl_sai: Improve fsl_sai_isr()", so that's why this PATCH-2 could
> > not be applied against it as it needs the macro that's included in the
> > patch "ASoC: fsl_sai: Add isr to deal with error flag".
>
> Ah, those dropped out of -next due to the merge window. I've applied
> your new patch now.
I can find them on the fsl-sai topic now. Thank you.
^ permalink raw reply
* [PATCH] power, sched: stop updating inside arch_update_cpu_topology() when nothing to be update
From: Michael wang @ 2014-04-02 3:29 UTC (permalink / raw)
To: linuxppc-dev, LKML, benh, paulus, nfont, sfr, Andrew Morton, rcj,
jlarrew, srivatsa.bhat, alistair
During the testing, we encounter below WARN followed by Oops:
WARNING: at kernel/sched/core.c:6218
...
NIP [c000000000101660] .build_sched_domains+0x11d0/0x1200
LR [c000000000101358] .build_sched_domains+0xec8/0x1200
PACATMSCRATCH [800000000000f032]
Call Trace:
[c00000001b103850] [c000000000101358] .build_sched_domains+0xec8/0x1200
[c00000001b1039a0] [c00000000010aad4] .partition_sched_domains+0x484/0x510
[c00000001b103aa0] [c00000000016d0a8] .rebuild_sched_domains+0x68/0xa0
[c00000001b103b30] [c00000000005cbf0] .topology_work_fn+0x10/0x30
...
Oops: Kernel access of bad area, sig: 11 [#1]
...
NIP [c00000000045c000] .__bitmap_weight+0x60/0xf0
LR [c00000000010132c] .build_sched_domains+0xe9c/0x1200
PACATMSCRATCH [8000000000029032]
Call Trace:
[c00000001b1037a0] [c000000000288ff4] .kmem_cache_alloc_node_trace+0x184/0x3a0
[c00000001b103850] [c00000000010132c] .build_sched_domains+0xe9c/0x1200
[c00000001b1039a0] [c00000000010aad4] .partition_sched_domains+0x484/0x510
[c00000001b103aa0] [c00000000016d0a8] .rebuild_sched_domains+0x68/0xa0
[c00000001b103b30] [c00000000005cbf0] .topology_work_fn+0x10/0x30
...
This was caused by that 'sd->groups == NULL' after building groups, which
was caused by the empty 'sd->span'.
The cpu's domain contain nothing because the cpu was assigned to wrong
node inside arch_update_cpu_topology() by calling update_lookup_table()
with the uninitialized param, in the case when there is nothing to be
update.
Thus we should stop the updating in such cases, this patch will achieve
this and fix the issue.
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <paulus@samba.org>
CC: Nathan Fontenot <nfont@linux.vnet.ibm.com>
CC: Stephen Rothwell <sfr@canb.auug.org.au>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Robert Jennings <rcj@linux.vnet.ibm.com>
CC: Jesse Larrew <jlarrew@linux.vnet.ibm.com>
CC: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>
CC: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Michael Wang <wangyun@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 30a42e2..6757690 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1591,6 +1591,14 @@ int arch_update_cpu_topology(void)
cpu = cpu_last_thread_sibling(cpu);
}
+ /*
+ * The 'cpu_associativity_changes_mask' could be cleared if
+ * all the cpus it indicates won't change their node, in
+ * which case the 'updated_cpus' will be empty.
+ */
+ if (!cpumask_weight(&updated_cpus))
+ goto out;
+
stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
/*
@@ -1612,6 +1620,7 @@ int arch_update_cpu_topology(void)
changed = 1;
}
+out:
kfree(updates);
return changed;
}
--
1.7.9.5
^ permalink raw reply related
* Re: [RFC] powerpc, ptrace: Add few more ptrace request macros
From: Anshuman Khandual @ 2014-04-02 3:40 UTC (permalink / raw)
To: Michael Neuling; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <25834.1396399387@ale.ozlabs.ibm.com>
On 04/02/2014 06:13 AM, Michael Neuling wrote:
> Anshuman Khandual <khandual@linux.vnet.ibm.com> wrote:
>> > This patch adds few more ptrace request macros expanding
>> > the existing capability. These ptrace requests macros can
>> > be classified into two categories.
> Why is this only an RFC?
>
Looking for comments, suggestions, concerns from people. But looks
like its bit big a patch to review at once.
> Also, please share the test case that you wrote for this.
Will split the patch into multiple components, add the test case
and send out again.
^ permalink raw reply
* Re: [PATCH REPOST v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Benjamin Herrenschmidt @ 2014-04-02 4:23 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Gautham R. Shenoy, Linux PM list, Viresh Kumar, linux-kernel,
cpufreq, linuxppc-dev, Anton Blanchard, srivatsa.bhat
In-Reply-To: <1506880.SKUfks4BOU@vostro.rjw.lan>
On Wed, 2014-04-02 at 00:03 +0200, Rafael J. Wysocki wrote:
> > Rafael, are you going to take these or should I send them to Linus ?
> >
> > (I'd rather you take them :-)
>
> I can do that, but the timing is pretty bad. How urgent are they?
To be honest pretty urgent. It's a new drop-in driver so it shouldn't
be a huge deal.
We have distros really waiting for this to hit upstream... But I'll
leave that decision to you :-)
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 1/1] mm: move FAULT_AROUND_ORDER to arch/
From: Madhavan Srinivasan @ 2014-04-02 4:45 UTC (permalink / raw)
To: Dave Hansen, Kirill A. Shutemov
Cc: linux-arch, riel, rusty, peterz, x86, linux-kernel, linux-mm, ak,
paulus, mgorman, akpm, linuxppc-dev, mingo, kirill.shutemov
In-Reply-To: <5331C1C9.5020309@intel.com>
On Tuesday 25 March 2014 11:20 PM, Dave Hansen wrote:
> On 03/25/2014 10:36 AM, Kirill A. Shutemov wrote:
>>>> +/*
>>>> + * Fault around order is a control knob to decide the fault around pages.
>>>> + * Default value is set to 0UL (disabled), but the arch can override it as
>>>> + * desired.
>>>> + */
>>>> +#ifndef FAULT_AROUND_ORDER
>>>> +#define FAULT_AROUND_ORDER 0UL
>>>> +#endif
>> FAULT_AROUND_ORDER == 0 case should be handled separately in
>> do_read_fault(): no reason to go to do_fault_around() if we are going to
>> fault in only one page.
>
> Isn't this the kind of thing we want to do in Kconfig?
>
>
I am still investigating this option since this looks better. But it is
taking time, my bad. I will get back on this.
With Regards
Maddy
^ permalink raw reply
* Re: [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-04-02 5:27 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list
In-Reply-To: <1396395275.19762.28.camel@pasglop>
On Wed, 2014-04-02 at 10:34 +1100, Benjamin Herrenschmidt wrote:
> Hi Linus !
>
> This time around, the powerpc merges are going to be a little bit
> more complicated than usual.
Looks like I sent this one twice, one with "merge" and one with "next"
in the subject. They are otherwise identical (it's "next" really). I
though I had cancelled the sending of the first one with the bad subject
but it looks like my mailer was faster than me.
Cheers,
Ben.
^ permalink raw reply
* [PATCH 0/3] Add new ptrace request macros on PowerPC
From: Anshuman Khandual @ 2014-04-02 7:02 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, avagin, oleg, roland, Anshuman Khandual
This patch series adds new ELF note sections which are used to
create new ptrace request macros for various transactional memory and
miscellaneous registers on PowerPC. Please find the test case exploiting
the new ptrace request macros and it's results on a POWER8 system.
RFC: https://lkml.org/lkml/2014/4/1/292
============================== Results ==============================
-------TM specific SPR------
TM TFHAR: 100009dc
TM TEXASR: de000001ac000001
TM TFIAR: c00000000003f386
TM CH ORIG_MSR: 900000050000f032
TM CH TAR: 6
TM CH PPR: c000000000000
TM CH DSCR: 1
-------TM checkpointed GPR-----
TM CH GPR[0]: 1000097c
TM CH GPR[1]: 5
TM CH GPR[2]: 6
TM CH GPR[7]: 1
TM CH NIP: 100009dc
TM CH LINK: 1000097c
TM CH CCR: 22000422
-------TM running GPR-----
TM RN GPR[0]: 1000097c
TM RN GPR[1]: 7
TM RN GPR[2]: 8
TM RN GPR[7]: 5
TM RN NIP: 100009fc
TM RN LINK: 1000097c
TM RN CCR: 2000422
-------TM running FPR-----
TM RN FPR[0]: 1002d3a3780
TM RN FPR[1]: 7
TM RN FPR[2]: 8
TM RN FPSCR: 0
-------TM checkpointed FPR-----
TM CH FPR[0]: 1002d3a3780
TM CH FPR[1]: 5
TM CH FPR[2]: 6
TM CH FPSCR: 0
-------Running miscellaneous registers-------
TM RN DSCR: 0
TM RN PPR: c000000000000
TM RN TAR: 8
============================ Test case ==============================
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <linux/elf.h>
#include <linux/types.h>
typedef unsigned long u64;
typedef unsigned int u32;
typedef __vector128 vector128;
/* TM CFPR */
struct tm_cfpr {
u64 fpr[32];
u64 fpscr;
};
/* TM CVMX */
struct tm_cvmx {
vector128 vr[32] __attribute__((aligned(16)));
vector128 vscr __attribute__((aligned(16)));
u32 vrsave;
};
/* TM SPR */
struct tm_spr_regs {
u64 tm_tfhar;
u64 tm_texasr;
u64 tm_tfiar;
u64 tm_orig_msr;
u64 tm_tar;
u64 tm_ppr;
u64 tm_dscr;
};
/* Miscellaneous registers */
struct misc_regs {
u64 dscr;
u64 ppr;
u64 tar;
};
/* TM instructions */
#define TBEGIN ".long 0x7C00051D ;"
#define TEND ".long 0x7C00055D ;"
#define SPRN_DSCR 0x3
#define SPRN_TAR 815
/* Ptrace request macros */
#define PTRACE_GETTM_SPRREGS 0x70
#define PTRACE_SETTM_SPRREGS 0x71
#define PTRACE_GETTM_CGPRREGS 0x72
#define PTRACE_SETTM_CGPRREGS 0x73
#define PTRACE_GETTM_CFPRREGS 0x74
#define PTRACE_SETTM_CFPRREGS 0x75
#define PTRACE_GETTM_CVMXREG 0x76
#define PTRACE_SETTM_CVMXREG 0x77
#define PTRACE_GETMSCREGS 0x78
#define PTRACE_SETMSCREGS 0x79
int main(int argc, char *argv[])
{
struct tm_spr_regs *tmr1;
struct pt_regs *pregs1, *pregs2;
struct tm_cfpr *fpr, *fpr1;
struct tm_cvmx *vr1;
struct misc_regs *dbr1;
pid_t child;
int ret = 0, status = 0, i = 0, flag = 1;
tmr1 = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
pregs1 = (struct pt_regs *) malloc(sizeof(struct pt_regs));
pregs2 = (struct pt_regs *) malloc(sizeof(struct pt_regs));
fpr = (struct tm_cfpr *) malloc(sizeof(struct tm_cfpr));
fpr1 = (struct tm_cfpr *) malloc(sizeof(struct tm_cfpr));
vr1 = (struct tm_cvmx *) malloc(sizeof(struct tm_cvmx));
dbr1 = (struct misc_regs *) malloc(sizeof(struct misc_regs));
child = fork();
if (child < 0) {
printf("fork() failed \n");
exit(-1);
}
/* Child code */
if (child == 0) {
asm __volatile__(
"6: ;" /* TM checkpointed values */
"li 1, 5;" /* GPR[1] */
".long 0x7C210166;" /* FPR[1] */
"li 2, 6;" /* GPR[2] */
".long 0x7C420166;" /* FPR[2] */
"mtspr %[tar], 2;" /* TAR */
"li 7, 1;" /* GPR[7] */
"mtspr %[dscr], 7;" /* DSCR */
"1: ;"
TBEGIN /* TM running values */
"beq 2f ;"
"li 1, 7;" /* GPR[1] */
".long 0x7C210166;" /* FPR[1] */
"li 2, 8;" /* GPR[2] */
".long 0x7C420166;" /* FPR[2] */
"mtspr %[tar], 2;" /* TAR */
"li 7, 5;" /* GPR[7] */
"mtspr %[dscr], 7;" /* DSCR */
"b .;"
TEND
"2: ;" /* Abort handler */
"b 1b;" /* Start from TBEGIN */
"3: ;"
"b 6b;" /* Start all over again */
:: [dscr]"i"(SPRN_DSCR), [tar]"i"(SPRN_TAR)
: "memory", "r7");
}
/* Parent */
if (child) {
do {
/* Wait till child hits "b ." instruction */
sleep(3);
memset(tmr1, 0 , sizeof(struct tm_spr_regs));
memset(pregs1, 0 , sizeof(struct pt_regs));
memset(pregs2, 0 , sizeof(struct pt_regs));
memset(fpr1, 0 , sizeof(struct tm_cfpr));
memset(fpr, 0 , sizeof(struct tm_cfpr));
memset(vr1, 0 , sizeof(struct tm_cvmx));
memset(dbr1, 0 , sizeof(struct misc_regs));
ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
if (ret == -1) {
printf("PTRACE_ATTACH failed: %s\n", strerror(errno));
exit(-1);
}
ret = waitpid(child, NULL, 0);
if (ret != child) {
printf("PID does not match\n");
exit(-1);
}
/* TM specific SPR */
ret = ptrace(PTRACE_GETTM_SPRREGS, child, NULL, tmr1);
if (ret == -1) {
printf("PTRACE_GETTM_SPRREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------TM specific SPR------\n");
printf("TM TFHAR: %lx\n", tmr1->tm_tfhar);
printf("TM TEXASR: %lx\n", tmr1->tm_texasr);
printf("TM TFIAR: %lx\n", tmr1->tm_tfiar);
printf("TM CH ORIG_MSR: %lx\n", tmr1->tm_orig_msr);
printf("TM CH TAR: %lx\n", tmr1->tm_tar);
printf("TM CH PPR: %lx\n", tmr1->tm_ppr);
printf("TM CH DSCR: %lx\n", tmr1->tm_dscr);
/* TM checkpointed GPR */
ret = ptrace(PTRACE_GETTM_CGPRREGS, child, NULL, pregs1);
if (ret == -1) {
printf("PTRACE_GETTM_CGPRREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------TM checkpointed GPR-----\n");
printf("TM CH GPR[0]: %lx\n", pregs1->gpr[0]);
printf("TM CH GPR[1]: %lx\n", pregs1->gpr[1]);
printf("TM CH GPR[2]: %lx\n", pregs1->gpr[2]);
printf("TM CH GPR[7]: %lx\n", pregs1->gpr[7]);
printf("TM CH NIP: %lx\n", pregs1->nip);
printf("TM CH LINK: %lx\n", pregs1->link);
printf("TM CH CCR: %lx\n", pregs1->ccr);
/* TM running GPR */
ret = ptrace(PTRACE_GETREGS, child, NULL, pregs2);
if (ret == -1) {
printf("PTRACE_GETREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------TM running GPR-----\n");
printf("TM RN GPR[0]: %lx\n", pregs2->gpr[0]);
printf("TM RN GPR[1]: %lx\n", pregs2->gpr[1]);
printf("TM RN GPR[2]: %lx\n", pregs2->gpr[2]);
printf("TM RN GPR[7]: %lx\n", pregs2->gpr[7]);
printf("TM RN NIP: %lx\n", pregs2->nip);
printf("TM RN LINK: %lx\n", pregs2->link);
printf("TM RN CCR: %lx\n", pregs2->ccr);
/* TM running FPR */
ret = ptrace(PTRACE_GETFPREGS, child, NULL, fpr);
if (ret == -1) {
printf("PTRACE_GETFPREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------TM running FPR-----\n");
printf("TM RN FPR[0]: %lx\n", fpr->fpr[0]);
printf("TM RN FPR[1]: %lx\n", fpr->fpr[1]);
printf("TM RN FPR[2]: %lx\n", fpr->fpr[2]);
printf("TM RN FPSCR: %lx\n", fpr->fpscr);
/* TM checkpointed FPR */
ret = ptrace(PTRACE_GETTM_CFPRREGS, child, NULL, fpr1);
if (ret == -1) {
printf("PTRACE_GETTM_CFPRREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------TM checkpointed FPR-----\n");
printf("TM CH FPR[0]: %lx\n", fpr1->fpr[0]);
printf("TM CH FPR[1]: %lx\n", fpr1->fpr[1]);
printf("TM CH FPR[2]: %lx\n", fpr1->fpr[2]);
printf("TM CH FPSCR: %lx\n", fpr1->fpscr);
/* Misc debug */
ret = ptrace(PTRACE_GETMSCREGS, child, NULL, dbr1);
if (ret == -1) {
printf("PTRACE_GETMSCREGS failed: %s\n", strerror(errno));
exit(-1);
}
printf("-------Running miscellaneous registers-------\n");
printf("TM RN DSCR: %lx\n", dbr1->dscr);
printf("TM RN PPR: %lx\n", dbr1->ppr);
printf("TM RN TAR: %lx\n", dbr1->tar);
ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
if (ret == -1) {
printf("PTRACE_DETACH failed: %s\n", strerror(errno));
exit(-1);
}
} while (0);
}
return 0;
}
=====================================================================
Anshuman Khandual (3):
elf: Add some new PowerPC specifc note sections
powerpc, ptrace: Add new ptrace request macros for transactional memory
powerpc, ptrace: Add new ptrace request macro for miscellaneous registers
arch/powerpc/include/asm/switch_to.h | 8 +
arch/powerpc/include/uapi/asm/ptrace.h | 61 +++
arch/powerpc/kernel/process.c | 24 ++
arch/powerpc/kernel/ptrace.c | 659 +++++++++++++++++++++++++++++++--
include/uapi/linux/elf.h | 5 +
5 files changed, 729 insertions(+), 28 deletions(-)
--
1.7.11.7
^ permalink raw reply
* [PATCH 1/3] elf: Add some new PowerPC specifc note sections
From: Anshuman Khandual @ 2014-04-02 7:02 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, avagin, oleg, roland, Anshuman Khandual
In-Reply-To: <1396422144-11032-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds four new note sections for transactional memory
and one note section for some miscellaneous registers. This addition
of new elf note sections extends the existing elf ABI without affecting
it in any manner.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
include/uapi/linux/elf.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index ef6103b..bd59452 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -379,6 +379,11 @@ typedef struct elf64_shdr {
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_PPC_TM_SPR 0x103 /* PowerPC transactional memory special registers */
+#define NT_PPC_TM_CGPR 0x104 /* PowerpC transactional memory checkpointed GPR */
+#define NT_PPC_TM_CFPR 0x105 /* PowerPC transactional memory checkpointed FPR */
+#define NT_PPC_TM_CVMX 0x106 /* PowerPC transactional memory checkpointed VMX */
+#define NT_PPC_MISC 0x107 /* PowerPC miscellaneous registers */
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
--
1.7.11.7
^ permalink raw reply related
* [PATCH 3/3] powerpc, ptrace: Add new ptrace request macro for miscellaneous registers
From: Anshuman Khandual @ 2014-04-02 7:02 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, avagin, oleg, roland, Anshuman Khandual
In-Reply-To: <1396422144-11032-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds following new set of ptrace request macros for miscellaneous
registers expanding the existing ptrace ABI on PowerPC.
/* Miscellaneous registers */
PTRACE_GETMSCREGS
PTRACE_SETMSCREGS
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/uapi/asm/ptrace.h | 10 ++++
arch/powerpc/kernel/ptrace.c | 91 +++++++++++++++++++++++++++++++++-
2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index 1a12c36..bce1055 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -241,6 +241,16 @@ struct pt_regs {
#define PTRACE_GETTM_CVMXREGS 0x76
#define PTRACE_SETTM_CVMXREGS 0x77
+/* Miscellaneous registers */
+#define PTRACE_GETMSCREGS 0x78
+#define PTRACE_SETMSCREGS 0x79
+
+/*
+ * XXX: A note to application developers. The existing data layout
+ * of the above four ptrace requests can change when new registers
+ * are available for each category in forthcoming processors.
+ */
+
#ifndef __ASSEMBLY__
struct ppc_debug_info {
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 9fbcb6a..2893958 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1054,6 +1054,76 @@ static int tm_cvmx_set(struct task_struct *target, const struct user_regset *reg
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
/*
+ * Miscellaneous Registers
+ *
+ * struct {
+ * unsigned long dscr;
+ * unsigned long ppr;
+ * unsigned long tar;
+ * };
+ */
+static int misc_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ /* DSCR register */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.dscr, 0,
+ sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+ sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+ /* PPR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ppr, sizeof(unsigned long),
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+ != offsetof(struct thread_struct, tar));
+ /* TAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tar, 2 * sizeof(unsigned long),
+ 3 * sizeof(unsigned long));
+ return ret;
+}
+
+static int misc_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ /* DSCR register */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.dscr, 0,
+ sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+ sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+ /* PPR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ppr, sizeof(unsigned long),
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+ != offsetof(struct thread_struct, tar));
+
+ /* TAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tar, 2 * sizeof(unsigned long),
+ 3 * sizeof(unsigned long));
+ return ret;
+}
+
+/*
* These are our native regset flavors.
*/
enum powerpc_regset {
@@ -1072,8 +1142,9 @@ enum powerpc_regset {
REGSET_TM_SPR, /* TM specific SPR */
REGSET_TM_CGPR, /* TM checkpointed GPR */
REGSET_TM_CFPR, /* TM checkpointed FPR */
- REGSET_TM_CVMX /* TM checkpointed VMX */
+ REGSET_TM_CVMX, /* TM checkpointed VMX */
#endif
+ REGSET_MISC /* Miscellaneous */
};
static const struct user_regset native_regsets[] = {
@@ -1130,6 +1201,11 @@ static const struct user_regset native_regsets[] = {
.get = tm_cvmx_get, .set = tm_cvmx_set
},
#endif
+ [REGSET_MISC] = {
+ .core_note_type = NT_PPC_MISC, .n = 3,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = misc_get, .set = misc_set
+ },
};
static const struct user_regset_view user_ppc_native_view = {
@@ -1320,6 +1396,11 @@ static const struct user_regset compat_regsets[] = {
.get = tm_cvmx_get, .set = tm_cvmx_set
},
#endif
+ [REGSET_MISC] = {
+ .core_note_type = NT_PPC_MISC, .n = 3,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = misc_get, .set = misc_set
+ },
};
static const struct user_regset_view user_ppc_compat_view = {
@@ -2269,6 +2350,14 @@ long arch_ptrace(struct task_struct *child, long request,
return copy_regset_from_user(child, &user_ppc_native_view,
REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+ case PTRACE_GETMSCREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_MISC, 0, 3 * sizeof(u64),
+ datavp);
+ case PTRACE_SETMSCREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_MISC, 0, 3 * sizeof(u64),
+ datavp);
default:
ret = ptrace_request(child, request, addr, data);
break;
--
1.7.11.7
^ permalink raw reply related
* [PATCH 2/3] powerpc, ptrace: Add new ptrace request macros for transactional memory
From: Anshuman Khandual @ 2014-04-02 7:02 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, avagin, oleg, roland, Anshuman Khandual
In-Reply-To: <1396422144-11032-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds following new sets of ptrace request macros for transactional
memory expanding the existing ptrace ABI on PowerPC.
/* TM special purpose registers */
PTRACE_GETTM_SPRREGS
PTRACE_SETTM_SPRREGS
/* TM checkpointed GPR registers */
PTRACE_GETTM_CGPRREGS
PTRACE_SETTM_CGPRREGS
/* TM checkpointed FPR registers */
PTRACE_GETTM_CFPRREGS
PTRACE_SETTM_CFPRREGS
/* TM checkpointed VMX registers */
PTRACE_GETTM_CVMXREGS
PTRACE_SETTM_CVMXREGS
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/switch_to.h | 8 +
arch/powerpc/include/uapi/asm/ptrace.h | 51 +++
arch/powerpc/kernel/process.c | 24 ++
arch/powerpc/kernel/ptrace.c | 570 +++++++++++++++++++++++++++++++--
4 files changed, 625 insertions(+), 28 deletions(-)
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 0e83e7d..22095e2 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -80,6 +80,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
}
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+extern void flush_tmreg_to_thread(struct task_struct *);
+#else
+static inline void flush_tmreg_to_thread(struct task_struct *t)
+{
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+
static inline void clear_task_ebb(struct task_struct *t)
{
#ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index 77d2ed3..1a12c36 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -190,6 +190,57 @@ struct pt_regs {
#define PPC_PTRACE_SETHWDEBUG 0x88
#define PPC_PTRACE_DELHWDEBUG 0x87
+/* Transactional memory */
+
+/*
+ * TM specific SPR
+ *
+ * struct data {
+ * u64 tm_tfhar;
+ * u64 tm_texasr;
+ * u64 tm_tfiar;
+ * unsigned long tm_orig_msr;
+ * u64 tm_tar;
+ * u64 tm_ppr;
+ * u64 tm_dscr;
+ * };
+ */
+#define PTRACE_GETTM_SPRREGS 0x70
+#define PTRACE_SETTM_SPRREGS 0x71
+
+/*
+ * TM Checkpointed GPR
+ *
+ * struct data {
+ * struct pt_regs ckpt_regs;
+ * };
+ */
+#define PTRACE_GETTM_CGPRREGS 0x72
+#define PTRACE_SETTM_CGPRREGS 0x73
+
+/*
+ * TM Checkpointed FPR
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
+#define PTRACE_GETTM_CFPRREGS 0x74
+#define PTRACE_SETTM_CFPRREGS 0x75
+
+/*
+ * TM Checkpointed VMX
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * unsigned long vrsave;
+ *};
+ */
+#define PTRACE_GETTM_CVMXREGS 0x76
+#define PTRACE_SETTM_CVMXREGS 0x77
+
#ifndef __ASSEMBLY__
struct ppc_debug_info {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index af064d2..230a0ee 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -673,6 +673,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
}
}
+void flush_tmreg_to_thread(struct task_struct *tsk)
+{
+ /*
+ * If task is not current, it should have been flushed
+ * already to it's thread_struct during __switch_to().
+ */
+ if (tsk != current)
+ return;
+
+ preempt_disable();
+ if (tsk->thread.regs) {
+ /*
+ * If we are still current, the TM state need to
+ * be flushed to thread_struct as it will be still
+ * present in the current cpu
+ */
+ if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+ __switch_to_tm(tsk);
+ tm_recheckpoint_new_task(tsk);
+ }
+ }
+ preempt_enable();
+}
+
/*
* This is called if we are on the way out to userspace and the
* TIF_RESTORE_TM flag is set. It checks if we need to reload
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 2e3d2bf..9fbcb6a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -357,6 +357,17 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
return ret;
}
+/*
+ * When any transaction is active, "thread_struct->transact_fp" holds
+ * the current running value of all FPR registers and "thread_struct->
+ * fp_state" holds the last checkpointed FPR registers state for the
+ * current transaction.
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
static int fpr_get(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
@@ -365,21 +376,41 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
u64 buf[33];
int i;
#endif
- flush_fp_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_fp_to_thread(target);
+ }
#ifdef CONFIG_VSX
/* copy to local buffer then write that out */
- for (i = 0; i < 32 ; i++)
- buf[i] = target->thread.TS_FPR(i);
- buf[32] = target->thread.fp_state.fpscr;
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_TRANS_FPR(i);
+ buf[32] = target->thread.transact_fp.fpscr;
+ } else {
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_FPR(i);
+ buf[32] = target->thread.fp_state.fpscr;
+ }
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
#else
- BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
- offsetof(struct thread_fp_state, fpr[32][0]));
+ if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+ BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+ offsetof(struct transact_fp, fpr[32][0]));
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.transact_fp, 0, -1);
+ } esle {
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.fp_state, 0, -1);
+ }
#endif
}
@@ -391,23 +422,44 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
u64 buf[33];
int i;
#endif
- flush_fp_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_fp_to_thread(target);
+ }
#ifdef CONFIG_VSX
/* copy to local buffer then write that out */
i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
if (i)
return i;
- for (i = 0; i < 32 ; i++)
- target->thread.TS_FPR(i) = buf[i];
- target->thread.fp_state.fpscr = buf[32];
+ for (i = 0; i < 32 ; i++) {
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.TS_TRANS_FPR(i) = buf[i];
+ else
+ target->thread.TS_FPR(i) = buf[i];
+ }
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.transact_fp.fpscr = buf[32];
+ else
+ target->thread.fp_state.fpscr = buf[32];
return 0;
#else
- BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
- offsetof(struct thread_fp_state, fpr[32][0]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+ offsetof(struct transact_fp, fpr[32][0]));
- return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fp_state, 0, -1);
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.transact_fp, 0, -1);
+ } else {
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fp_state, 0, -1);
+ }
#endif
}
@@ -432,20 +484,44 @@ static int vr_active(struct task_struct *target,
return target->thread.used_vr ? regset->n : 0;
}
+/*
+ * When any transaction is active, "thread_struct->transact_vr" holds
+ * the current running value of all VMX registers and "thread_struct->
+ * vr_state" holds the last checkpointed value of VMX registers for the
+ * current transaction.
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * vector128 vrsave;
+ * };
+ */
static int vr_get(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
int ret;
+ struct thread_vr_state *addr;
- flush_altivec_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_altivec_to_thread(target);
+ }
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
offsetof(struct thread_vr_state, vr[32]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ addr = &target->thread.transact_vr;
+ else
+ addr = &target->thread.vr_state;
+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.vr_state, 0,
- 33 * sizeof(vector128));
+ addr, 0, 33 * sizeof(vector128));
+
if (!ret) {
/*
* Copy out only the low-order word of vrsave.
@@ -455,11 +531,14 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
u32 word;
} vrsave;
memset(&vrsave, 0, sizeof(vrsave));
- vrsave.word = target->thread.vrsave;
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ vrsave.word = target->thread.transact_vrsave;
+ else
+ vrsave.word = target->thread.vrsave;
+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
33 * sizeof(vector128), -1);
}
-
return ret;
}
@@ -467,16 +546,27 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
+ struct thread_vr_state *addr;
int ret;
- flush_altivec_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_altivec_to_thread(target);
+ }
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
offsetof(struct thread_vr_state, vr[32]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ addr = &target->thread.transact_vr;
+ else
+ addr = &target->thread.vr_state;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.vr_state, 0,
- 33 * sizeof(vector128));
+ addr, 0, 33 * sizeof(vector128));
+
if (!ret && count > 0) {
/*
* We use only the first word of vrsave.
@@ -486,13 +576,21 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
u32 word;
} vrsave;
memset(&vrsave, 0, sizeof(vrsave));
- vrsave.word = target->thread.vrsave;
+
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ vrsave.word = target->thread.transact_vrsave;
+ else
+ vrsave.word = target->thread.vrsave;
+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
33 * sizeof(vector128), -1);
- if (!ret)
- target->thread.vrsave = vrsave.word;
+ if (!ret) {
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.transact_vrsave = vrsave.word;
+ else
+ target->thread.vrsave = vrsave.word;
+ }
}
-
return ret;
}
#endif /* CONFIG_ALTIVEC */
@@ -613,6 +711,347 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
}
#endif /* CONFIG_SPE */
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+
+/*
+ * Transactional memory SPR
+ *
+ * struct {
+ * u64 tm_tfhar;
+ * u64 tm_texasr;
+ * u64 tm_tfiar;
+ * unsigned long tm_orig_msr;
+ * unsigned long tm_tar;
+ * unsigned long tm_ppr;
+ * unsigned long tm_dscr;
+ * };
+ */
+static int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ /* TFHAR register */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfhar, 0, sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+ /* TEXASR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+ /* TFIAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+ /* TM checkpointed original MSR */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_orig_msr, 3 * sizeof(u64),
+ 3 * sizeof(u64) + sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr) +
+ sizeof(unsigned long) + sizeof(struct pt_regs)
+ != offsetof(struct thread_struct, tm_tar));
+
+ /* TM checkpointed TAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tar, 3 * sizeof(u64) +
+ sizeof(unsigned long) , 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+ + sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_ppr));
+
+ /* TM checkpointed PPR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_ppr, 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long), 3 * sizeof(u64) +
+ 3 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+ sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_dscr));
+
+ /* TM checkpointed DSCR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_dscr, 3 * sizeof(u64)
+ + 3 * sizeof(unsigned long), 3 * sizeof(u64)
+ + 4 * sizeof(unsigned long));
+ return ret;
+}
+
+static int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ /* TFHAR register */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfhar, 0, sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+ /* TEXASR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+ /* TFIAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+ /* TM checkpointed orig MSR */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_orig_msr, 3 * sizeof(u64),
+ 3 * sizeof(u64) + sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr)
+ + sizeof(unsigned long) + sizeof(struct pt_regs) !=
+ offsetof(struct thread_struct, tm_tar));
+
+ /* TM checkpointed TAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tar, 3 * sizeof(u64) +
+ sizeof(unsigned long), 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+ + sizeof(unsigned long) != offsetof(struct thread_struct, tm_ppr));
+
+ /* TM checkpointed PPR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_ppr, 3 * sizeof(u64)
+ + 2 * sizeof(unsigned long), 3 * sizeof(u64)
+ + 3 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+ sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_dscr));
+
+ /* TM checkpointed DSCR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_dscr,
+ 3 * sizeof(u64) + 3 * sizeof(unsigned long),
+ 3 * sizeof(u64) + 4 * sizeof(unsigned long));
+
+ return ret;
+}
+
+/*
+ * TM Checkpointed GPR
+ *
+ * struct data {
+ * struct pt_regs ckpt_regs;
+ * };
+ */
+static int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ckpt_regs, 0,
+ sizeof(struct pt_regs));
+ return ret;
+}
+
+static int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ckpt_regs, 0,
+ sizeof(struct pt_regs));
+ return ret;
+}
+
+/*
+ * TM Checkpointed FPR
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
+static int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+ u64 buf[33];
+ int i;
+#endif
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+ /* copy to local buffer then write that out */
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_FPR(i);
+ buf[32] = target->thread.fp_state.fpscr;
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+
+#else
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.thread_fp_state, 0, -1);
+#endif
+}
+
+static int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+ u64 buf[33];
+ int i;
+#endif
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+ /* copy to local buffer then write that out */
+ i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+ if (i)
+ return i;
+ for (i = 0; i < 32 ; i++)
+ target->thread.TS_FPR(i) = buf[i];
+ target->thread.fp_state.fpscr = buf[32];
+ return 0;
+#else
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fp_state, 0, -1);
+#endif
+}
+
+/*
+ * TM Checkpointed VMX
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * vector128 vrsave;
+ *};
+ */
+static int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+ offsetof(struct thread_vr_state, vr[32]));
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.vr_state, 0,
+ 33 * sizeof(vector128));
+ if (!ret) {
+ /*
+ * Copy out only the low-order word of vrsave.
+ */
+ union {
+ elf_vrreg_t reg;
+ u32 word;
+ } vrsave;
+ memset(&vrsave, 0, sizeof(vrsave));
+ vrsave.word = target->thread.vrsave;
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
+ 33 * sizeof(vector128), -1);
+ }
+ return ret;
+}
+
+static int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+ offsetof(struct thread_vr_state, vr[32]));
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.vr_state, 0,
+ 33 * sizeof(vector128));
+ if (!ret && count > 0) {
+ /*
+ * We use only the first word of vrsave.
+ */
+ union {
+ elf_vrreg_t reg;
+ u32 word;
+ } vrsave;
+ memset(&vrsave, 0, sizeof(vrsave));
+ vrsave.word = target->thread.vrsave;
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
+ 33 * sizeof(vector128), -1);
+ if (!ret)
+ target->thread.vrsave = vrsave.word;
+ }
+ return ret;
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
/*
* These are our native regset flavors.
@@ -629,6 +1068,12 @@ enum powerpc_regset {
#ifdef CONFIG_SPE
REGSET_SPE,
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ REGSET_TM_SPR, /* TM specific SPR */
+ REGSET_TM_CGPR, /* TM checkpointed GPR */
+ REGSET_TM_CFPR, /* TM checkpointed FPR */
+ REGSET_TM_CVMX /* TM checkpointed VMX */
+#endif
};
static const struct user_regset native_regsets[] = {
@@ -663,6 +1108,28 @@ static const struct user_regset native_regsets[] = {
.active = evr_active, .get = evr_get, .set = evr_set
},
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ [REGSET_TM_SPR] = {
+ .core_note_type = NT_PPC_TM_SPR, .n = 7,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_spr_get, .set = tm_spr_set
+ },
+ [REGSET_TM_CGPR] = {
+ .core_note_type = NT_PPC_TM_CGPR, .n = 14,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_cgpr_get, .set = tm_cgpr_set
+ },
+ [REGSET_TM_CFPR] = {
+ .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+ .size = sizeof(double), .align = sizeof(double),
+ .get = tm_cfpr_get, .set = tm_cfpr_set
+ },
+ [REGSET_TM_CVMX] = {
+ .core_note_type = NT_PPC_TM_CVMX, .n = 34,
+ .size = sizeof(vector128), .align = sizeof(vector128),
+ .get = tm_cvmx_get, .set = tm_cvmx_set
+ },
+#endif
};
static const struct user_regset_view user_ppc_native_view = {
@@ -831,6 +1298,28 @@ static const struct user_regset compat_regsets[] = {
.active = evr_active, .get = evr_get, .set = evr_set
},
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ [REGSET_TM_SPR] = {
+ .core_note_type = NT_PPC_TM_SPR, .n = 7,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_spr_get, .set = tm_spr_set
+ },
+ [REGSET_TM_CGPR] = {
+ .core_note_type = NT_PPC_TM_CGPR, .n = 14,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_cgpr_get, .set = tm_cgpr_set
+ },
+ [REGSET_TM_CFPR] = {
+ .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+ .size = sizeof(double), .align = sizeof(double),
+ .get = tm_cfpr_get, .set = tm_cfpr_set
+ },
+ [REGSET_TM_CVMX] = {
+ .core_note_type = NT_PPC_TM_CVMX, .n = 34,
+ .size = sizeof(vector128), .align = sizeof(vector128),
+ .get = tm_cvmx_get, .set = tm_cvmx_set
+ },
+#endif
};
static const struct user_regset_view user_ppc_compat_view = {
@@ -1754,7 +2243,32 @@ long arch_ptrace(struct task_struct *child, long request,
REGSET_SPE, 0, 35 * sizeof(u32),
datavp);
#endif
-
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ case PTRACE_GETTM_SPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+ case PTRACE_SETTM_SPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+ case PTRACE_GETTM_CGPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+ case PTRACE_SETTM_CGPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+ case PTRACE_GETTM_CFPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+ case PTRACE_SETTM_CFPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+ case PTRACE_GETTM_CVMXREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+ case PTRACE_SETTM_CVMXREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
default:
ret = ptrace_request(child, request, addr, data);
break;
--
1.7.11.7
^ permalink raw reply related
* Re: [alsa-devel] [PATCH 0/2] Add ipg clock control to sai driver
From: Nicolin Chen @ 2014-04-02 8:01 UTC (permalink / raw)
To: Nicolin Chen
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
Li.Xiubo, ijc+devicetree, linux-kernel, robh+dt, Timur Tabi,
broonie, rob, galak, Shawn Guo, linuxppc-dev
In-Reply-To: <cover.1396352401.git.Guangyu.Chen@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 1164 bytes --]
Please disregard this version.
SAI actually has three master clocks and one bus clock.
So the patch should have added three sai_clks to the driver.
I'll later send v2 to append the other two.
Thank you.
On Tue, Apr 1, 2014 at 7:52 PM, Nicolin Chen <Guangyu.Chen@freescale.com>wrote:
> This series of patches add ipg clock control to fsl_sai driver and updates
> the vf610.dtsi accordingly.
>
> @Shawn
> I'm not sure if VF610 currently does full works with SAI audio function.
> The PATCH-2 is based on broonie/for-next.
>
> Nicolin Chen (2):
> ASoC: fsl_sai: Add clock control for SAI
> ARM: dts: Add ipg clock for sai2 on VF610 platform
>
> .../devicetree/bindings/sound/fsl-sai.txt | 7 ++--
> arch/arm/boot/dts/vf610.dtsi | 4 +--
> sound/soc/fsl/fsl_sai.c | 37
> ++++++++++++++++++++--
> sound/soc/fsl/fsl_sai.h | 2 ++
> 4 files changed, 43 insertions(+), 7 deletions(-)
>
> --
> 1.8.4
>
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
[-- Attachment #2: Type: text/html, Size: 1846 bytes --]
^ permalink raw reply
* Re: [PATCH 0/3] Add new ptrace request macros on PowerPC
From: Anshuman Khandual @ 2014-04-02 9:32 UTC (permalink / raw)
To: Anshuman Khandual; +Cc: mikey, avagin, oleg, linux-kernel, linuxppc-dev, roland
In-Reply-To: <1396422144-11032-1-git-send-email-khandual@linux.vnet.ibm.com>
On 04/02/2014 12:32 PM, Anshuman Khandual wrote:
> This patch series adds new ELF note sections which are used to
> create new ptrace request macros for various transactional memory and
> miscellaneous registers on PowerPC. Please find the test case exploiting
> the new ptrace request macros and it's results on a POWER8 system.
>
> RFC: https://lkml.org/lkml/2014/4/1/292
>
> ============================== Results ==============================
> -------TM specific SPR------
> TM TFHAR: 100009dc
> TM TEXASR: de000001ac000001
> TM TFIAR: c00000000003f386
> TM CH ORIG_MSR: 900000050000f032
> TM CH TAR: 6
> TM CH PPR: c000000000000
> TM CH DSCR: 1
> -------TM checkpointed GPR-----
> TM CH GPR[0]: 1000097c
> TM CH GPR[1]: 5
> TM CH GPR[2]: 6
> TM CH GPR[7]: 1
> TM CH NIP: 100009dc
> TM CH LINK: 1000097c
> TM CH CCR: 22000422
> -------TM running GPR-----
> TM RN GPR[0]: 1000097c
> TM RN GPR[1]: 7
> TM RN GPR[2]: 8
> TM RN GPR[7]: 5
> TM RN NIP: 100009fc
> TM RN LINK: 1000097c
> TM RN CCR: 2000422
> -------TM running FPR-----
> TM RN FPR[0]: 1002d3a3780
> TM RN FPR[1]: 7
> TM RN FPR[2]: 8
> TM RN FPSCR: 0
> -------TM checkpointed FPR-----
> TM CH FPR[0]: 1002d3a3780
> TM CH FPR[1]: 5
> TM CH FPR[2]: 6
> TM CH FPSCR: 0
> -------Running miscellaneous registers-------
TM RN DSCR: 0
There is a problem in here which I forgot to mention. The running DSCR value
comes from thread->dscr component of the target process. While we are inside the
transaction (which is the case here as we are stuck at "b ." instruction and
have not reached TEND) thread->dscr should have the running value of the DSCR
register at that point of time. Here we expect the DSCR value to be 5 instead
of 0 as shown in the output above. During the tests when I moved the "b ." after
TEND, the thread->dscr gets the value of 5 while all check pointed reg values are
thrown away. I believe there is some problem in the way thread->dscr context
is saved away inside the TM section. Will look into this problem further and
keep informed.
^ permalink raw reply
* Re: [PATCH] cpuidle: add freescale e500 family porcessors idle support
From: Daniel Lezcano @ 2014-04-02 9:36 UTC (permalink / raw)
To: Dongsheng Wang, scottwood
Cc: chenhui.zhao, linux-pm, rjw, jason.jin, linuxppc-dev
In-Reply-To: <1396341234-40515-1-git-send-email-dongsheng.wang@freescale.com>
On 04/01/2014 10:33 AM, Dongsheng Wang wrote:
> From: Wang Dongsheng <dongsheng.wang@freescale.com>
>
> Add cpuidle support for e500 family, using cpuidle framework to
> manage various low power modes. The new implementation will remain
> compatible with original idle method.
>
> I have done test about power consumption and latency. Cpuidle framework
> will make CPU response time faster than original method, but power
> consumption is higher than original method.
>
> Power consumption:
> The original method, power consumption is 10.51202 (W).
> The cpuidle framework, power consumption is 10.5311 (W).
>
> Latency:
> The original method, avg latency is 6782 (us).
> The cpuidle framework, avg latency is 6482 (us).
>
> Initially, this supports PW10, PW20 and subsequent patches will support
> DOZE/NAP and PH10, PH20.
>
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
>
> diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
> index 5b6c03f..9301420 100644
> --- a/arch/powerpc/include/asm/machdep.h
> +++ b/arch/powerpc/include/asm/machdep.h
> @@ -294,6 +294,15 @@ extern void power7_idle(void);
> extern void ppc6xx_idle(void);
> extern void book3e_idle(void);
>
> +static inline void cpuidle_wait(void)
> +{
> +#ifdef CONFIG_PPC64
> + book3e_idle();
> +#else
> + e500_idle();
> +#endif
> +}
> +
> /*
> * ppc_md contains a copy of the machine description structure for the
> * current platform. machine_id contains the initial address where the
> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
> index 97e1dc9..edd193f 100644
> --- a/arch/powerpc/kernel/sysfs.c
> +++ b/arch/powerpc/kernel/sysfs.c
> @@ -190,6 +190,9 @@ static ssize_t show_pw20_wait_time(struct device *dev,
> return sprintf(buf, "%llu\n", time > 0 ? time : 0);
> }
>
> +#ifdef CONFIG_CPU_IDLE_E500
> +u32 cpuidle_entry_bit;
> +#endif
> static void set_pw20_wait_entry_bit(void *val)
> {
> u32 *value = val;
> @@ -204,7 +207,11 @@ static void set_pw20_wait_entry_bit(void *val)
> /* set count */
> pw20_idle |= ((MAX_BIT - *value) << PWRMGTCR0_PW20_ENT_SHIFT);
>
> +#ifdef CONFIG_CPU_IDLE_E500
> + cpuidle_entry_bit = *value;
> +#else
> mtspr(SPRN_PWRMGTCR0, pw20_idle);
> +#endif
> }
>
> static ssize_t store_pw20_wait_time(struct device *dev,
> diff --git a/drivers/cpuidle/Kconfig.powerpc b/drivers/cpuidle/Kconfig.powerpc
> index 66c3a09..0949dbf 100644
> --- a/drivers/cpuidle/Kconfig.powerpc
> +++ b/drivers/cpuidle/Kconfig.powerpc
> @@ -18,3 +18,10 @@ config POWERNV_CPUIDLE
> help
> Select this option to enable processor idle state management
> through cpuidle subsystem.
> +
> +config CPU_IDLE_E500
> + bool "CPU Idle Driver for E500 family processors"
> + depends on CPU_IDLE
> + depends on FSL_SOC_BOOKE
> + help
> + Select this to enable cpuidle on e500 family processors.
> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
> index f71ae1b..7e6adea 100644
> --- a/drivers/cpuidle/Makefile
> +++ b/drivers/cpuidle/Makefile
> @@ -18,3 +18,4 @@ obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
> # POWERPC drivers
> obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o
> obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
> +obj-$(CONFIG_CPU_IDLE_E500) += cpuidle-e500.o
> diff --git a/drivers/cpuidle/cpuidle-e500.c b/drivers/cpuidle/cpuidle-e500.c
> new file mode 100644
> index 0000000..ddc0def
> --- /dev/null
> +++ b/drivers/cpuidle/cpuidle-e500.c
> @@ -0,0 +1,194 @@
> +/*
> + * CPU Idle driver for Freescale PowerPC e500 family processors.
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + *
> + * Author: Dongsheng Wang <dongsheng.wang@freescale.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/cpu.h>
> +#include <linux/cpuidle.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/notifier.h>
> +
> +#include <asm/cputable.h>
> +#include <asm/machdep.h>
> +#include <asm/mpc85xx.h>
> +
> +static unsigned int max_idle_state;
> +static struct cpuidle_state *cpuidle_state_table;
> +
> +struct cpuidle_driver e500_idle_driver = {
> + .name = "e500_idle",
> + .owner = THIS_MODULE,
> +};
> +
> +static void e500_cpuidle(void)
> +{
> + if (cpuidle_idle_call())
> + cpuidle_wait();
> +}
Nope, that has been changed. No more call to cpuidle_idle_call in a driver.
> +
> +static int pw10_enter(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int index)
> +{
> + cpuidle_wait();
> + return index;
> +}
> +
> +#define MAX_BIT 63
> +#define MIN_BIT 1
> +extern u32 cpuidle_entry_bit;
> +static int pw20_enter(struct cpuidle_device *dev,
> + struct cpuidle_driver *drv, int index)
> +{
> + u32 pw20_idle;
> + u32 entry_bit;
> + pw20_idle = mfspr(SPRN_PWRMGTCR0);
> + if ((pw20_idle & PWRMGTCR0_PW20_ENT) != PWRMGTCR0_PW20_ENT) {
> + pw20_idle &= ~PWRMGTCR0_PW20_ENT;
> + entry_bit = MAX_BIT - cpuidle_entry_bit;
> + pw20_idle |= (entry_bit << PWRMGTCR0_PW20_ENT_SHIFT);
> + mtspr(SPRN_PWRMGTCR0, pw20_idle);
> + }
> +
> + cpuidle_wait();
> +
> + pw20_idle &= ~PWRMGTCR0_PW20_ENT;
> + pw20_idle |= (MIN_BIT << PWRMGTCR0_PW20_ENT_SHIFT);
> + mtspr(SPRN_PWRMGTCR0, pw20_idle);
> +
> + return index;
> +}
Is it possible to give some comments and encapsulate the code with
explicit function names to be implemented in an arch specific directory
file (eg. pm.c) and export these functions in a linux/ header ? We try
to prevent to include asm if possible.
> +
> +static struct cpuidle_state pw_idle_states[] = {
> + {
> + .name = "pw10",
> + .desc = "pw10",
> + .flags = CPUIDLE_FLAG_TIME_VALID,
> + .exit_latency = 0,
> + .target_residency = 0,
> + .enter = &pw10_enter
> + },
> +
> + {
> + .name = "pw20",
> + .desc = "pw20-core-idle",
> + .flags = CPUIDLE_FLAG_TIME_VALID,
> + .exit_latency = 1,
> + .target_residency = 50,
> + .enter = &pw20_enter
> + },
> +};
No need to define this intermediate structure here, you can directly
initialize the cpuidle_driver:
struct cpuidle_driver e500_idle_driver = {
.name = "e500_idle",
.owner = THIS_MODULE,
.states = {
.name = "pw10",
.desc = "pw10",
.flags = CPUIDLE_FLAG_TIME_VALID,
.target_residency = 0,
.enter = &pw10_enter,
},
....
.state_count = 2,
};
Then in the init function you initialize the state_count consequently:
if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
drv->state_count = 1;
Then you can kill:
max_idle_state, cpuidle_state_table, e500_idle_state_probe and
pw_idle_states.
> +
> +static int cpu_hotplug_notify(struct notifier_block *n,
> + unsigned long action, void *hcpu)
> +{
> + unsigned long hotcpu = (unsigned long)hcpu;
> + struct cpuidle_device *dev =
> + per_cpu_ptr(cpuidle_devices, hotcpu);
> +
> + if (dev && cpuidle_get_driver()) {
> + switch (action) {
> + case CPU_ONLINE:
> + case CPU_ONLINE_FROZEN:
> + cpuidle_pause_and_lock();
> + cpuidle_enable_device(dev);
> + cpuidle_resume_and_unlock();
> + break;
> +
> + case CPU_DEAD:
> + case CPU_DEAD_FROZEN:
> + cpuidle_pause_and_lock();
> + cpuidle_disable_device(dev);
> + cpuidle_resume_and_unlock();
> + break;
> +
> + default:
> + return NOTIFY_DONE;
> + }
> + }
> +
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block cpu_hotplug_notifier = {
> + .notifier_call = cpu_hotplug_notify,
> +};
Can you explain why this is needed ?
> +static void e500_cpuidle_driver_init(void)
> +{
> + int idle_state;
> + struct cpuidle_driver *drv = &e500_idle_driver;
Pass the cpuidle_driver as parameter to the function.
> +
> + drv->state_count = 0;
> +
> + for (idle_state = 0; idle_state < max_idle_state; ++idle_state) {
> + if (!cpuidle_state_table[idle_state].enter)
> + break;
> +
> + drv->states[drv->state_count] = cpuidle_state_table[idle_state];
> + drv->state_count++;
> + }
This code should disappear.
As this function will just initialize state_count, you can move it in
caller and kill this function.
> +}
> +
> +static int e500_idle_state_probe(void)
> +{
> + if (cpuidle_disable != IDLE_NO_OVERRIDE)
> + return -ENODEV;
> +
> + cpuidle_state_table = pw_idle_states;
> + max_idle_state = ARRAY_SIZE(pw_idle_states);
> +
> + /* Disable PW20 feature for e500mc, e5500 */
> + if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
> + cpuidle_state_table[1].enter = NULL;
> +
> + if (!cpuidle_state_table || !max_idle_state)
> + return -ENODEV;
> +
> + return 0;
> +}
This code should disappear.
> +static void replace_orig_idle(void *dummy)
> +{
> + return;
> +}
> +
> +static int __init e500_idle_init(void)
> +{
> + struct cpuidle_driver *drv = &e500_idle_driver;
> + int err;
> +
> + if (e500_idle_state_probe())
> + return -ENODEV;
> +
> + e500_cpuidle_driver_init();
> + if (!drv->state_count)
> + return -ENODEV;
No need of this check, because:
1. you know how you initialized the driver (1 or 2 states)
2. this is already by the cpuidle framework
> +
> + err = cpuidle_register(drv, NULL);
> + if (err) {
> + pr_err("Register e500 family cpuidle driver failed.\n");
extra carriage return.
> +
> + return err;
> + }
> +
> + err = register_cpu_notifier(&cpu_hotplug_notifier);
> + if (err)
> + pr_warn("Cpuidle driver: register cpu notifier failed.\n");
> +
> + /* Replace the original way of idle after cpuidle registered. */
> + ppc_md.power_save = e500_cpuidle;
> + on_each_cpu(replace_orig_idle, NULL, 1);
Why ?
> + pr_info("e500_idle_driver registered.\n");
> +
> + return 0;
> +}
> +late_initcall(e500_idle_init);
>
Thanks
-- Daniel
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* Re: [PATCH] cpuidle: add freescale e500 family porcessors idle support
From: Daniel Lezcano @ 2014-04-02 9:39 UTC (permalink / raw)
To: Dongsheng Wang, scottwood
Cc: chenhui.zhao, linux-pm, Rafael J. Wysocki, jason.jin,
linuxppc-dev
In-Reply-To: <533BDA11.9080905@linaro.org>
On 04/02/2014 11:36 AM, Daniel Lezcano wrote:
> On 04/01/2014 10:33 AM, Dongsheng Wang wrote:
>> From: Wang Dongsheng <dongsheng.wang@freescale.com>
>>
>> Add cpuidle support for e500 family, using cpuidle framework to
>> manage various low power modes. The new implementation will remain
>> compatible with original idle method.
>>
>> I have done test about power consumption and latency. Cpuidle framework
>> will make CPU response time faster than original method, but power
>> consumption is higher than original method.
>>
>> Power consumption:
>> The original method, power consumption is 10.51202 (W).
>> The cpuidle framework, power consumption is 10.5311 (W).
>>
>> Latency:
>> The original method, avg latency is 6782 (us).
>> The cpuidle framework, avg latency is 6482 (us).
>>
>> Initially, this supports PW10, PW20 and subsequent patches will support
>> DOZE/NAP and PH10, PH20.
>>
>> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
Please fix Rafael's email when resending/answering.
Thanks
-- Daniel
>> diff --git a/arch/powerpc/include/asm/machdep.h
>> b/arch/powerpc/include/asm/machdep.h
>> index 5b6c03f..9301420 100644
>> --- a/arch/powerpc/include/asm/machdep.h
>> +++ b/arch/powerpc/include/asm/machdep.h
>> @@ -294,6 +294,15 @@ extern void power7_idle(void);
>> extern void ppc6xx_idle(void);
>> extern void book3e_idle(void);
>>
>> +static inline void cpuidle_wait(void)
>> +{
>> +#ifdef CONFIG_PPC64
>> + book3e_idle();
>> +#else
>> + e500_idle();
>> +#endif
>> +}
>> +
>> /*
>> * ppc_md contains a copy of the machine description structure for the
>> * current platform. machine_id contains the initial address where the
>> diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
>> index 97e1dc9..edd193f 100644
>> --- a/arch/powerpc/kernel/sysfs.c
>> +++ b/arch/powerpc/kernel/sysfs.c
>> @@ -190,6 +190,9 @@ static ssize_t show_pw20_wait_time(struct device
>> *dev,
>> return sprintf(buf, "%llu\n", time > 0 ? time : 0);
>> }
>>
>> +#ifdef CONFIG_CPU_IDLE_E500
>> +u32 cpuidle_entry_bit;
>> +#endif
>> static void set_pw20_wait_entry_bit(void *val)
>> {
>> u32 *value = val;
>> @@ -204,7 +207,11 @@ static void set_pw20_wait_entry_bit(void *val)
>> /* set count */
>> pw20_idle |= ((MAX_BIT - *value) << PWRMGTCR0_PW20_ENT_SHIFT);
>>
>> +#ifdef CONFIG_CPU_IDLE_E500
>> + cpuidle_entry_bit = *value;
>> +#else
>> mtspr(SPRN_PWRMGTCR0, pw20_idle);
>> +#endif
>> }
>>
>> static ssize_t store_pw20_wait_time(struct device *dev,
>> diff --git a/drivers/cpuidle/Kconfig.powerpc
>> b/drivers/cpuidle/Kconfig.powerpc
>> index 66c3a09..0949dbf 100644
>> --- a/drivers/cpuidle/Kconfig.powerpc
>> +++ b/drivers/cpuidle/Kconfig.powerpc
>> @@ -18,3 +18,10 @@ config POWERNV_CPUIDLE
>> help
>> Select this option to enable processor idle state management
>> through cpuidle subsystem.
>> +
>> +config CPU_IDLE_E500
>> + bool "CPU Idle Driver for E500 family processors"
>> + depends on CPU_IDLE
>> + depends on FSL_SOC_BOOKE
>> + help
>> + Select this to enable cpuidle on e500 family processors.
>> diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
>> index f71ae1b..7e6adea 100644
>> --- a/drivers/cpuidle/Makefile
>> +++ b/drivers/cpuidle/Makefile
>> @@ -18,3 +18,4 @@ obj-$(CONFIG_ARM_AT91_CPUIDLE) +=
>> cpuidle-at91.o
>> # POWERPC drivers
>> obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o
>> obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
>> +obj-$(CONFIG_CPU_IDLE_E500) += cpuidle-e500.o
>> diff --git a/drivers/cpuidle/cpuidle-e500.c
>> b/drivers/cpuidle/cpuidle-e500.c
>> new file mode 100644
>> index 0000000..ddc0def
>> --- /dev/null
>> +++ b/drivers/cpuidle/cpuidle-e500.c
>> @@ -0,0 +1,194 @@
>> +/*
>> + * CPU Idle driver for Freescale PowerPC e500 family processors.
>> + *
>> + * Copyright 2014 Freescale Semiconductor, Inc.
>> + *
>> + * Author: Dongsheng Wang <dongsheng.wang@freescale.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/cpu.h>
>> +#include <linux/cpuidle.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/notifier.h>
>> +
>> +#include <asm/cputable.h>
>> +#include <asm/machdep.h>
>> +#include <asm/mpc85xx.h>
>> +
>> +static unsigned int max_idle_state;
>> +static struct cpuidle_state *cpuidle_state_table;
>> +
>> +struct cpuidle_driver e500_idle_driver = {
>> + .name = "e500_idle",
>> + .owner = THIS_MODULE,
>> +};
>> +
>> +static void e500_cpuidle(void)
>> +{
>> + if (cpuidle_idle_call())
>> + cpuidle_wait();
>> +}
>
> Nope, that has been changed. No more call to cpuidle_idle_call in a driver.
>
>> +
>> +static int pw10_enter(struct cpuidle_device *dev,
>> + struct cpuidle_driver *drv, int index)
>> +{
>> + cpuidle_wait();
>> + return index;
>> +}
>> +
>> +#define MAX_BIT 63
>> +#define MIN_BIT 1
>> +extern u32 cpuidle_entry_bit;
>> +static int pw20_enter(struct cpuidle_device *dev,
>> + struct cpuidle_driver *drv, int index)
>> +{
>> + u32 pw20_idle;
>> + u32 entry_bit;
>> + pw20_idle = mfspr(SPRN_PWRMGTCR0);
>> + if ((pw20_idle & PWRMGTCR0_PW20_ENT) != PWRMGTCR0_PW20_ENT) {
>> + pw20_idle &= ~PWRMGTCR0_PW20_ENT;
>> + entry_bit = MAX_BIT - cpuidle_entry_bit;
>> + pw20_idle |= (entry_bit << PWRMGTCR0_PW20_ENT_SHIFT);
>> + mtspr(SPRN_PWRMGTCR0, pw20_idle);
>> + }
>> +
>> + cpuidle_wait();
>> +
>> + pw20_idle &= ~PWRMGTCR0_PW20_ENT;
>> + pw20_idle |= (MIN_BIT << PWRMGTCR0_PW20_ENT_SHIFT);
>> + mtspr(SPRN_PWRMGTCR0, pw20_idle);
>> +
>> + return index;
>> +}
>
> Is it possible to give some comments and encapsulate the code with
> explicit function names to be implemented in an arch specific directory
> file (eg. pm.c) and export these functions in a linux/ header ? We try
> to prevent to include asm if possible.
>
>> +
>> +static struct cpuidle_state pw_idle_states[] = {
>> + {
>> + .name = "pw10",
>> + .desc = "pw10",
>> + .flags = CPUIDLE_FLAG_TIME_VALID,
>> + .exit_latency = 0,
>> + .target_residency = 0,
>> + .enter = &pw10_enter
>> + },
>> +
>> + {
>> + .name = "pw20",
>> + .desc = "pw20-core-idle",
>> + .flags = CPUIDLE_FLAG_TIME_VALID,
>> + .exit_latency = 1,
>> + .target_residency = 50,
>> + .enter = &pw20_enter
>> + },
>> +};
>
> No need to define this intermediate structure here, you can directly
> initialize the cpuidle_driver:
>
>
> struct cpuidle_driver e500_idle_driver = {
> .name = "e500_idle",
> .owner = THIS_MODULE,
> .states = {
> .name = "pw10",
> .desc = "pw10",
> .flags = CPUIDLE_FLAG_TIME_VALID,
> .target_residency = 0,
> .enter = &pw10_enter,
> },
>
> ....
>
> .state_count = 2,
> };
>
> Then in the init function you initialize the state_count consequently:
>
> if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
> drv->state_count = 1;
>
> Then you can kill:
>
> max_idle_state, cpuidle_state_table, e500_idle_state_probe and
> pw_idle_states.
>
>> +
>> +static int cpu_hotplug_notify(struct notifier_block *n,
>> + unsigned long action, void *hcpu)
>> +{
>> + unsigned long hotcpu = (unsigned long)hcpu;
>> + struct cpuidle_device *dev =
>> + per_cpu_ptr(cpuidle_devices, hotcpu);
>> +
>> + if (dev && cpuidle_get_driver()) {
>> + switch (action) {
>> + case CPU_ONLINE:
>> + case CPU_ONLINE_FROZEN:
>> + cpuidle_pause_and_lock();
>> + cpuidle_enable_device(dev);
>> + cpuidle_resume_and_unlock();
>> + break;
>> +
>> + case CPU_DEAD:
>> + case CPU_DEAD_FROZEN:
>> + cpuidle_pause_and_lock();
>> + cpuidle_disable_device(dev);
>> + cpuidle_resume_and_unlock();
>> + break;
>> +
>> + default:
>> + return NOTIFY_DONE;
>> + }
>> + }
>> +
>> + return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block cpu_hotplug_notifier = {
>> + .notifier_call = cpu_hotplug_notify,
>> +};
>
> Can you explain why this is needed ?
>
>> +static void e500_cpuidle_driver_init(void)
>> +{
>> + int idle_state;
>> + struct cpuidle_driver *drv = &e500_idle_driver;
>
> Pass the cpuidle_driver as parameter to the function.
>
>> +
>> + drv->state_count = 0;
>> +
>> + for (idle_state = 0; idle_state < max_idle_state; ++idle_state) {
>> + if (!cpuidle_state_table[idle_state].enter)
>> + break;
>> +
>> + drv->states[drv->state_count] = cpuidle_state_table[idle_state];
>> + drv->state_count++;
>> + }
>
> This code should disappear.
>
> As this function will just initialize state_count, you can move it in
> caller and kill this function.
>
>> +}
>> +
>> +static int e500_idle_state_probe(void)
>> +{
>> + if (cpuidle_disable != IDLE_NO_OVERRIDE)
>> + return -ENODEV;
>> +
>> + cpuidle_state_table = pw_idle_states;
>> + max_idle_state = ARRAY_SIZE(pw_idle_states);
>> +
>> + /* Disable PW20 feature for e500mc, e5500 */
>> + if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
>> + cpuidle_state_table[1].enter = NULL;
>> +
>> + if (!cpuidle_state_table || !max_idle_state)
>> + return -ENODEV;
>> +
>> + return 0;
>> +}
>
> This code should disappear.
>
>> +static void replace_orig_idle(void *dummy)
>> +{
>> + return;
>> +}
>> +
>> +static int __init e500_idle_init(void)
>> +{
>> + struct cpuidle_driver *drv = &e500_idle_driver;
>> + int err;
>> +
>> + if (e500_idle_state_probe())
>> + return -ENODEV;
>> +
>> + e500_cpuidle_driver_init();
>> + if (!drv->state_count)
>> + return -ENODEV;
>
> No need of this check, because:
>
> 1. you know how you initialized the driver (1 or 2 states)
> 2. this is already by the cpuidle framework
>
>> +
>> + err = cpuidle_register(drv, NULL);
>> + if (err) {
>> + pr_err("Register e500 family cpuidle driver failed.\n");
>
> extra carriage return.
>> +
>> + return err;
>> + }
>> +
>> + err = register_cpu_notifier(&cpu_hotplug_notifier);
>> + if (err)
>> + pr_warn("Cpuidle driver: register cpu notifier failed.\n");
>> +
>> + /* Replace the original way of idle after cpuidle registered. */
>> + ppc_md.power_save = e500_cpuidle;
>> + on_each_cpu(replace_orig_idle, NULL, 1);
>
> Why ?
>
>> + pr_info("e500_idle_driver registered.\n");
>> +
>> + return 0;
>> +}
>> +late_initcall(e500_idle_init);
>>
>
> Thanks
>
> -- Daniel
>
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* Re: [PATCH] gpio: ge: Convert to platform driver
From: Alexandre Courbot @ 2014-04-02 9:41 UTC (permalink / raw)
To: Alexander Shiyan; +Cc: linux-gpio@vger.kernel.org, Linus Walleij, linuxppc-dev
In-Reply-To: <1396156455-4225-1-git-send-email-shc_work@mail.ru>
On Sun, Mar 30, 2014 at 2:14 PM, Alexander Shiyan <shc_work@mail.ru> wrote:
> This patch converts GE I/O FPGA GPIO driver to platform driver.
>
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
> ---
> Only compile tested.
Could we get a couple of Tested-by by people who can try this patch?
It greatly simplifies the driver, but we need to make sure it doesn't
break anything before going further...
^ permalink raw reply
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