* [PATCH 2/2] MAINTAINERS: ibmvfc driver maintainer change
From: Tyrel Datwyler @ 2015-01-13 0:31 UTC (permalink / raw)
To: linux-scsi; +Cc: brking, nfont, linux-kernel, linuxppc-dev, Tyrel Datwyler
In-Reply-To: <1421109095-18613-1-git-send-email-tyreld@linux.vnet.ibm.com>
Change maintainer of ibmvfc driver to Tyrel Datwyler.
Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Cc: Brian King <brking@linux.vnet.ibm.com>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index a646b94..f0d7593 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4761,7 +4761,7 @@ F: drivers/scsi/ibmvscsi/ibmvscsi*
F: drivers/scsi/ibmvscsi/viosrp.h
IBM Power Virtual FC Device Drivers
-M: Brian King <brking@linux.vnet.ibm.com>
+M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/ibmvscsi/ibmvfc*
--
1.7.12.2
^ permalink raw reply related
* Re: [PATCH] powerpc: Reword the "returning from prom_init" message
From: Michael Ellerman @ 2015-01-13 0:58 UTC (permalink / raw)
To: Paul Clarke; +Cc: linuxppc-dev
In-Reply-To: <54B40403.1000202@us.ibm.com>
On Mon, 2015-01-12 at 11:27 -0600, Paul Clarke wrote:
> On 01/12/2015 03:48 AM, Michael Ellerman wrote:
> > We get way too many bug reports that say "the kernel is hung in
> > prom_init", which stems from the fact that the last piece of output
> > people see is "returning from prom_init".
> >
> > The kernel is almost never hung in prom_init(), it's just that it's
> > crashed somewhere after prom_init() but prior to the console coming up.
> >
> > The existing message should give a clue to that, ie. "returning from"
> > indicates that prom_init() has finished, but it doesn't seem to work.
> > Let's try something different.
> >
> > This prints:
> >
> > Calling quiesce...
> > Shutting down Open Firmware, booting Linux via __start() ...
> >
> > Which hopefully makes it clear that prom_init() is not the problem, and
> > although __start() probably isn't either, it's at least the right place
> > to begin looking.
>
> I'm very much in favor of anything that increases usability or decreases
> confusion.
>
> I worry about confusion caused by any phrase that begins "Shutting
> down.." Even if accurate, I wonder if something more positive that
> indicates that, at least at this point, things are continuing to proceed
> along would be preferred.
True.
> Perhaps something like "Transferring control from Open Firmware to
> kernel (via __start) ...".
Yeah, that's not quite accurate either :)
Linux already has control, but up until that point it is running alongside OF
and using its services. After prom_init() returns we take over the machine
entirely.
Maybe "Leaving Open Firmware, booting Linux ..."
Or just "Booting Linux ...".
> (Do we know for certain that what is about to be invoked is "Linux"
> per-se, or can it be something else that has a "__start"?)
Yes it's Linux.
Although we treat prom_init() as a separate thing, it's just linked into the
regular kernel binary. So the "transfer" here is really just a function call.
But it signifies a switch from code that runs alongside Open Firmware
(prom_init()), to code that doesn't (the rest of the kernel).
We have talked about actually linking them separately but we've never bothered,
it wouldn't buy us much.
cheers
^ permalink raw reply
* [PATCH 5/6] powerpc/ps3: Fix sys-manager-core sparse warnings
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
Fixes warnings like these:
drivers/ps3/sys-manager-core.c: error: symbol 'ps3_sys_manager_power_off' redeclared with different type
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/ps3/sys-manager-core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/ps3/sys-manager-core.c b/drivers/ps3/sys-manager-core.c
index 0e41737..c429ffc 100644
--- a/drivers/ps3/sys-manager-core.c
+++ b/drivers/ps3/sys-manager-core.c
@@ -47,7 +47,7 @@ void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops)
}
EXPORT_SYMBOL_GPL(ps3_sys_manager_register_ops);
-void ps3_sys_manager_power_off(void)
+void __noreturn ps3_sys_manager_power_off(void)
{
if (ps3_sys_manager_ops.power_off)
ps3_sys_manager_ops.power_off(ps3_sys_manager_ops.dev);
@@ -55,7 +55,7 @@ void ps3_sys_manager_power_off(void)
ps3_sys_manager_halt();
}
-void ps3_sys_manager_restart(void)
+void __noreturn ps3_sys_manager_restart(void)
{
if (ps3_sys_manager_ops.restart)
ps3_sys_manager_ops.restart(ps3_sys_manager_ops.dev);
@@ -63,7 +63,7 @@ void ps3_sys_manager_restart(void)
ps3_sys_manager_halt();
}
-void ps3_sys_manager_halt(void)
+void __noreturn ps3_sys_manager_halt(void)
{
pr_emerg("System Halted, OK to turn off power\n");
local_irq_disable();
--
1.9.1
^ permalink raw reply related
* [PATCH 4/6] powerpc/ps3: Fix vuart sparse warnings
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
Fix sparse warnings like these:
drivers/ps3/ps3-vuart.c: warning: symbol 'ps3_vuart_disable_interrupt_tx' was not declared. Should it be static?
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/ps3/ps3-vuart.c | 5 -----
drivers/ps3/vuart.h | 16 ++++++++++++++++
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
index bc1e513..d6db822 100644
--- a/drivers/ps3/ps3-vuart.c
+++ b/drivers/ps3/ps3-vuart.c
@@ -151,11 +151,6 @@ static void __maybe_unused _dump_port_params(unsigned int port_number,
#endif
}
-struct vuart_triggers {
- unsigned long rx;
- unsigned long tx;
-};
-
int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev,
struct vuart_triggers *trig)
{
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index eb7f6d9..23358b7 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -82,4 +82,20 @@ void ps3_vuart_cancel_async(struct ps3_system_bus_device *dev);
void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev,
unsigned int bytes);
+struct vuart_triggers {
+ unsigned long rx;
+ unsigned long tx;
+};
+
+int ps3_vuart_get_triggers(struct ps3_system_bus_device *dev,
+ struct vuart_triggers *trig);
+int ps3_vuart_set_triggers(struct ps3_system_bus_device *dev, unsigned int tx,
+ unsigned int rx);
+int ps3_vuart_enable_interrupt_tx(struct ps3_system_bus_device *dev);
+int ps3_vuart_disable_interrupt_tx(struct ps3_system_bus_device *dev);
+int ps3_vuart_enable_interrupt_rx(struct ps3_system_bus_device *dev);
+int ps3_vuart_disable_interrupt_rx(struct ps3_system_bus_device *dev);
+int ps3_vuart_enable_interrupt_disconnect(struct ps3_system_bus_device *dev);
+int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev);
+
#endif
--
1.9.1
^ permalink raw reply related
* [PATCH 3/6] powerpc/ps3: Write highmem info to repository
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
Add calls to the ps3_mm_set_repository_highmem() routine when the ps3
r1 highmem region is either created or destroyed.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/platforms/ps3/mm.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 04c1b93..b0f3466 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -329,6 +329,7 @@ static void ps3_mm_region_destroy(struct mem_region *r)
r->size = r->base = r->offset = 0;
map.total = map.rm.size;
}
+ ps3_mm_set_repository_highmem(NULL);
}
/*============================================================================*/
@@ -1218,8 +1219,12 @@ void __init ps3_mm_init(void)
/* Check if we got the highmem region from an earlier boot step */
- if (ps3_mm_get_repository_highmem(&map.r1))
- ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+ if (ps3_mm_get_repository_highmem(&map.r1)) {
+ result = ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+
+ if (!result)
+ ps3_mm_set_repository_highmem(&map.r1);
+ }
/* correct map.total for the real total amount of memory we use */
map.total = map.rm.size + map.r1.size;
--
1.9.1
^ permalink raw reply related
* [PATCH 0/6] *** SUBJECT HERE ***
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
Hi Ben,
Here is a short series of updates for PS3, none are critical. Please queue.
These are based on v3.18. I can rebase to something else if you like.
The first three patches are to have the kernel write the PS3 highmem info to
the LV1 hypervisor registry so that the info will be available to second stage
OS's loaded by petitboot/kexec. FreeBSD and some Linux derivatives use this
feature.
The next two patches fix some warnings emitted by sparse.
The final patch refreshes ps3_defconfig and enables the highmem info write
feature (CONFIG_PS3_REPOSITORY_WRITE=y) introduced in the first three patches.
-Geoff
The following changes since commit b2776bf7149bddd1f4161f14f79520f17fc1d71d:
Linux 3.18 (2014-12-07 14:21:05 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-linux.git for-powerpc
for you to fetch changes up to c9fc20b63c625d8d5c136f1e72d9930a6b0070df:
powerpc/ps3: Update ps3_defconfig (2014-12-23 14:56:29 -0800)
----------------------------------------------------------------
Geoff Levand (6):
powerpc/ps3: Add empty repository highmem routines
powerpc/ps3: Add ps3_mm_set_repository_highmem
powerpc/ps3: Write highmem info to repository
powerpc/ps3: Fix vuart sparse warnings
powerpc/ps3: Fix sys-manager-core sparse warnings
powerpc/ps3: Update ps3_defconfig
arch/powerpc/configs/ps3_defconfig | 17 +++-----
arch/powerpc/platforms/ps3/mm.c | 77 ++++++++++++++++++++---------------
arch/powerpc/platforms/ps3/platform.h | 13 ++++++
drivers/ps3/ps3-vuart.c | 5 ---
drivers/ps3/sys-manager-core.c | 6 +--
drivers/ps3/vuart.h | 16 ++++++++
6 files changed, 83 insertions(+), 51 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 6/6] powerpc/ps3: Update ps3_defconfig
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
Refresh ps3_defconfig and add CONFIG_PS3_REPOSITORY_WRITE=y.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/configs/ps3_defconfig | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 2e637c8..9836c1b 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -22,6 +22,8 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_PS3=y
+CONFIG_PS3_ADVANCED=y
+CONFIG_PS3_REPOSITORY_WRITE=y
CONFIG_PS3_DISK=y
CONFIG_PS3_ROM=y
CONFIG_PS3_FLASH=y
@@ -64,11 +66,9 @@ CONFIG_BT_HCIBTUSB=m
CONFIG_CFG80211=m
CONFIG_CFG80211_WEXT=y
CONFIG_MAC80211=m
-CONFIG_MAC80211_RC_PID=y
# CONFIG_MAC80211_RC_MINSTREL is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65535
@@ -76,7 +76,6 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_MD=y
CONFIG_BLK_DEV_DM=m
@@ -107,7 +106,6 @@ CONFIG_INPUT_EVDEV=m
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
CONFIG_FB_PS3=y
# CONFIG_VGA_CONSOLE is not set
@@ -130,8 +128,6 @@ CONFIG_HID_TWINHAN=m
CONFIG_HID_LOGITECH=m
CONFIG_HID_LOGITECH_DJ=m
CONFIG_HID_MICROSOFT=m
-CONFIG_HID_PS3REMOTE=m
-CONFIG_HID_SONY=m
CONFIG_HID_SUNPLUS=m
CONFIG_HID_SMARTJOYPLUS=m
CONFIG_USB_HIDDEV=y
@@ -169,18 +165,17 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRC_CCITT=m
CONFIG_CRC_T10DIF=y
-CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_FTRACE is not set
-CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
--
1.9.1
^ permalink raw reply related
* [PATCH 2/6] powerpc/ps3: Add ps3_mm_set_repository_highmem
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
Add the new routine ps3_mm_set_repository_highmem() that saves highmem info to
the ps3 repository. Also, move the existing ps3_mm_get_repository_highmem()
routine up in the source file.
This inplementation of ps3_mm_set_repository_highmem() assumes the repository
will have a single highmem region entry (at index 0).
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/platforms/ps3/mm.c | 68 +++++++++++++++++++++++------------------
1 file changed, 38 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 0c9f643..04c1b93 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -223,6 +223,44 @@ void ps3_mm_vas_destroy(void)
}
}
+static int ps3_mm_get_repository_highmem(struct mem_region *r)
+{
+ int result;
+
+ /* Assume a single highmem region. */
+
+ result = ps3_repository_read_highmem_info(0, &r->base, &r->size);
+
+ if (result)
+ goto zero_region;
+
+ if (!r->base || !r->size) {
+ result = -1;
+ goto zero_region;
+ }
+
+ r->offset = r->base - map.rm.size;
+
+ DBG("%s:%d: Found high region in repository: %llxh %llxh\n",
+ __func__, __LINE__, r->base, r->size);
+
+ return 0;
+
+zero_region:
+ DBG("%s:%d: No high region in repository.\n", __func__, __LINE__);
+
+ r->size = r->base = r->offset = 0;
+ return result;
+}
+
+static int ps3_mm_set_repository_highmem(const struct mem_region *r)
+{
+ /* Assume a single highmem region. */
+
+ return r ? ps3_repository_write_highmem_info(0, r->base, r->size) :
+ ps3_repository_write_highmem_info(0, 0, 0);
+}
+
/**
* ps3_mm_region_create - create a memory region in the vas
* @r: pointer to a struct mem_region to accept initialized values
@@ -293,36 +331,6 @@ static void ps3_mm_region_destroy(struct mem_region *r)
}
}
-static int ps3_mm_get_repository_highmem(struct mem_region *r)
-{
- int result;
-
- /* Assume a single highmem region. */
-
- result = ps3_repository_read_highmem_info(0, &r->base, &r->size);
-
- if (result)
- goto zero_region;
-
- if (!r->base || !r->size) {
- result = -1;
- goto zero_region;
- }
-
- r->offset = r->base - map.rm.size;
-
- DBG("%s:%d: Found high region in repository: %llxh %llxh\n",
- __func__, __LINE__, r->base, r->size);
-
- return 0;
-
-zero_region:
- DBG("%s:%d: No high region in repository.\n", __func__, __LINE__);
-
- r->size = r->base = r->offset = 0;
- return result;
-}
-
/*============================================================================*/
/* dma routines */
/*============================================================================*/
--
1.9.1
^ permalink raw reply related
* [PATCH 1/6] powerpc/ps3: Add empty repository highmem routines
From: Geoff Levand @ 2015-01-13 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
In-Reply-To: <cover.1421109719.git.geoff@infradead.org>
To avoid the need for preprocessor conditionals in C source files add a set of
empty inline repository highmem write routines to platform.h that are used when
CONFIG_PS3_REPOSITORY_WRITE is not defined.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/platforms/ps3/platform.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index d71329a..1809cfc 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -196,6 +196,7 @@ int ps3_repository_read_highmem_size(unsigned int region_index,
int ps3_repository_read_highmem_info(unsigned int region_index,
u64 *highmem_base, u64 *highmem_size);
+#if defined (CONFIG_PS3_REPOSITORY_WRITE)
int ps3_repository_write_highmem_region_count(unsigned int region_count);
int ps3_repository_write_highmem_base(unsigned int region_index,
u64 highmem_base);
@@ -204,6 +205,18 @@ int ps3_repository_write_highmem_size(unsigned int region_index,
int ps3_repository_write_highmem_info(unsigned int region_index,
u64 highmem_base, u64 highmem_size);
int ps3_repository_delete_highmem_info(unsigned int region_index);
+#else
+static inline int ps3_repository_write_highmem_region_count(
+ unsigned int region_count) {return 0;}
+static inline int ps3_repository_write_highmem_base(unsigned int region_index,
+ u64 highmem_base) {return 0;}
+static inline int ps3_repository_write_highmem_size(unsigned int region_index,
+ u64 highmem_size) {return 0;}
+static inline int ps3_repository_write_highmem_info(unsigned int region_index,
+ u64 highmem_base, u64 highmem_size) {return 0;}
+static inline int ps3_repository_delete_highmem_info(unsigned int region_index)
+ {return 0;}
+#endif
/* repository pme info */
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 3/6] powerpc/ps3: Write highmem info to repository
From: Michael Ellerman @ 2015-01-13 3:04 UTC (permalink / raw)
To: Geoff Levand; +Cc: cbe-oss-dev, linuxppc-dev, Nathan Whitehorn
In-Reply-To: <3deced9919246f281e48f1258885937f11a4b4ee.1421109719.git.geoff@infradead.org>
On Tue, 2015-01-13 at 01:00 +0000, Geoff Levand wrote:
> Add calls to the ps3_mm_set_repository_highmem() routine when the ps3
> r1 highmem region is either created or destroyed.
What does this actually do? ie. from a user perspective.
cheers
^ permalink raw reply
* Re: [PATCH 3/5] powerpc/powernv: Introduce pnv_pci_poll()
From: Gavin Shan @ 2015-01-13 3:16 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, linuxppc-dev, Gavin Shan
In-Reply-To: <20150109174304.GD6575@google.com>
On Fri, Jan 09, 2015 at 10:43:04AM -0700, Bjorn Helgaas wrote:
>On Thu, Dec 04, 2014 at 04:54:46PM +1100, Gavin Shan wrote:
>> We might not get some PCI slot information (e.g. power status)
>> immediately by OPAL API. Instead, opal_pci_poll() need to be called
>> for the required information.
>>
>> The patch introduces pnv_pci_poll(), which bases on original
>> ioda_eeh_poll(), to cover the above case
>>
>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>
>Hi Gavin,
>
>This patch doesn't apply cleanly on v3.19-rc1. Can you refresh this
>series, please?
>
Bjorn, the patchset depends on PowerPC specific changes as follows. The
PowerPC specfic changes should go first before you can apply this patchset
cleanly. Also, all patches depend on the firwmare changes, which is waiting
for Ben's comments. So I guess it's not urgent to merge it for now.
PowerPC specific patchs:
https://patchwork.ozlabs.org/patch/417638/
https://patchwork.ozlabs.org/patch/417637/
https://patchwork.ozlabs.org/patch/417636/
Thanks,
Gavin
>Bjorn
>
>> ---
>> arch/powerpc/platforms/powernv/eeh-ioda.c | 28 ++--------------------------
>> arch/powerpc/platforms/powernv/pci.c | 19 +++++++++++++++++++
>> arch/powerpc/platforms/powernv/pci.h | 1 +
>> 3 files changed, 22 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
>> index cf38781..21fa033 100644
>> --- a/arch/powerpc/platforms/powernv/eeh-ioda.c
>> +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
>> @@ -490,24 +490,6 @@ static int ioda_eeh_get_state(struct eeh_pe *pe)
>> return ioda_eeh_get_pe_state(pe);
>> }
>>
>> -static s64 ioda_eeh_poll(uint64_t id)
>> -{
>> - s64 rc = OPAL_HARDWARE;
>> -
>> - while (1) {
>> - rc = opal_pci_poll(id, NULL);
>> - if (rc <= 0)
>> - break;
>> -
>> - if (system_state < SYSTEM_RUNNING)
>> - udelay(1000 * rc);
>> - else
>> - msleep(rc);
>> - }
>> -
>> - return rc;
>> -}
>> -
>> int ioda_eeh_phb_reset(struct pci_controller *hose, int option)
>> {
>> struct pnv_phb *phb = hose->private_data;
>> @@ -536,10 +518,7 @@ int ioda_eeh_phb_reset(struct pci_controller *hose, int option)
>>
>> /* Issue reset and poll until it's completed */
>> rc = opal_pci_reset(phb->opal_id, scope, OPAL_ASSERT_RESET);
>> - if (rc > 0)
>> - rc = ioda_eeh_poll(phb->opal_id);
>> -
>> - return (rc == OPAL_SUCCESS) ? 0 : -EIO;
>> + return pnv_pci_poll(phb->opal_id, rc, NULL);
>> }
>>
>> static int __ioda_eeh_bridge_reset(struct pci_dev *dev, int option)
>> @@ -630,10 +609,7 @@ static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option)
>> phb = hose->private_data;
>> id |= (dev->bus->number << 24) | (dev->devfn << 16) | phb->opal_id;
>> rc = opal_pci_reset(id, scope, OPAL_ASSERT_RESET);
>> - if (rc > 0)
>> - ioda_eeh_poll(id);
>> -
>> - return (rc == OPAL_SUCCESS) ? 0 : -EIO;
>> + return pnv_pci_poll(id, rc, NULL);
>> }
>>
>> static int pnv_pci_dev_reset_type(struct pci_dev *pdev, void *data)
>> diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
>> index 4b20f2c..6dc8ea9 100644
>> --- a/arch/powerpc/platforms/powernv/pci.c
>> +++ b/arch/powerpc/platforms/powernv/pci.c
>> @@ -45,6 +45,25 @@
>> #define cfg_dbg(fmt...) do { } while(0)
>> //#define cfg_dbg(fmt...) printk(fmt)
>>
>> +int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval)
>> +{
>> + while (rval > 0) {
>> + rval = opal_pci_poll(id, pval);
>> + if (rval == OPAL_SUCCESS && pval)
>> + rval = opal_pci_poll(id, pval);
>> +
>> + if (rval <= 0)
>> + break;
>> +
>> + if (system_state < SYSTEM_RUNNING)
>> + udelay(1000 * rval);
>> + else
>> + msleep(rval);
>> + }
>> +
>> + return rval ? -EIO : 0;
>> +}
>> +
>> #ifdef CONFIG_PCI_MSI
>> static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
>> {
>> diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
>> index 6c02ff8..396fe02 100644
>> --- a/arch/powerpc/platforms/powernv/pci.h
>> +++ b/arch/powerpc/platforms/powernv/pci.h
>> @@ -217,6 +217,7 @@ extern struct pci_ops pnv_pci_ops;
>> extern struct pnv_eeh_ops ioda_eeh_ops;
>> #endif
>>
>> +int pnv_pci_poll(uint64_t id, int64_t rval, uint8_t *pval);
>> void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
>> unsigned char *log_buff);
>> int pnv_pci_cfg_read(struct device_node *dn,
>> --
>> 1.8.3.2
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 1/3] KVM: PPC: BOOK3S: HV: Add helpers for lock/unlock hpte
From: Aneesh Kumar K.V @ 2015-01-13 5:09 UTC (permalink / raw)
To: agraf, benh, paulus; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1413815340-22426-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
Hi,
Any update on this patch. We could drop patch 3. Any feedback on 1 and 2
?.
-aneesh
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
> This patch adds helper routine for lock and unlock hpte and use
> the same for rest of the code. We don't change any locking rules in this
> patch. In the next patch we switch some of the unlock usage to use
> the api with barrier and also document the usage without barriers.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/kvm_book3s_64.h | 14 ++++++++++++++
> arch/powerpc/kvm/book3s_64_mmu_hv.c | 25 ++++++++++---------------
> arch/powerpc/kvm/book3s_hv_rm_mmu.c | 27 ++++++++++-----------------
> 3 files changed, 34 insertions(+), 32 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
> index 0aa817933e6a..ec9fb6085843 100644
> --- a/arch/powerpc/include/asm/kvm_book3s_64.h
> +++ b/arch/powerpc/include/asm/kvm_book3s_64.h
> @@ -86,6 +86,20 @@ static inline long try_lock_hpte(__be64 *hpte, unsigned long bits)
> return old == 0;
> }
>
> +static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> +{
> + hpte_v &= ~HPTE_V_HVLOCK;
> + asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> + hpte[0] = cpu_to_be64(hpte_v);
> +}
> +
> +/* Without barrier */
> +static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> +{
> + hpte_v &= ~HPTE_V_HVLOCK;
> + hpte[0] = cpu_to_be64(hpte_v);
> +}
> +
> static inline int __hpte_actual_psize(unsigned int lp, int psize)
> {
> int i, shift;
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index cebb86bc4a37..5ea4b2b6a157 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -475,9 +475,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
> v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
> gr = kvm->arch.revmap[index].guest_rpte;
>
> - /* Unlock the HPTE */
> - asm volatile("lwsync" : : : "memory");
> - hptep[0] = cpu_to_be64(v);
> + unlock_hpte(hptep, v);
> preempt_enable();
>
> gpte->eaddr = eaddr;
> @@ -606,8 +604,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
> hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK;
> hpte[1] = be64_to_cpu(hptep[1]);
> hpte[2] = r = rev->guest_rpte;
> - asm volatile("lwsync" : : : "memory");
> - hptep[0] = cpu_to_be64(hpte[0]);
> + unlock_hpte(hptep, hpte[0]);
> preempt_enable();
>
> if (hpte[0] != vcpu->arch.pgfault_hpte[0] ||
> @@ -758,7 +755,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
>
> hptep[1] = cpu_to_be64(r);
> eieio();
> - hptep[0] = cpu_to_be64(hpte[0]);
> + __unlock_hpte(hptep, hpte[0]);
> asm volatile("ptesync" : : : "memory");
> preempt_enable();
> if (page && hpte_is_writable(r))
> @@ -777,7 +774,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
> return ret;
>
> out_unlock:
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> preempt_enable();
> goto out_put;
> }
> @@ -907,7 +904,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
> }
> }
> unlock_rmap(rmapp);
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> }
> return 0;
> }
> @@ -995,7 +992,7 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
> }
> ret = 1;
> }
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> } while ((i = j) != head);
>
> unlock_rmap(rmapp);
> @@ -1118,8 +1115,7 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)
>
> /* Now check and modify the HPTE */
> if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) {
> - /* unlock and continue */
> - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hptep, be64_to_cpu(hptep[0]));
> continue;
> }
> /* need to make it temporarily absent so C is stable */
> @@ -1139,9 +1135,9 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)
> npages_dirty = n;
> eieio();
> }
> - v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK);
> + v &= ~HPTE_V_ABSENT;
> v |= HPTE_V_VALID;
> - hptep[0] = cpu_to_be64(v);
> + __unlock_hpte(hptep, v);
> } while ((i = j) != head);
>
> unlock_rmap(rmapp);
> @@ -1379,8 +1375,7 @@ static long record_hpte(unsigned long flags, __be64 *hptp,
> r &= ~HPTE_GR_MODIFIED;
> revp->guest_rpte = r;
> }
> - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> - hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + unlock_hpte(hptp, be64_to_cpu(hptp[0]));
> preempt_enable();
> if (!(valid == want_valid && (first_pass || dirty)))
> ok = 0;
> diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> index 084ad54c73cd..769a5d4c0430 100644
> --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
> @@ -154,12 +154,6 @@ static pte_t lookup_linux_pte_and_update(pgd_t *pgdir, unsigned long hva,
> return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift);
> }
>
> -static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v)
> -{
> - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory");
> - hpte[0] = cpu_to_be64(hpte_v);
> -}
> -
> long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
> long pte_index, unsigned long pteh, unsigned long ptel,
> pgd_t *pgdir, bool realmode, unsigned long *pte_idx_ret)
> @@ -295,10 +289,10 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
> u64 pte;
> while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
> cpu_relax();
> - pte = be64_to_cpu(*hpte);
> + pte = be64_to_cpu(hpte[0]);
> if (!(pte & (HPTE_V_VALID | HPTE_V_ABSENT)))
> break;
> - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> hpte += 2;
> }
> if (i == 8)
> @@ -314,9 +308,9 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
>
> while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
> cpu_relax();
> - pte = be64_to_cpu(*hpte);
> + pte = be64_to_cpu(hpte[0]);
> if (pte & (HPTE_V_VALID | HPTE_V_ABSENT)) {
> - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_PTEG_FULL;
> }
> }
> @@ -356,7 +350,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
>
> /* Write the first HPTE dword, unlocking the HPTE and making it valid */
> eieio();
> - hpte[0] = cpu_to_be64(pteh);
> + __unlock_hpte(hpte, pteh);
> asm volatile("ptesync" : : : "memory");
>
> *pte_idx_ret = pte_index;
> @@ -487,7 +481,7 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,
> if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 ||
> ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn) ||
> ((flags & H_ANDCOND) && (pte & avpn) != 0)) {
> - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_NOT_FOUND;
> }
>
> @@ -623,7 +617,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
> be64_to_cpu(hp[0]), be64_to_cpu(hp[1]));
> rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C);
> args[j] |= rcbits << (56 - 5);
> - hp[0] = 0;
> + __unlock_hpte(hp, 0);
> }
> }
>
> @@ -649,7 +643,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
> pte = be64_to_cpu(hpte[0]);
> if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 ||
> ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn)) {
> - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, pte);
> return H_NOT_FOUND;
> }
>
> @@ -700,7 +694,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
> }
> hpte[1] = cpu_to_be64(r);
> eieio();
> - hpte[0] = cpu_to_be64(v & ~HPTE_V_HVLOCK);
> + __unlock_hpte(hpte, v);
> asm volatile("ptesync" : : : "memory");
> return H_SUCCESS;
> }
> @@ -841,8 +835,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
> /* Return with the HPTE still locked */
> return (hash << 3) + (i >> 1);
>
> - /* Unlock and move on */
> - hpte[i] = cpu_to_be64(v);
> + __unlock_hpte(&hpte[i], v);
> }
>
> if (val & HPTE_V_SECONDARY)
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 09/10] PCI, powerpc: clip firmware assigned resource under parent bridge's
From: Wei Yang @ 2015-01-13 9:07 UTC (permalink / raw)
To: Yinghai Lu
Cc: Wei Yang, linux-pci, Andrew Murray, Sebastian Ott, linux-kernel,
Gavin Shan, Paul Mackerras, Anton Blanchard, Bjorn Helgaas,
linuxppc-dev
In-Reply-To: <1421090600-9750-10-git-send-email-yinghai@kernel.org>
Did a quick test, looks good on my machine.
Thanks :-)
On Mon, Jan 12, 2015 at 11:23:19AM -0800, Yinghai Lu wrote:
>Some bios put range that is not fully coverred by root bus resources.
>Try to clip them and update them in pci bridge bars.
>
>We'd like to fix other arches instead of just x86.
>
>Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
>Reported-by: Marek Kordik <kordikmarek@gmail.com>
>Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
>Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>Cc: Paul Mackerras <paulus@samba.org>
>Cc: Michael Ellerman <mpe@ellerman.id.au>
>Cc: Gavin Shan <gwshan@linux.vnet.ibm.com>
>Cc: Anton Blanchard <anton@samba.org>
>Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
>Cc: Wei Yang <weiyang@linux.vnet.ibm.com>
>Cc: Andrew Murray <amurray@embedded-bits.co.uk>
>Cc: linuxppc-dev@lists.ozlabs.org
>---
> arch/powerpc/kernel/pci-common.c | 43 +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
>diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
>index 37d512d..6909546 100644
>--- a/arch/powerpc/kernel/pci-common.c
>+++ b/arch/powerpc/kernel/pci-common.c
>@@ -1148,6 +1148,7 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> struct pci_bus *b;
> int i;
> struct resource *res, *pr;
>+ bool changed = false;
>
> pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
> pci_domain_nr(bus), bus->number);
>@@ -1184,6 +1185,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> pr, (pr && pr->name) ? pr->name : "nil");
>
> if (pr && !(pr->flags & IORESOURCE_UNSET)) {
>+ struct pci_dev *dev = bus->self;
>+
> if (request_resource(pr, res) == 0)
> continue;
> /*
>@@ -1193,6 +1196,16 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> */
> if (reparent_resources(pr, res) == 0)
> continue;
>+
>+ if (dev && i >= PCI_BRIDGE_RESOURCES &&
>+ i < PCI_NUM_RESOURCES &&
>+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+ pci_bus_clip_resource(dev, res)) {
>+ changed = true;
>+ if (pci_claim_resource(dev, i) >= 0)
>+ continue;
>+ }
>+
> }
> pr_warning("PCI: Cannot allocate resource region "
> "%d of PCI bridge %d, will remap\n", i, bus->number);
>@@ -1208,6 +1221,9 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> res->flags = 0;
> }
>
>+ if (changed)
>+ pci_setup_bridge(bus);
>+
> list_for_each_entry(b, &bus->children, node)
> pcibios_allocate_bus_resources(b);
> }
>@@ -1225,6 +1241,13 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
> pr = pci_find_parent_resource(dev, r);
> if (!pr || (pr->flags & IORESOURCE_UNSET) ||
> request_resource(pr, r) < 0) {
>+ /* try again with clip */
>+ if (idx != PCI_ROM_RESOURCE && pci_bus_clip_resource(dev, r)) {
>+ pci_update_resource(dev, idx);
>+ if (pci_claim_resource(dev, idx) >= 0)
>+ return;
>+ }
>+
> printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
> " of device %s, will remap\n", idx, pci_name(dev));
> if (pr)
>@@ -1386,6 +1409,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
> struct pci_bus *child_bus;
>
> list_for_each_entry(dev, &bus->devices, bus_list) {
>+ bool changed = false;
> int i;
>
> for (i = 0; i < PCI_NUM_RESOURCES; i++) {
>@@ -1401,8 +1425,25 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
> (unsigned long long)r->end,
> (unsigned int)r->flags);
>
>- pci_claim_resource(dev, i);
>+ if (pci_claim_resource(dev, i) >= 0)
>+ continue;
>+
>+ if (dev->subordinate &&
>+ i >= PCI_BRIDGE_RESOURCES &&
>+ i < PCI_NUM_RESOURCES &&
>+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+ pci_bus_clip_resource(dev, r)) {
>+ changed = true;
>+ pci_claim_resource(dev, i);
>+ } else if (i < PCI_BRIDGE_RESOURCES &&
>+ i != PCI_ROM_RESOURCE &&
>+ pci_bus_clip_resource(dev, r)) {
>+ pci_update_resource(dev, i);
>+ pci_claim_resource(dev, i);
>+ }
> }
>+ if (changed)
>+ pci_setup_bridge(dev->subordinate);
> }
>
> list_for_each_entry(child_bus, &bus->children, node)
>--
>1.8.4.5
--
Richard Yang
Help you, Help me
^ permalink raw reply
* [PATCH 1/2] MAINTAINERS: ibmvscsi driver maintainer change
From: Tyrel Datwyler @ 2015-01-13 0:31 UTC (permalink / raw)
To: linux-scsi; +Cc: brking, nfont, linux-kernel, linuxppc-dev, Tyrel Datwyler
Change maintainer of ibmvscsi driver to Tyrel Datwyler.
Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Cc: Brian King <brking@linux.vnet.ibm.com>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 79b2e4b..a646b94 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4754,7 +4754,7 @@ S: Supported
F: drivers/net/ethernet/ibm/ibmveth.*
IBM Power Virtual SCSI Device Drivers
-M: Nathan Fontenot <nfont@linux.vnet.ibm.com>
+M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/ibmvscsi/ibmvscsi*
--
1.7.12.2
^ permalink raw reply related
* [PATCH V2 02/12] powerpc, process: Remove the unused extern dscr_default
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
The process context switch code no longer uses dscr_default variable
from the sysfs.c file. The variable became unused when we started
storing the CPU specific DSCR value in the PACA structure instead.
This patch just removes this extern declaration. It was originally
added by the following commit.
efcac658: powerpc: Per process DSCR + some fixes (try#4)
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/kernel/process.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b4cc7be..fe3f682 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1112,8 +1112,6 @@ static void setup_ksp_vsid(struct task_struct *p, unsigned long sp)
/*
* Copy a thread..
*/
-extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
-
int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long arg, struct task_struct *p)
{
--
1.9.3
^ permalink raw reply related
* [PATCH V2 00/12] POWER DSCR fixes, improvements, docs and tests
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
This patch series has patches for POWER DSCR fixes, improvements,
in code documentaion, kernel support user documentation and selftest based
test cases. It has got five test cases which are derived from Anton's DSCR
test bucket which can be listed as follows.
(1) http://ozlabs.org/~anton/junkcode/dscr_default_test.c
(2) http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
(3) http://ozlabs.org/~anton/junkcode/dscr_inherit_exec_test.c
(4) http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c
(5) http://ozlabs.org/~anton/junkcode/user_dscr_test.c
So the derivied test cases have Anton's copyright along with mine but the
commit message as of now has only my signed-off-by statement. As Anton
mentioned before he would put his signed-off-by after reviewing these
modified test cases.
NOTE1: Anton's original inherit exec test expected the child to have system
default DSCR value instead of the inherited DSCR value from it's parent.
But looks like thats not the case when we execute the test, it always
inherits it's parent's DSCR value over the exec call as well. So I have
changed the test program assuming its correct to have the inherited DSCR
value in the fork/execed child program. Please let me know if thats not
correct and I am missing something there.
NOTE2: The selftests/powerpc/.gitignore will be added and will get updated
through a different patch series related to ptrace instead of this one.
Changes in V2:
-------------
- Updated the thread struct DSCR value inside mtspr facility exception path
- Modified the in code documentation to follow the kernel-doc format
- Added seven selftest based DSCR related test cases under powerpc
Original V1:
------------
- Posted here at https://patchwork.ozlabs.org/patch/418583/
Anshuman Khandual (12):
powerpc: Fix handling of DSCR related facility unavailable exception
powerpc, process: Remove the unused extern dscr_default
powerpc, offset: Change PACA_DSCR to PACA_DSCR_DEFAULT
powerpc, dscr: Added some in-code documentation
documentation, powerpc: Add documentation for DSCR support
selftests, powerpc: Add test for system wide DSCR default
selftests, powerpc: Add test for explicitly changing DSCR value
selftests, powerpc: Add test for DSCR SPR numbers
selftests, powerpc: Add test for DSCR value inheritence across fork
selftests, powerpc: Add test for DSCR inheritence across fork & exec
selftests, powerpc: Add test for all DSCR sysfs interfaces
selftests, powerpc: Add thread based stress test for DSCR sysfs interfaces
Documentation/powerpc/00-INDEX | 2 +
Documentation/powerpc/dscr.txt | 83 ++++++++++++++
arch/powerpc/include/asm/processor.h | 9 ++
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/entry_64.S | 2 +-
arch/powerpc/kernel/process.c | 2 -
arch/powerpc/kernel/sysfs.c | 38 +++++++
arch/powerpc/kernel/tm.S | 4 +-
arch/powerpc/kernel/traps.c | 45 +++++++-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/dscr/Makefile | 19 ++++
tools/testing/selftests/powerpc/dscr/dscr.h | 120 ++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_default_test.c | 121 +++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_explicit_test.c | 72 ++++++++++++
.../powerpc/dscr/dscr_inherit_exec_test.c | 118 ++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_inherit_test.c | 96 ++++++++++++++++
.../selftests/powerpc/dscr/dscr_sysfs_test.c | 89 +++++++++++++++
.../powerpc/dscr/dscr_sysfs_thread_test.c | 114 +++++++++++++++++++
.../selftests/powerpc/dscr/dscr_user_test.c | 62 +++++++++++
20 files changed, 989 insertions(+), 13 deletions(-)
create mode 100644 Documentation/powerpc/dscr.txt
create mode 100644 tools/testing/selftests/powerpc/dscr/Makefile
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr.h
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_default_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_user_test.c
--
1.9.3
^ permalink raw reply
* [PATCH V2 01/12] powerpc: Fix handling of DSCR related facility unavailable exception
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
Currently DSCR (Data Stream Control Register) can be accessed with
mfspr or mtspr instructions inside a thread via two different SPR
numbers. One being the user accessible problem state SPR number 0x03
and the other being the privilege state SPR number 0x11. All access
through the privilege state SPR number get emulated through illegal
instruction exception. Any access through the problem state SPR number
raises one facility unavailable exception which sets the thread based
dscr_inherit bit and enables DSCR facility through FSCR register thus
allowing direct access to DSCR without going through this exception in
the future. We set the thread.dscr_inherit bit whether the access was
with mfspr or mtspr instruction which is neither correct nor does it
match the behaviour through the instruction emulation code path driven
from privilege state SPR number. User currently observes two different
kind of behaviour when accessing the DSCR through these two SPR numbers.
This problem can be observed through these two test cases by replacing
the privilege state SPR number with the problem state SPR number.
(1) http://ozlabs.org/~anton/junkcode/dscr_default_test.c
(2) http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
This patch fixes the problem by making sure that the behaviour visible
to the user remains the same irrespective of which SPR number is being
used. Inside facility unavailable exception, we check whether it was
cuased by a mfspr or a mtspr isntrucction. In case of mfspr instruction,
just emulate the instruction. In case of mtspr instruction, set the
thread based dscr_inherit bit and also enable the facility through FSCR.
All user SPR based mfspr instruction will be emulated till one user SPR
based mtspr has been executed.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/kernel/traps.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index e6595b7..cd69340 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1377,6 +1377,7 @@ void facility_unavailable_exception(struct pt_regs *regs)
};
char *facility = "unknown";
u64 value;
+ u32 instword, rd;
u8 status;
bool hv;
@@ -1388,12 +1389,46 @@ void facility_unavailable_exception(struct pt_regs *regs)
status = value >> 56;
if (status == FSCR_DSCR_LG) {
- /* User is acessing the DSCR. Set the inherit bit and allow
- * the user to set it directly in future by setting via the
- * FSCR DSCR bit. We always leave HFSCR DSCR set.
+ /*
+ * User is accessing the DSCR register using the problem
+ * state only SPR number (0x03) either through a mfspr or
+ * a mtspr instruction. If it is a write attempt through
+ * a mtspr, then we set the inherit bit. This also allows
+ * the user to write or read the register directly in the
+ * future by setting via the FSCR DSCR bit. But in case it
+ * is a read DSCR attempt through a mfspr instruction, we
+ * just emulate the instruction instead. This code path will
+ * always emulate all the mfspr instructions till the user
+ * has attempted atleast one mtspr instruction. This way it
+ * preserves the same behaviour when the user is accessing
+ * the DSCR through privilege level only SPR number (0x11)
+ * which is emulated through illegal instruction exception.
+ * We always leave HFSCR DSCR set.
*/
- current->thread.dscr_inherit = 1;
- mtspr(SPRN_FSCR, value | FSCR_DSCR);
+ if (get_user(instword, (u32 __user *)(regs->nip))) {
+ pr_err("Failed to fetch the user instruction\n");
+ return;
+ }
+
+ /* Write into DSCR (mtspr 0x03, RS) */
+ if ((instword & PPC_INST_MTSPR_DSCR_USER_MASK)
+ == PPC_INST_MTSPR_DSCR_USER) {
+ rd = (instword >> 21) & 0x1f;
+ current->thread.dscr = regs->gpr[rd];
+ current->thread.dscr_inherit = 1;
+ mtspr(SPRN_FSCR, value | FSCR_DSCR);
+ }
+
+ /* Read from DSCR (mfspr RT, 0x03) */
+ if ((instword & PPC_INST_MFSPR_DSCR_USER_MASK)
+ == PPC_INST_MFSPR_DSCR_USER) {
+ if (emulate_instruction(regs)) {
+ pr_err("DSCR based mfspr emulation failed\n");
+ return;
+ }
+ regs->nip += 4;
+ emulate_single_step(regs);
+ }
return;
}
--
1.9.3
^ permalink raw reply related
* [PATCH V2 03/12] powerpc, offset: Change PACA_DSCR to PACA_DSCR_DEFAULT
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
PACA_DSCR offset macro tracks dscr_default element in the paca
structure. Better change the name of this macro to match that
of the data element it tracks. Makes the code more readable.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/entry_64.S | 2 +-
arch/powerpc/kernel/tm.S | 4 ++--
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index e624f96..dcfffe2 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -246,7 +246,7 @@ int main(void)
#endif
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
- DEFINE(PACA_DSCR, offsetof(struct paca_struct, dscr_default));
+ DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default));
DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime));
DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 194e46d..b5cd2b59 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -564,7 +564,7 @@ BEGIN_FTR_SECTION
ld r0,THREAD_DSCR(r4)
cmpwi r6,0
bne 1f
- ld r0,PACA_DSCR(r13)
+ ld r0,PACA_DSCR_DEFAULT(r13)
1:
BEGIN_FTR_SECTION_NESTED(70)
mfspr r8, SPRN_FSCR
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S
index 2a324f4..dbd2c18 100644
--- a/arch/powerpc/kernel/tm.S
+++ b/arch/powerpc/kernel/tm.S
@@ -293,7 +293,7 @@ dont_backup_fp:
ld r2, STK_GOT(r1)
/* Load CPU's default DSCR */
- ld r0, PACA_DSCR(r13)
+ ld r0, PACA_DSCR_DEFAULT(r13)
mtspr SPRN_DSCR, r0
blr
@@ -473,7 +473,7 @@ restore_gprs:
ld r2, STK_GOT(r1)
/* Load CPU's default DSCR */
- ld r0, PACA_DSCR(r13)
+ ld r0, PACA_DSCR_DEFAULT(r13)
mtspr SPRN_DSCR, r0
blr
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 10554df..109794b 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -283,7 +283,7 @@ kvm_start_guest:
kvm_secondary_got_guest:
/* Set HSTATE_DSCR(r13) to something sensible */
- ld r6, PACA_DSCR(r13)
+ ld r6, PACA_DSCR_DEFAULT(r13)
std r6, HSTATE_DSCR(r13)
bl kvmppc_hv_entry
--
1.9.3
^ permalink raw reply related
* [PATCH V2 04/12] powerpc, dscr: Added some in-code documentation
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds some in-code documentation to the DSCR related
code to make it more readable without having any functional
change to it.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/processor.h | 9 +++++++++
arch/powerpc/kernel/sysfs.c | 38 ++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index bf117d8..28ded5d 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -295,6 +295,15 @@ struct thread_struct {
#endif
#ifdef CONFIG_PPC64
unsigned long dscr;
+ /*
+ * This member element dscr_inherit indicates that the process
+ * has explicitly attempted and changed the DSCR register value
+ * for itself. Hence kernel wont use the default CPU DSCR value
+ * contained in the PACA structure anymore during process context
+ * switch. Once this variable is set, this behaviour will also be
+ * inherited to all the children of this process from that point
+ * onwards.
+ */
int dscr_inherit;
unsigned long ppr; /* used to save/restore SMT priority */
#endif
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index fa1fd8a..692873b 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -496,13 +496,34 @@ static DEVICE_ATTR(spurr, 0400, show_spurr, NULL);
static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
static DEVICE_ATTR(pir, 0400, show_pir, NULL);
+/*
+ * This is the system wide DSCR register default value. Any
+ * change to this default value through the sysfs interface
+ * will update all per cpu DSCR default values across the
+ * system stored in their respective PACA structures.
+ */
static unsigned long dscr_default;
+/**
+ * read_dscr() - Fetch the cpu specific DSCR default
+ * @val: Returned cpu specific DSCR default value
+ *
+ * This function returns the per cpu DSCR default value
+ * for any cpu which is contained in it's PACA structure.
+ */
static void read_dscr(void *val)
{
*(unsigned long *)val = get_paca()->dscr_default;
}
+
+/**
+ * write_dscr() - Update the cpu specific DSCR default
+ * @val: New cpu specific DSCR default value to update
+ *
+ * This function updates the per cpu DSCR default value
+ * for any cpu which is contained in it's PACA structure.
+ */
static void write_dscr(void *val)
{
get_paca()->dscr_default = *(unsigned long *)val;
@@ -520,12 +541,29 @@ static void add_write_permission_dev_attr(struct device_attribute *attr)
attr->attr.mode |= 0200;
}
+/**
+ * show_dscr_default() - Fetch the system wide DSCR default
+ * @dev: Device structure
+ * @attr: Device attribute structure
+ * @buf: Interface buffer
+ *
+ * This function returns the system wide DSCR default value.
+ */
static ssize_t show_dscr_default(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%lx\n", dscr_default);
}
+/**
+ * store_dscr_default() - Update the system wide DSCR default
+ * @dev: Device structure
+ * @attr: Device attribute structure
+ * @buf: Interface buffer
+ * @count: Size of the update
+ *
+ * This function updates the system wide DSCR default value.
+ */
static ssize_t __used store_dscr_default(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
--
1.9.3
^ permalink raw reply related
* [PATCH V2 05/12] documentation, powerpc: Add documentation for DSCR support
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a new documentation file explaining the DSCR
support on powerpc platforms. This explains DSCR related data
structure, code paths and also available user interfaces. Any
further functional changes to the DSCR support in the kernel
should definitely update the documentation here.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
Documentation/powerpc/00-INDEX | 2 +
Documentation/powerpc/dscr.txt | 83 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 Documentation/powerpc/dscr.txt
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index 6fd0e8b..9dc845c 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -30,3 +30,5 @@ ptrace.txt
- Information on the ptrace interfaces for hardware debug registers.
transactional_memory.txt
- Overview of the Power8 transactional memory support.
+dscr.txt
+ - Overview DSCR (Data Stream Control Register) support.
diff --git a/Documentation/powerpc/dscr.txt b/Documentation/powerpc/dscr.txt
new file mode 100644
index 0000000..1ff4400
--- /dev/null
+++ b/Documentation/powerpc/dscr.txt
@@ -0,0 +1,83 @@
+ DSCR (Data Stream Control Register)
+ ================================================
+
+DSCR register in powerpc allows user to have some control of prefetch of data
+stream in the processor. Please refer to the ISA documents or related manual
+for more detailed information regarding how to use this DSCR to attain this
+control of the pefetches . This document here provides an overview of kernel
+support for DSCR, related kernel objects, it's functionalities and exported
+user interface.
+
+(A) Data Structures:
+
+ (1) thread_struct:
+ dscr /* Thread DSCR value */
+ dscr_inherit /* Thread has changed default DSCR */
+
+ (2) PACA:
+ dscr_default /* per-CPU DSCR default value */
+
+ (3) sysfs.c:
+ dscr_default /* System DSCR default value */
+
+(B) Scheduler Changes:
+
+ Scheduler will write the per-CPU DSCR default which is stored in the
+ CPU's PACA value into the register if the thread has dscr_inherit value
+ cleared which means that it has not changed the default DSCR till now.
+ If the dscr_inherit value is set which means that it has changed the
+ default DSCR value, scheduler will write the changed value which will
+ now be contained in thread struct's dscr into the register instead of
+ the per-CPU default PACA based DSCR value.
+
+ NOTE: Please note here that the system wide global DSCR value never
+ gets used directly in the scheduler process context switch at all.
+
+(C) SYSFS Interface:
+
+ Global DSCR default: /sys/devices/system/cpu/dscr_default
+ CPU specific DSCR default: /sys/devices/system/cpu/cpuN/dscr
+
+ Changing the global DSCR default in the sysfs will change all the CPU
+ specific DSCR defaults immediately in their PACA structures. Again if
+ the current process has the dscr_inherit clear, it also writes the new
+ value into every CPU's DSCR register right away and updates the current
+ thread's DSCR value as well.
+
+ Changing the CPU specif DSCR default value in the sysfs does exactly
+ the same thing as above but unlike the global one above, it just changes
+ stuff for that particular CPU instead for all the CPUs on the system.
+
+(D) User Space Instructions:
+
+ The DSCR register can be accessed in the user space using any of these
+ two SPR numbers available for that purpose.
+
+ (1) Problem state SPR: 0x03 (Un-privileged, POWER8 only)
+ (2) Privileged state SPR: 0x11 (Privileged)
+
+ Accessing DSCR through privileged SPR number (0x11) from user space
+ works, as it is emulated following an illegal instruction exception
+ inside the kernel. Both mfspr and mtspr instructions are emulated.
+
+ Accessing DSCR through user level SPR (0x03) from user space will first
+ create a facility unavailable exception. Inside this exception handler
+ all mfspr isntruction based read attempts will get emulated and returned
+ where as the first mtspr instruction based write attempts will enable
+ the DSCR facility for the next time around (both for read and write) by
+ setting DSCR facility in the FSCR register.
+
+(E) Specifics about 'dscr_inherit':
+
+ The thread struct element 'dscr_inherit' represents whether the thread
+ in question has attempted and changed the DSCR itself using any of the
+ following methods. This element signifies whether the thread wants to
+ use the CPU default DSCR value or its own changed DSCR value in the
+ kernel.
+
+ (1) mtspr instruction (SPR number 0x03)
+ (2) mtspr instruction (SPR number 0x11)
+ (3) ptrace interface (Explicitly set user DSCR value)
+
+ Any child of the process created after this event in the process inherits
+ this same behaviour as well.
--
1.9.3
^ permalink raw reply related
* [PATCH V2 06/12] selftests, powerpc: Add test for system wide DSCR default
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a test case for the system wide DSCR default
value, which when changed through it's sysfs interface must
be visible to all threads reading DSCR either through the
privilege state SPR or the problem state SPR. The DSCR value
change should be immediate as well.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/dscr/Makefile | 17 +++
tools/testing/selftests/powerpc/dscr/dscr.h | 120 ++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_default_test.c | 121 +++++++++++++++++++++
4 files changed, 259 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/Makefile
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr.h
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_default_test.c
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index f6ff90a..1318883 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
export CC CFLAGS
-TARGETS = pmu copyloops mm tm primitives
+TARGETS = pmu copyloops mm tm primitives dscr
endif
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
new file mode 100644
index 0000000..0aa90ab
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -0,0 +1,17 @@
+PROGS := dscr_default_test
+
+CFLAGS := $(CFLAGS) -lpthread
+
+all: $(PROGS)
+
+$(PROGS): ../harness.c
+
+run_tests: all
+ @-for PROG in $(PROGS); do \
+ ./$$PROG; \
+ done;
+
+clean:
+ rm -f $(PROGS) *.o
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/dscr/dscr.h b/tools/testing/selftests/powerpc/dscr/dscr.h
new file mode 100644
index 0000000..2e6535b
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr.h
@@ -0,0 +1,120 @@
+/*
+ * POWER Data Stream Control Register (DSCR)
+ *
+ * This header file contains helper functions and macros
+ * required for all the DSCR related test cases.
+ *
+ * Copyright (C) 2012 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _SELFTESTS_POWERPC_DSCR_DSCR_H
+#define _SELFTESTS_POWERPC_DSCR_DSCR_H
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <sched.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include "utils.h"
+
+#define SPRN_DSCR 0x11 /* Privilege state SPR */
+#define SPRN_DSCR_USR 0x03 /* Problem state SPR */
+#define THREADS 100 /* Max threads */
+#define COUNT 100 /* Max iterations */
+#define DSCR_MAX 16 /* Max DSCR value */
+#define LEN_MAX 100 /* Max name length */
+
+#define DSCR_DEFAULT "/sys/devices/system/cpu/dscr_default"
+#define CPU_PATH "/sys/devices/system/cpu/"
+
+#define rmb() asm volatile("lwsync":::"memory")
+#define wmb() asm volatile("lwsync":::"memory")
+
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
+/* Prilvilege state DSCR access */
+inline unsigned long get_dscr(void)
+{
+ unsigned long ret;
+
+ asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR));
+
+ return ret;
+}
+
+inline void set_dscr(unsigned long val)
+{
+ asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
+}
+
+/* Problem state DSCR access */
+inline unsigned long get_dscr_usr(void)
+{
+ unsigned long ret;
+
+ asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR_USR));
+
+ return ret;
+}
+
+inline void set_dscr_usr(unsigned long val)
+{
+ asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR_USR));
+}
+
+/* Default DSCR access */
+unsigned long get_default_dscr(void)
+{
+ int fd = -1;
+ char buf[16];
+ unsigned long val;
+
+ if (fd == -1) {
+ fd = open(DSCR_DEFAULT, O_RDONLY);
+ if (fd == -1) {
+ perror("open() failed\n");
+ exit(1);
+ }
+ }
+ memset(buf, 0, sizeof(buf));
+ lseek(fd, 0, SEEK_SET);
+ read(fd, buf, sizeof(buf));
+ sscanf(buf, "%lx", &val);
+ close(fd);
+ return val;
+}
+
+void set_default_dscr(unsigned long val)
+{
+ int fd = -1;
+ char buf[16];
+
+ if (fd == -1) {
+ fd = open(DSCR_DEFAULT, O_RDWR);
+ if (fd == -1) {
+ perror("open() failed\n");
+ exit(1);
+ }
+ }
+ sprintf(buf, "%lx\n", val);
+ write(fd, buf, strlen(buf));
+ close(fd);
+}
+
+double uniform_deviate(int seed)
+{
+ return seed * (1.0 / (RAND_MAX + 1.0));
+}
+#endif /* _SELFTESTS_POWERPC_DSCR_DSCR_H */
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_default_test.c b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c
new file mode 100644
index 0000000..fd8b7b9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr_default_test.c
@@ -0,0 +1,121 @@
+/*
+ * POWER Data Stream Control Register (DSCR) default test
+ *
+ * This test modifies the system wide default DSCR through
+ * it's sysfs interface and then verifies that all threads
+ * see the correct changed DSCR value immediately.
+ *
+ * Copyright (C) 2012 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "dscr.h"
+
+static unsigned long dscr; /* System DSCR default */
+static unsigned long sequence;
+static unsigned long result[THREADS];
+
+static void *do_test(void *in)
+{
+ unsigned long thread = (unsigned long)in;
+ unsigned long i;
+
+ for (i = 0; i < COUNT; i++) {
+ unsigned long d, cur_dscr, cur_dscr_usr;
+ unsigned long s1, s2;
+
+ s1 = ACCESS_ONCE(sequence);
+ if (s1 & 1)
+ continue;
+ rmb();
+
+ d = dscr;
+ cur_dscr = get_dscr();
+ cur_dscr_usr = get_dscr_usr();
+
+ rmb();
+ s2 = sequence;
+
+ if (s1 != s2)
+ continue;
+
+ if (cur_dscr != d) {
+ fprintf(stderr, "thread %ld kernel DSCR should be %ld "
+ "but is %ld\n", thread, d, cur_dscr);
+ result[thread] = 1;
+ pthread_exit(&result[thread]);
+ }
+
+ if (cur_dscr_usr != d) {
+ fprintf(stderr, "thread %ld user DSCR should be %ld "
+ "but is %ld\n", thread, d, cur_dscr_usr);
+ result[thread] = 1;
+ pthread_exit(&result[thread]);
+ }
+ }
+ result[thread] = 0;
+ pthread_exit(&result[thread]);
+}
+
+int test_body(void)
+{
+ pthread_t threads[THREADS];
+ unsigned long i, *status[THREADS];
+
+ /* Initial DSCR default */
+ dscr = 1;
+ set_default_dscr(dscr);
+
+ /* Spawn all testing threads */
+ for (i = 0; i < THREADS; i++) {
+ if (pthread_create(&threads[i], NULL, do_test, (void *)i)) {
+ perror("pthread_create() failed\n");
+ exit(1);
+ }
+ }
+
+ srand(getpid());
+
+ /* Keep changing the DSCR default */
+ for (i = 0; i < COUNT; i++) {
+ double ret = uniform_deviate(rand());
+
+ if (ret < 0.0001) {
+ sequence++;
+ wmb();
+
+ dscr++;
+ if (dscr > DSCR_MAX)
+ dscr = 0;
+
+ set_default_dscr(dscr);
+
+ wmb();
+ sequence++;
+ }
+ }
+
+ /* Individual testing thread exit status */
+ for (i = 0; i < THREADS; i++) {
+ if (pthread_join(threads[i], (void **)&(status[i]))) {
+ perror("pthread_join() failed\n");
+ exit(1);
+ }
+
+ if (*status[i]) {
+ printf("%ldth thread failed to join with %ld status\n",
+ i, *status[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(test_body, "dscr_default_test");
+}
--
1.9.3
^ permalink raw reply related
* [PATCH V2 07/12] selftests, powerpc: Add test for explicitly changing DSCR value
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a test which modifies the DSCR using mtspr instruction
and verifies the change using mfspr instruction. It uses both the
privilege state SPR as well as the problem state SPR for the purpose.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../selftests/powerpc/dscr/dscr_explicit_test.c | 72 ++++++++++++++++++++++
2 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
index 0aa90ab..aede453 100644
--- a/tools/testing/selftests/powerpc/dscr/Makefile
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -1,4 +1,4 @@
-PROGS := dscr_default_test
+PROGS := dscr_default_test dscr_explicit_test
CFLAGS := $(CFLAGS) -lpthread
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
new file mode 100644
index 0000000..5c0b7c1
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
@@ -0,0 +1,72 @@
+/*
+ * POWER Data Stream Control Register (DSCR) explicit test
+ *
+ * This test modifies the DSCR value using mtspr instruction and
+ * verifies the change with mfspr instruction. It uses both the
+ * privilege state SPR and the problem state SPR for this purpose.
+ *
+ * When using the privilege state SPR, the instructions such as
+ * mfspr or mtspr are priviledged and the kernel emulates them
+ * for us. Instructions using problem state SPR can be exuecuted
+ * directly without any emulation if the HW supports them. Else
+ * they also get emulated by the kernel.
+ *
+ * Copyright (C) 2012 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "dscr.h"
+
+int test_body(void)
+{
+ unsigned long i, dscr = 0;
+
+ srand(getpid());
+ set_dscr(dscr);
+
+ for (i = 0; i < COUNT; i++) {
+ unsigned long cur_dscr, cur_dscr_usr;
+ double ret = uniform_deviate(rand());
+
+ if (ret < 0.001) {
+ dscr++;
+ if (dscr > DSCR_MAX)
+ dscr = 0;
+
+ set_dscr(dscr);
+ }
+
+ cur_dscr = get_dscr();
+ if (cur_dscr != dscr) {
+ fprintf(stderr, "Kernel DSCR should be %ld but "
+ "is %ld\n", dscr, cur_dscr);
+ return 1;
+ }
+
+ ret = uniform_deviate(rand());
+ if (ret < 0.001) {
+ dscr++;
+ if (dscr > DSCR_MAX)
+ dscr = 0;
+
+ set_dscr_usr(dscr);
+ }
+
+ cur_dscr_usr = get_dscr_usr();
+ if (cur_dscr_usr != dscr) {
+ fprintf(stderr, "User DSCR should be %ld but "
+ "is %ld\n", dscr, cur_dscr_usr);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(test_body, "dscr_explicit_test");
+}
--
1.9.3
^ permalink raw reply related
* [PATCH V2 08/12] selftests, powerpc: Add test for DSCR SPR numbers
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a test which verifies that the DSCR privilege and
problem state SPR read & write accesses while making sure that the
results are always the same irrespective of which SPR number is
being used.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../selftests/powerpc/dscr/dscr_user_test.c | 62 ++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_user_test.c
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
index aede453..ae865d8 100644
--- a/tools/testing/selftests/powerpc/dscr/Makefile
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -1,4 +1,4 @@
-PROGS := dscr_default_test dscr_explicit_test
+PROGS := dscr_default_test dscr_explicit_test dscr_user_test
CFLAGS := $(CFLAGS) -lpthread
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_user_test.c b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c
new file mode 100644
index 0000000..f25d68e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr_user_test.c
@@ -0,0 +1,62 @@
+/*
+ * POWER Data Stream Control Register (DSCR) SPR test
+ *
+ * This test modifies the DSCR value through both the SPR number
+ * based mtspr instruction and then makes sure that the same is
+ * reflected through mfspr instruction using either of the SPR
+ * numbers.
+ *
+ * When using the privilege state SPR, the instructions such as
+ * mfspr or mtspr are priviledged and the kernel emulates them
+ * for us. Instructions using problem state SPR can be exuecuted
+ * directly without any emulation if the HW supports them. Else
+ * they also get emulated by the kernel.
+ *
+ * Copyright (C) 2013 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "dscr.h"
+
+static int check_dscr(char *str)
+{
+ unsigned long cur_dscr, cur_dscr_usr;
+
+ cur_dscr = get_dscr();
+ cur_dscr_usr = get_dscr_usr();
+ if (cur_dscr != cur_dscr_usr) {
+ printf("%s set, kernel get %lx != user get %lx\n",
+ str, cur_dscr, cur_dscr_usr);
+ return 1;
+ }
+ return 0;
+}
+
+int test_body(void)
+{
+ int i;
+
+ check_dscr("");
+
+ for (i = 0; i < COUNT; i++) {
+ set_dscr(i);
+ if (check_dscr("kernel"))
+ return 1;
+ }
+
+ for (i = 0; i < COUNT; i++) {
+ set_dscr_usr(i);
+ if (check_dscr("user"))
+ return 1;
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(test_body, "dscr_user_test");
+}
--
1.9.3
^ permalink raw reply related
* [PATCH V2 09/12] selftests, powerpc: Add test for DSCR value inheritence across fork
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a test to verify that the changed DSCR value inside
any process would be inherited to it's child process across the fork
system call.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
tools/testing/selftests/powerpc/dscr/Makefile | 3 +-
.../selftests/powerpc/dscr/dscr_inherit_test.c | 96 ++++++++++++++++++++++
2 files changed, 98 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
index ae865d8..81239e2 100644
--- a/tools/testing/selftests/powerpc/dscr/Makefile
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -1,4 +1,5 @@
-PROGS := dscr_default_test dscr_explicit_test dscr_user_test
+PROGS := dscr_default_test dscr_explicit_test dscr_user_test \
+ dscr_inherit_test
CFLAGS := $(CFLAGS) -lpthread
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
new file mode 100644
index 0000000..f1add77
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
@@ -0,0 +1,96 @@
+/*
+ * POWER Data Stream Control Register (DSCR) fork test
+ *
+ * This testcase modifies the DSCR using mtspr, forks and then
+ * verifies that the child process has the correct changed DSCR
+ * value using mfspr.
+ *
+ * When using the privilege state SPR, the instructions such as
+ * mfspr or mtspr are priviledged and the kernel emulates them
+ * for us. Instructions using problem state SPR can be exuecuted
+ * directly without any emulation if the HW supports them. Else
+ * they also get emulated by the kernel.
+ *
+ * Copyright (C) 2012 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "dscr.h"
+
+int test_body(void)
+{
+ unsigned long i, dscr = 0;
+ pid_t pid;
+
+ srand(getpid());
+ set_dscr(dscr);
+
+ for (i = 0; i < COUNT; i++) {
+ unsigned long cur_dscr, cur_dscr_usr;
+
+ dscr++;
+ if (dscr > DSCR_MAX)
+ dscr = 0;
+
+ if (i % 2 == 0)
+ set_dscr_usr(dscr);
+ else
+ set_dscr(dscr);
+
+ /*
+ * XXX: Force a context switch out so that DSCR
+ * current value is copied into the thread struct
+ * which is required for the child to inherit the
+ * changed value.
+ */
+ sleep(1);
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork() failed\n");
+ exit(1);
+ } else if (pid) {
+ int status;
+
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid() failed\n");
+ exit(1);
+ }
+
+ if (!WIFEXITED(status)) {
+ fprintf(stderr, "Child didn't exit cleanly\n");
+ exit(1);
+ }
+
+ if (WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "Child didn't exit cleanly\n");
+ return 1;
+ }
+ } else {
+ cur_dscr = get_dscr();
+ if (cur_dscr != dscr) {
+ fprintf(stderr, "Kernel DSCR should be %ld "
+ "but is %ld\n", dscr, cur_dscr);
+ exit(1);
+ }
+
+ cur_dscr_usr = get_dscr_usr();
+ if (cur_dscr_usr != dscr) {
+ fprintf(stderr, "User DSCR should be %ld "
+ "but is %ld\n", dscr, cur_dscr_usr);
+ exit(1);
+ }
+ exit(0);
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(test_body, "dscr_inherit_test");
+}
--
1.9.3
^ permalink raw reply related
* [PATCH V2 10/12] selftests, powerpc: Add test for DSCR inheritence across fork & exec
From: Anshuman Khandual @ 2015-01-13 10:22 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, shuahkh, anton
In-Reply-To: <1421144560-15901-1-git-send-email-khandual@linux.vnet.ibm.com>
This patch adds a test case to verify that the changed DSCR value
inside any process would be inherited to it's child across the fork
and exec system call.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../powerpc/dscr/dscr_inherit_exec_test.c | 118 +++++++++++++++++++++
2 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
index 81239e2..4e84309 100644
--- a/tools/testing/selftests/powerpc/dscr/Makefile
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -1,5 +1,5 @@
PROGS := dscr_default_test dscr_explicit_test dscr_user_test \
- dscr_inherit_test
+ dscr_inherit_test dscr_inherit_exec_test
CFLAGS := $(CFLAGS) -lpthread
diff --git a/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
new file mode 100644
index 0000000..5ff3849
--- /dev/null
+++ b/tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
@@ -0,0 +1,118 @@
+/*
+ * POWER Data Stream Control Register (DSCR) fork exec test
+ *
+ * This testcase modifies the DSCR using mtspr, forks & execs and
+ * verifies that the child is using the changed DSCR using mfspr.
+ *
+ * When using the privilege state SPR, the instructions such as
+ * mfspr or mtspr are priviledged and the kernel emulates them
+ * for us. Instructions using problem state SPR can be exuecuted
+ * directly without any emulation if the HW supports them. Else
+ * they also get emulated by the kernel.
+ *
+ * Copyright (C) 2012 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2015 Anshuman Khandual <khandual@linux.vnet.ibm.com>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "dscr.h"
+
+static char prog[LEN_MAX];
+
+static void do_exec(unsigned long parent_dscr)
+{
+ unsigned long cur_dscr, cur_dscr_usr;
+
+ cur_dscr = get_dscr();
+ cur_dscr_usr = get_dscr_usr();
+
+ if (cur_dscr != parent_dscr) {
+ fprintf(stderr, "Parent DSCR %ld was not inherited "
+ "over exec (kernel value)\n", parent_dscr);
+ exit(1);
+ }
+
+ if (cur_dscr_usr != parent_dscr) {
+ fprintf(stderr, "Parent DSCR %ld was not inherited "
+ "over exec (user value)\n", parent_dscr);
+ exit(1);
+ }
+ exit(0);
+}
+
+int test_body(void)
+{
+ unsigned long i, dscr = 0;
+ pid_t pid;
+
+ for (i = 0; i < COUNT; i++) {
+ dscr++;
+ if (dscr > DSCR_MAX)
+ dscr = 0;
+
+ if (dscr == get_default_dscr())
+ continue;
+
+ if (i % 2 == 0)
+ set_dscr_usr(dscr);
+ else
+ set_dscr(dscr);
+
+ /*
+ * XXX: Force a context switch out so that DSCR
+ * current value is copied into the thread struct
+ * which is required for the child to inherit the
+ * changed value.
+ */
+ sleep(1);
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork() failed\n");
+ exit(1);
+ } else if (pid) {
+ int status;
+
+ if (waitpid(pid, &status, 0) == -1) {
+ perror("waitpid() failed\n");
+ exit(1);
+ }
+
+ if (!WIFEXITED(status)) {
+ fprintf(stderr, "Child didn't exit cleanly\n");
+ exit(1);
+ }
+
+ if (WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "Child didn't exit cleanly\n");
+ return 1;
+ }
+ } else {
+ char dscr_str[16];
+
+ sprintf(dscr_str, "%ld", dscr);
+ execlp(prog, prog, "exec", dscr_str, NULL);
+ exit(1);
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc == 3 && !strcmp(argv[1], "exec")) {
+ unsigned long parent_dscr;
+
+ parent_dscr = atoi(argv[2]);
+ do_exec(parent_dscr);
+ } else if (argc != 1) {
+ fprintf(stderr, "Usage: %s\n", argv[0]);
+ exit(1);
+ }
+
+ strncpy(prog, argv[0], strlen(argv[0]));
+ return test_harness(test_body, "dscr_inherit_exec_test");
+}
--
1.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox