summaryrefslogtreecommitdiff
path: root/drivers/staging/unisys
diff options
context:
space:
mode:
authorSameer Wadgaonkar <sameer.wadgaonkar@unisys.com>2017-04-18 16:55:24 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-28 11:55:53 +0200
commitbb1fb8ac399f75fccf3da5c7430a40bb0e5f01c8 (patch)
tree24bac1dea0e1cbec72b1d716ef5f443837475bf9 /drivers/staging/unisys
parent372b9f22763915ea32d19f6397f6292d2667e2bf (diff)
staging: unisys: visorbus: fix s-Par to boot with option CONFIG_VMAP_STACK set to y
The root issue is that we are not allowed to have items on the stack being passed to "DMA" like operations. In this case we have vmcall operation that was using parameters from the stack. This patch fixes the issue by moving the variables on stack in issue_vmcall_io_controlvm_addr() to vmcall_controlvm_addr struct. Signed-off-by: Sameer Wadgaonkar <sameer.wadgaonkar@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.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index e098526372cb..4cfd0fae9bd5 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -57,6 +57,12 @@ struct parser_context {
char data[0];
};
+struct vmcall_controlvm_addr {
+ struct vmcall_io_controlvm_addr_params params;
+ int err;
+ u64 physaddr;
+};
+
struct visorchipset_device {
struct acpi_device *acpi_device;
unsigned long poll_jiffies;
@@ -74,6 +80,7 @@ struct visorchipset_device {
*/
struct controlvm_message controlvm_pending_msg;
bool controlvm_pending_msg_valid;
+ struct vmcall_controlvm_addr controlvm_addr;
};
static struct visorchipset_device *chipset_dev;
@@ -1338,17 +1345,15 @@ error: /* Need to convert from VMCALL error codes to Linux */
static unsigned int
issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes)
{
- struct vmcall_io_controlvm_addr_params params;
- int err;
- u64 physaddr;
+ chipset_dev->controlvm_addr.physaddr = virt_to_phys(
+ &chipset_dev->controlvm_addr.params);
+ chipset_dev->controlvm_addr.err = unisys_vmcall(VMCALL_CONTROLVM_ADDR,
+ chipset_dev->controlvm_addr.physaddr);
+ if (chipset_dev->controlvm_addr.err)
+ return chipset_dev->controlvm_addr.err;
- physaddr = virt_to_phys(&params);
- err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, physaddr);
- if (err)
- return err;
-
- *control_addr = params.address;
- *control_bytes = params.channel_bytes;
+ *control_addr = chipset_dev->controlvm_addr.params.address;
+ *control_bytes = chipset_dev->controlvm_addr.params.channel_bytes;
return 0;
}
@@ -1819,14 +1824,14 @@ visorchipset_init(struct acpi_device *acpi_device)
uuid_le uuid = SPAR_CONTROLVM_CHANNEL_PROTOCOL_UUID;
struct visorchannel *controlvm_channel;
- addr = controlvm_get_channel_address();
- if (!addr)
- goto error;
-
chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL);
if (!chipset_dev)
goto error;
+ addr = controlvm_get_channel_address();
+ if (!addr)
+ goto error;
+
acpi_device->driver_data = chipset_dev;
chipset_dev->acpi_device = acpi_device;