summaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys
diff options
context:
space:
mode:
authorTim Sell2016-03-02 01:45:03 +0100
committerGreg Kroah-Hartman2016-03-02 04:14:07 +0100
commitc732623b0bb3631d61203e1e9f87bee34b7fd169 (patch)
tree18b74a00401b335379a6c2ad2691532225296ae9 /drivers/staging/unisys
parentstaging: unisys: visorbus: fix payload memory usage in controlvm channel (diff)
downloadkernel-qcow2-linux-c732623b0bb3631d61203e1e9f87bee34b7fd169.tar.gz
kernel-qcow2-linux-c732623b0bb3631d61203e1e9f87bee34b7fd169.tar.xz
kernel-qcow2-linux-c732623b0bb3631d61203e1e9f87bee34b7fd169.zip
staging: unisys: visorbus: tolerate larger-than-expected controlvm channel
Use the dynamic size of the controlvm channel (struct channel_header.size) instead of the statically computed sizeof(struct controlvm_channel) when determining the valid bounds for visorchannel_read() and visorchannel_write(). This prevents an observed problem where kdump was failing because controlvm_channel.local_crash_msg_offset was pointing beyond the statically computed size of the channel, even though the channel was physically large enough. This was causing visorchannel_read() to unecessarily fail, because we thought we were attempting to access memory outside of the channel. Signed-off-by: Timothy Sell <timothy.sell@unisys.com> Signed-off-by: David Kershner <david.kershner@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/unisys')
-rw-r--r--drivers/staging/unisys/visorbus/visorchipset.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index e1a5b672fe6d..166a067e8bb4 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -2251,7 +2251,6 @@ visorchipset_init(struct acpi_device *acpi_device)
{
int rc = 0;
u64 addr;
- int tmp_sz = sizeof(struct spar_controlvm_channel_protocol);
uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID;
addr = controlvm_get_channel_address();
@@ -2261,8 +2260,10 @@ visorchipset_init(struct acpi_device *acpi_device)
memset(&busdev_notifiers, 0, sizeof(busdev_notifiers));
memset(&controlvm_payload_info, 0, sizeof(controlvm_payload_info));
- controlvm_channel = visorchannel_create_with_lock(addr, tmp_sz,
+ controlvm_channel = visorchannel_create_with_lock(addr, 0,
GFP_KERNEL, uuid);
+ if (!controlvm_channel)
+ return -ENODEV;
if (SPAR_CONTROLVM_CHANNEL_OK_CLIENT(
visorchannel_get_header(controlvm_channel))) {
initialize_controlvm_payload();