Age | Commit message (Collapse) | Author | Files | Lines |
|
Fixes: 8f433d6cd4f92b4f878e5ddc414e2800a2fb7140
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
|
|
This removes below unnecessary message in phb3_sm_fundamental_reset()
as there already has on subsequent message indicating the situation.
Performing PERST...
Also, this decreases the outputing level of all messages in this
function to DEBUG.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
When issuing fundamental reset on below IPR adapter that seats
behind root complex, there is 50% possibility that the link
fails to come up after the reset. In that case, the adapter's
config space is blocked and it's not usable.
host# lspci -ns 0004:01:00.0
0004:01:00.0 0104: 1014:034a (rev 01)
host# lspci -s 0004:01:00.0
0004:01:00.0 RAID bus controller: IBM PCI-E IPR SAS Adapter
(ASIC) (rev 01)
This introduces another PHB3 state (PHB3_STATE_FRESET_START)
allowing to redo fundamental reset if the link doesn't come up
in time at the first attempt, to improve the robustness of PHB's
fundamental reset. If the link comes up after the first reset,
the 2nd reset won't be issued at all.
Reported-by: Paul Nguyen <nguyenp@us.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
This bug has originated since day 1 (of public release), what was going on
was that we were incorrectly using PSI_DMA_LOC_COD_BUF as the *address*
to write to for the FSP to read rather than using that purely as the
TCE table.
What we *should* have been doing (and this patch now does), is allocating
some (aligned) memory and using it.
With this patch, we no longer write over some poor random memory location
that could be being used by the host OS for something important, for example,
in the (internal) bug report of this, it was futex_hash_bucket in Linux
being replaced with our structure for replying to FSP_CMD_GET_LED_LIST (which
is around 4kb) and Linux doesn't like it when you replace a bunch of lock
data structures with essentially garbage.
Since this is FSP LED code specific, this only affects FSP based systems.
Reported-by: Dionysius d. Bell <belldi@us.ibm.com>
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
This removes below unnecessary message in phb3_sm_fundamental_reset()
as there already has on subsequent message indicating the situation.
Performing PERST...
Also, this decreases the outputing level of all messages in this
function to DEBUG.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
When issuing fundamental reset on below IPR adapter that seats
behind root complex, there is 50% possibility that the link
fails to come up after the reset. In that case, the adapter's
config space is blocked and it's not usable.
host# lspci -ns 0004:01:00.0
0004:01:00.0 0104: 1014:034a (rev 01)
host# lspci -s 0004:01:00.0
0004:01:00.0 RAID bus controller: IBM PCI-E IPR SAS Adapter
(ASIC) (rev 01)
This introduces another PHB3 state (PHB3_STATE_FRESET_START)
allowing to redo fundamental reset if the link doesn't come up
in time at the first attempt, to improve the robustness of PHB's
fundamental reset. If the link comes up after the first reset,
the 2nd reset won't be issued at all.
Reported-by: Paul Nguyen <nguyenp@us.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
When deciding if a BT message has timed out we should first check for
a message response. This will ensure that messages will not time out
if there was a delay calling the pollers.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
It works just like P8, we copy the code for now rather than make
it somewhat common due to our locking differences and to limit
the risk close to release. We can refactor later.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
We didn't pass the right "is_write" argument for writes and
the string used for logging was somewhat confusing.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
When struct phb3::has_link is set to true, the downstream link of
root port is up, not down. This fixes the incorrect comments.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Our normal sequence for a soft power action (IPMI 'power soft' or
'power cycle') involve receiving a SEL from the BMC, sending a message
to Linux's opal platform support which instructs the host OS to shut
down, and finally the host will request OPAL to cut power.
When the host is not yet up we will send the message to /dev/null, and
no action will be taken. This patches changes that behaviour to perform
the action immediately if we know how.
Signed-off-by: Joel Stanley <joel@jms.id.au>
[stewart@linux.vnet.ibm.com: modify checking of OPAL_BOOT_COMPLETE flag, typo]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
We disallow to inject error to reserved PE#, which is 255 instead
of 0 on PHB3. Otherwise, error OPAL_PARAM is returned when injecting
error to PE#0.
This fixes above issue by checking against the correct PE number 255.
Reported-by: Pradeep Ramanna <pramann2@in.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
In the event of a lot of OCC events (or many CPU cores), we could
send many OCC messages to the host, which if it wasn't calling
opal_get_msg really often, would cause skiboot to malloc() additional
messages until we ran out of skiboot heap and things didn't end up
being much fun.
When running certain hardware exercisers, they seem to steal all time
from Linux being able to call opal_get_msg, causing these to queue up
and get "opalmsg: No available node in the free list, allocating" warnings
followed by tonnes of backtraces of failing memory allocations.
|
|
Copy/paste bug ... we were displaying the same message for
all error sources.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Recent HostBoot & SBE firmware provide a HW timer facility that can
be used to implement OPAL timers and thus limit the reliance on the
Linux heartbeat.
This implements support for it. The side effect is that i2c from Centaurs
is now usable.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[stewart@linux.vnet.ibm.com: fix run-timer unit test]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
The caller usually has it and it avoids additional mftb() which
can be expensive.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[stewart@linux.vnet.ibm.com: fix run-timer unit test]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
The patch fixes an illegal access to the memory which has been
freed.
Fixes Coverity defect # 101858
Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Nothing critical, no functional changes.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Presently abort() function is not working on BMC based machine. System
hangs after abort/assert call. We have to reboot machine from BMC (IPMI
command or BMC console).
This patch introduces attention functionality for BMC based machine.
It logs eSEL event that contains OPAL version, file info and backtrace.
And calls cec_reboot... which takes care of rebooting host.
Note:
- This patch uses ipmi_queue_msg() instead of ipmi_queue_msg_sync() as
we are having some issues with sync path. This will resolved once we
sort out [1].
- This patch calls cec_reboot to reboot machine after logging eSEL event.
It queues IPMI message and bt_poll() should be working until we pass
reboot IPMI message to BMC. Hence we have while loop with time_wait_ms().
Alternatively we can use xscom_trigger_xstop().. but it will stop
immediately and eSEL logging fails.
[1] https://lists.ozlabs.org/pipermail/skiboot/2015-August/001824.html
Sample eSEL output after assert call:
------------------------------------
[hegdevasant@hegdevasant bin]$ strings fir01bmc.150820.120511.eSel.binary
BB821410
AT8335-GTA000000000000
AT8335-GTA000000000000UD
ATDESC
OPAL version : skiboot-5.1.1-44-geae3999-hegdevasant-dirty-bb31bfd
File info : core/init.c:463:0
CPU 0060 Backtrace:
S: 0000000031d83bc0 R: 000000003006086c .ipmi_terminate+0x110
S: 0000000031d83c60 R: 0000000030017f90 ._abort+0x80
S: 0000000031d83ce0 R: 0000000030017fd8 .assert_fail+0x34
S: 0000000031d83d60 R: 0000000030013dcc .load_and_boot_kernel+0x784
S: 0000000031d83e30 R: 000000003001437c .main_cpu_entry+0x57c
S: 0000000031d83f00 R: 0000000030002544 boot_entry+0x194
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Presently abort() call sets up HID0, triggers attention and finally
calls infinite for loop. FSP takes care of collecting required logs
and reboots the system. This sequence is specific to FSP machine
and it will not work on BMC based machine. Hence move FSP specific
code to hw/fsp/fsp-attn.c.
Note that this patch adds new parameter to abort call. Hence replaced
_abort() by abort() in exception.c so that we can capture file info
as well.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
We want to use MAX_PEL_SIZE in other code (like attention) as well.
Hence move this to ipmi.h.
Also rename MAX_PEL_SIZE as IPMI_MAX_PEL_SIZE to reflect its IPMI
specific macro.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Currently we allocate ipmi_msg for every eSEL event.. But in PANIC
its not advised to allocate memory. Hence pre-allocate ipmi_msg for
PANIC event.
Note that we continue to allocate memory for normal event. Also with
current implementation we can log only one eSEL event in PANIC path.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Presently we allocate ipmi_msg separately for SEL and eSEL event
...which is not required. Instead we can use same memory for sending
SEL event. As these two events are serialized.
This is useful when we pre-allocate memory for PANIC path.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
We log SEL event with eSEL record ID for every eSEL event. Presently
SEL event is added to tail of IPMI queue. It works fine during normal
event. But it fails in terminate immediate path...as reboot message
will be called before SEL event.
This patch adds message to head of IPMI queue.. so that we can log
SEL event before sending reboot.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
eSEL logging fails, if eSEL event size is multiples of IPMI
buffer size.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
In the event that we had no IO paths up, we could index -1 into the
array of iopaths, no doubt causing casual amounts of fun.
Although, since this is in early boot code only, the possibility of
this being a problem is quite slim.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
merge in CAPI fixes from Ian and Daniel
|
|
It only sends one event, so this name is more accurate.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Acked-by: Jeremy Kerr <jk@ozlabs.org>
|
|
In send_pending_events() we set event to the type of event received
yet did nothing with it.
This seems to be a left over bit of code, as what does happen is on
consuming the message (prd_msg_consumed) we'll clear the event bit
and then send the next event:
120 if (event)
121 events[proc] &= ~event;
122 prd_msg_inuse = false;
123 send_pending_events();
124 unlock(&events_lock);
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Acked-by: Jeremy Kerr <jk@ozlabs.org>
|
|
If the PHB is fenced during phb3_pci_msi_check_q, it can get stuck in an
infinite loop waiting to lock the FFI. Further, as the phb lock is held
during this function it will prevent any other CPUs from dealing with
the fence, leading to the entire system hanging.
If the PHB_FFI_LOCK returns all Fs, return immediately to allow the
fence to be dealt with.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Instead just print a PR_TRACE notice as (by design), this is an okay thing.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Just log an error if we fail to re-read GP0.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
See https://github.com/lucasdemarchi/codespel
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
This fixes a critical bug in CAPI support.
CAPI requires that all faults are escalated into a fence, not a
freeze. This is done by setting bits in a number of MMIO
registers. phb3_set_capi_mode() calls phb3_init_capp_errors() to do
this. However, if the PHB is already in CAPP mode - for example in the
recovery case - phb3_set_capi_mode() will bail out early, and those
registers will not be set.
This is quite easy to verify. PCI config space access errors, for
example, normally cause a freeze. On a CAPI-mode PHB, they should
cause a fence. Say we have a CAPI card on PHB 0, and we inject a
PCI config space error:
echo 0x8000000000000000 > /sys/kernel/debug/powerpc/PCI0000/err_injct_inboundA;
lspci;
The first time we inject this, the PHB will fence and recover, but
won't reset the registers. Therefore, the second time we inject it,
we will incorrectly freeze, not fence.
Worse, the recovery for the resultant EEH freeze event interacts
poorly with the CAPP, triggering an EEH recovery of the PHB. The
combination of the two attempted recoveries will get the PHB into
an inoperable state.
It's quite likely that there other side effects of bailing out
early. For example, the timebase sync probably fails to recover.
Rather than auditing all the possibilities, I verified that
repeating the entire setup procedure still works when the PHB is
already in CAPP mode. It does work, so just do the entire setup
every time instead of bailing out early.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Acked-By: Michael Neuling <mikey@neuling.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Hostboot is going to cover these ranges with its own reservations (to
allow access from the HBRT image), so don't overwrite reservations
with our own.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Our PEL logs doesn't contain timestamp as we don't have timesource.
Hence create SEL event for every eSEL log with eSEL record ID. This
event will be used to get PEL event time.
New SEL event contains eSEL record ID.
Sample output:
-------------
SEL Record ID : 0016
Record Type : 02
Timestamp : 08/09/2015 12:35:16
Generator ID : 0020
EvM Revision : 04
Sensor Type : System Event
Sensor Number : 61
Event Type : Generic Discrete
Event Direction : Assertion Event
Event Data (RAW) : 011400
Description : State Asserted
Sensor ID : System Event (0x61)
Entity ID : 1.0
Sensor Type (Discrete): System Event
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Presently we are passing PEL log without adding Extended SEL record.
Hence logging eSEL event is failing.
This patch sends Extended SEL structure before sending actual PEL log.
So that BMC understands its eSEL log and logs it appropriately.
eSEL format:
<IPMI SEL header> : <eSEL record> : <PEL data>
Note that we use sensor type "System Event (0x12)" for logging OPAL
events.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Cc: Alistair Popple <alistair@popple.id.au>
Cc: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
This fixes a critical bug in CAPI support.
CAPI requires that all faults are escalated into a fence, not a
freeze. This is done by setting bits in a number of MMIO
registers. phb3_set_capi_mode() calls phb3_init_capp_errors() to do
this. However, if the PHB is already in CAPP mode - for example in the
recovery case - phb3_set_capi_mode() will bail out early, and those
registers will not be set.
This is quite easy to verify. PCI config space access errors, for
example, normally cause a freeze. On a CAPI-mode PHB, they should
cause a fence. Say we have a CAPI card on PHB 0, and we inject a
PCI config space error:
echo 0x8000000000000000 > /sys/kernel/debug/powerpc/PCI0000/err_injct_inboundA;
lspci;
The first time we inject this, the PHB will fence and recover, but
won't reset the registers. Therefore, the second time we inject it,
we will incorrectly freeze, not fence.
Worse, the recovery for the resultant EEH freeze event interacts
poorly with the CAPP, triggering an EEH recovery of the PHB. The
combination of the two attempted recoveries will get the PHB into
an inoperable state.
It's quite likely that there other side effects of bailing out
early. For example, the timebase sync probably fails to recover.
Rather than auditing all the possibilities, I verified that
repeating the entire setup procedure still works when the PHB is
already in CAPP mode. It does work, so just do the entire setup
every time instead of bailing out early.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Presently we are logging all the events to service processor (FSP/BMC).
But on BMC machines we should only log events that requires attention.
As per PEL spec, we should log events with severity >= 0x22 and "service
action flag" is "on". But in our case, all logs OPAL originagted logs
are makred as report externally.
So lets log all events that are originated from OAPL (presently all logs
as payload is not logging any PEL event) and severity >= 0x22.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Alistair Popple <alistair@popple.id.au>
Cc: Jeremy Kerr <jk@ozlabs.org>
[stewart@linux.vnet.ibm.com: s/SEL:/IPMI:/ in prlog]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Currently we are assuming Max PEL size is 64K. But in reality log size
much lesser than this. Hence chose max size to 2K.
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Cc: Alistair Popple <alistair@popple.id.au>
Cc: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Currently, we have reserved PE#0 to which all RIDs are mapped prior
to PE assignment request from kernel. The last M64 BAR is configured
to have shared mode. So we have to cut off the first M64 segment,
which corresponds to reserved PE#0 in kernel. If the first BAR
(for example PF's IOV BAR) requires huge alignment in kernel, we
have to waste huge M64 space to accomodate the alignment. If we
have reserved PE#256, the waste of M64 space will be avoided.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Initialized variable rc to 0, to fix uninitialized value
issue.
Fixes Coverity defect#101857.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Acked-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
In p7ioc_err_inject_io32() addr is passed as an argument.
Based on its value , we have a conditional check(s).
Re-assigning the addr to 0x0ull, make the whole branching
check(s) a dead code.
Remove the re-assignment of addr, to fix the issue.
Fixes Coverity defect#101020.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Gavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
Refactor _chiptod_get_chip_status(), to remove goto
label.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
If chiptod_adjust_topology returned true, rc would be uninitialised and the
message type passed to fsp_mkmsg would be undefined.
This also changes chiptod_adjust_topology to return true/false instead
of -1 and 0.
hw/fsp/fsp-chiptod.c:45:7: error: variable 'rc' is used uninitialized whenever
'if' condition is false [-Werror,-Wsometimes-uninitialized]
if (chiptod_adjust_topology(topo, action) < 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hw/fsp/fsp-chiptod.c:48:50: note: uninitialized use occurs here
resp = fsp_mkmsg(FSP_RSP_TOPO_ENABLE_DISABLE | rc, 0);
^~
hw/fsp/fsp-chiptod.c:45:3: note: remove the 'if' if its condition is always true
if (chiptod_adjust_topology(topo, action) < 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hw/fsp/fsp-chiptod.c:30:12: note: initialize the variable 'rc' to silence this
warning
uint8_t rc;
^
= '\0'
Signed-off-by: Joel Stanley <joel@jms.id.au>
foo
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|
|
In the error path of the OPAL function to receive the ipmi message,
the function returns the error code without deleting the message
containing response. Though the kernel doesn't claim this message
later and continue with the subsequent ipmi commands. This leads to
a scenario when there is a mismatch between the ipmi command and its
response for all the subsequent ipmi commands.
Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Cc: Alistair Popple <alistair@popple.id.au>
Acked-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
|