Commit 8a1182eb authored by Benjamin Romer's avatar Benjamin Romer Committed by Greg Kroah-Hartman

staging: unisys: detect controlvm channel on module load

The controlvm channel is not removable from a guest after the guest starts,
so it makes no sense to constantly check for it. Move the channel address
discovery to visorchipset_init(), and remove all of the checks for the channel
address from the rest of the module, as the module will not load if the
channel pointer is not valid.
Signed-off-by: default avatarBenjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 524b0b63
...@@ -576,8 +576,6 @@ static void ...@@ -576,8 +576,6 @@ static void
controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response) controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
{ {
CONTROLVM_MESSAGE outmsg; CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response); controlvm_init_response(&outmsg, msgHdr, response);
/* For DiagPool channel DEVICE_CHANGESTATE, we need to send /* For DiagPool channel DEVICE_CHANGESTATE, we need to send
* back the deviceChangeState structure in the packet. */ * back the deviceChangeState structure in the packet. */
...@@ -604,8 +602,6 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response, ...@@ -604,8 +602,6 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
ULTRA_CHIPSET_FEATURE features) ULTRA_CHIPSET_FEATURE features)
{ {
CONTROLVM_MESSAGE outmsg; CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response); controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.initChipset.features = features; outmsg.cmd.initChipset.features = features;
if (!visorchannel_signalinsert(ControlVm_channel, if (!visorchannel_signalinsert(ControlVm_channel,
...@@ -620,8 +616,6 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr, ...@@ -620,8 +616,6 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
int response, ULTRA_SEGMENT_STATE state) int response, ULTRA_SEGMENT_STATE state)
{ {
CONTROLVM_MESSAGE outmsg; CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
controlvm_init_response(&outmsg, msgHdr, response); controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.deviceChangeState.state = state; outmsg.cmd.deviceChangeState.state = state;
outmsg.cmd.deviceChangeState.flags.physicalDevice = 1; outmsg.cmd.deviceChangeState.flags.physicalDevice = 1;
...@@ -739,9 +733,6 @@ device_changestate_responder(CONTROLVM_ID cmdId, ...@@ -739,9 +733,6 @@ device_changestate_responder(CONTROLVM_ID cmdId,
VISORCHIPSET_DEVICE_INFO *p = NULL; VISORCHIPSET_DEVICE_INFO *p = NULL;
CONTROLVM_MESSAGE outmsg; CONTROLVM_MESSAGE outmsg;
if (!ControlVm_channel)
return;
p = finddevice(&DevInfoList, busNo, devNo); p = finddevice(&DevInfoList, busNo, devNo);
if (!p) { if (!p) {
LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo); LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
...@@ -1855,7 +1846,6 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1855,7 +1846,6 @@ controlvm_periodic_work(struct work_struct *work)
{ {
VISORCHIPSET_CHANNEL_INFO chanInfo; VISORCHIPSET_CHANNEL_INFO chanInfo;
CONTROLVM_MESSAGE inmsg; CONTROLVM_MESSAGE inmsg;
char s[99];
BOOL gotACommand = FALSE; BOOL gotACommand = FALSE;
BOOL handle_command_failed = FALSE; BOOL handle_command_failed = FALSE;
static U64 Poll_Count; static U64 Poll_Count;
...@@ -1870,32 +1860,9 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1870,32 +1860,9 @@ controlvm_periodic_work(struct work_struct *work)
goto Away; goto Away;
memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO)); memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO));
if (!ControlVm_channel) {
HOSTADDRESS addr = controlvm_get_channel_address();
if (addr != 0) {
ControlVm_channel =
visorchannel_create_with_lock
(addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ControlVm_channel == NULL)
LOGERR("failed to create controlvm channel");
else if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
(visorchannel_get_header(ControlVm_channel),
NULL)) {
LOGINF("Channel %s (ControlVm) discovered",
visorchannel_id(ControlVm_channel, s));
initialize_controlvm_payload();
} else {
LOGERR("controlvm channel is invalid");
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
}
}
}
Poll_Count++; Poll_Count++;
if ((ControlVm_channel != NULL) || (Poll_Count >= 250)) if (Poll_Count >= 250)
; /* keep going */ ; /* keep going */
else else
goto Away; goto Away;
...@@ -1914,54 +1881,46 @@ controlvm_periodic_work(struct work_struct *work) ...@@ -1914,54 +1881,46 @@ controlvm_periodic_work(struct work_struct *work)
} }
} }
if (ControlVm_channel) { while (visorchannel_signalremove(ControlVm_channel,
while (visorchannel_signalremove(ControlVm_channel, CONTROLVM_QUEUE_RESPONSE,
CONTROLVM_QUEUE_RESPONSE, &inmsg)) {
&inmsg)) { if (inmsg.hdr.PayloadMaxBytes != 0) {
if (inmsg.hdr.PayloadMaxBytes != 0) { LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.", (ulong) inmsg.hdr.PayloadMaxBytes,
(ulong) inmsg.hdr.PayloadMaxBytes, (ulong) inmsg.hdr.PayloadVmOffset,
(ulong) inmsg.hdr.PayloadVmOffset, inmsg.hdr.Id);
inmsg.hdr.Id);
}
}
if (!gotACommand) {
if (ControlVm_Pending_Msg_Valid) {
/* we throttled processing of a prior
* msg, so try to process it again
* rather than reading a new one
*/
inmsg = ControlVm_Pending_Msg;
ControlVm_Pending_Msg_Valid = FALSE;
gotACommand = TRUE;
} else
gotACommand = read_controlvm_event(&inmsg);
} }
} }
if (!gotACommand) {
if (ControlVm_Pending_Msg_Valid) {
/* we throttled processing of a prior
* msg, so try to process it again
* rather than reading a new one
*/
inmsg = ControlVm_Pending_Msg;
ControlVm_Pending_Msg_Valid = FALSE;
gotACommand = TRUE;
} else
gotACommand = read_controlvm_event(&inmsg);
}
handle_command_failed = FALSE; handle_command_failed = FALSE;
while (gotACommand && (!handle_command_failed)) { while (gotACommand && (!handle_command_failed)) {
Most_recent_message_jiffies = jiffies; Most_recent_message_jiffies = jiffies;
if (ControlVm_channel) { if (handle_command(inmsg,
if (handle_command(inmsg, visorchannel_get_physaddr
visorchannel_get_physaddr (ControlVm_channel)))
(ControlVm_channel))) gotACommand = read_controlvm_event(&inmsg);
gotACommand = read_controlvm_event(&inmsg); else {
else { /* this is a scenario where throttling
/* this is a scenario where throttling * is required, but probably NOT an
* is required, but probably NOT an * error...; we stash the current
* error...; we stash the current * controlvm msg so we will attempt to
* controlvm msg so we will attempt to * reprocess it on our next loop
* reprocess it on our next loop */
*/ handle_command_failed = TRUE;
handle_command_failed = TRUE; ControlVm_Pending_Msg = inmsg;
ControlVm_Pending_Msg = inmsg; ControlVm_Pending_Msg_Valid = TRUE;
ControlVm_Pending_Msg_Valid = TRUE;
}
} else {
handle_command(inmsg, 0);
gotACommand = FALSE;
} }
} }
...@@ -1998,7 +1957,6 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -1998,7 +1957,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
CONTROLVM_MESSAGE localCrashCreateBusMsg; CONTROLVM_MESSAGE localCrashCreateBusMsg;
CONTROLVM_MESSAGE localCrashCreateDevMsg; CONTROLVM_MESSAGE localCrashCreateDevMsg;
CONTROLVM_MESSAGE msg; CONTROLVM_MESSAGE msg;
HOSTADDRESS host_addr;
U32 localSavedCrashMsgOffset; U32 localSavedCrashMsgOffset;
U16 localSavedCrashMsgCount; U16 localSavedCrashMsgCount;
...@@ -2021,26 +1979,6 @@ setup_crash_devices_work_queue(struct work_struct *work) ...@@ -2021,26 +1979,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
chipset_init(&msg); chipset_init(&msg);
host_addr = controlvm_get_channel_address();
if (!host_addr) {
LOGERR("Huh? Host address is NULL");
POSTCODE_LINUX_2(CRASH_DEV_HADDR_NULL, POSTCODE_SEVERITY_ERR);
return;
}
ControlVm_channel =
visorchannel_create_with_lock
(host_addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ControlVm_channel == NULL) {
LOGERR("failed to create controlvm channel");
POSTCODE_LINUX_2(CRASH_DEV_CONTROLVM_NULL,
POSTCODE_SEVERITY_ERR);
return;
}
/* get saved message count */ /* get saved message count */
if (visorchannel_read(ControlVm_channel, if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
...@@ -2331,9 +2269,6 @@ proc_read_installer(struct file *file, char __user *buf, ...@@ -2331,9 +2269,6 @@ proc_read_installer(struct file *file, char __user *buf,
char *vbuf; char *vbuf;
loff_t pos = *offset; loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
...@@ -2383,9 +2318,6 @@ proc_write_installer(struct file *file, ...@@ -2383,9 +2318,6 @@ proc_write_installer(struct file *file,
U16 remainingSteps; U16 remainingSteps;
U32 error, textId; U32 error, textId;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */ /* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1)) if (count > (sizeof(buf) - 1))
return -EINVAL; return -EINVAL;
...@@ -2447,9 +2379,6 @@ proc_read_toolaction(struct file *file, char __user *buf, ...@@ -2447,9 +2379,6 @@ proc_read_toolaction(struct file *file, char __user *buf,
char *vbuf; char *vbuf;
loff_t pos = *offset; loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
...@@ -2488,9 +2417,6 @@ proc_write_toolaction(struct file *file, ...@@ -2488,9 +2417,6 @@ proc_write_toolaction(struct file *file,
char buf[3]; char buf[3];
U8 toolAction; U8 toolAction;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */ /* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1)) if (count > (sizeof(buf) - 1))
return -EINVAL; return -EINVAL;
...@@ -2530,9 +2456,6 @@ proc_read_bootToTool(struct file *file, char __user *buf, ...@@ -2530,9 +2456,6 @@ proc_read_bootToTool(struct file *file, char __user *buf,
char *vbuf; char *vbuf;
loff_t pos = *offset; loff_t pos = *offset;
if (!ControlVm_channel)
return -ENODEV;
if (pos < 0) if (pos < 0)
return -EINVAL; return -EINVAL;
...@@ -2571,9 +2494,6 @@ proc_write_bootToTool(struct file *file, ...@@ -2571,9 +2494,6 @@ proc_write_bootToTool(struct file *file,
int inputVal; int inputVal;
ULTRA_EFI_SPAR_INDICATION efiSparIndication; ULTRA_EFI_SPAR_INDICATION efiSparIndication;
if (!ControlVm_channel)
return -ENODEV;
/* Check to make sure there is no buffer overflow */ /* Check to make sure there is no buffer overflow */
if (count > (sizeof(buf) - 1)) if (count > (sizeof(buf) - 1))
return -EINVAL; return -EINVAL;
...@@ -2612,9 +2532,11 @@ static int __init ...@@ -2612,9 +2532,11 @@ static int __init
visorchipset_init(void) visorchipset_init(void)
{ {
int rc = 0, x = 0; int rc = 0, x = 0;
char s[64];
struct proc_dir_entry *installer_file; struct proc_dir_entry *installer_file;
struct proc_dir_entry *toolaction_file; struct proc_dir_entry *toolaction_file;
struct proc_dir_entry *bootToTool_file; struct proc_dir_entry *bootToTool_file;
HOSTADDRESS addr;
if (!unisys_spar_platform) if (!unisys_spar_platform)
return -ENODEV; return -ENODEV;
...@@ -2646,6 +2568,30 @@ visorchipset_init(void) ...@@ -2646,6 +2568,30 @@ visorchipset_init(void)
goto Away; goto Away;
} }
addr = controlvm_get_channel_address();
if (addr != 0) {
ControlVm_channel =
visorchannel_create_with_lock
(addr,
sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
UltraControlvmChannelProtocolGuid);
if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
(visorchannel_get_header(ControlVm_channel),
NULL)) {
LOGINF("Channel %s (ControlVm) discovered",
visorchannel_id(ControlVm_channel, s));
initialize_controlvm_payload();
} else {
LOGERR("controlvm channel is invalid");
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
return -ENODEV;
}
} else {
LOGERR("no controlvm channel discovered");
return -ENODEV;
}
MajorDev = MKDEV(visorchipset_major, 0); MajorDev = MKDEV(visorchipset_major, 0);
rc = visorchipset_file_init(MajorDev, &ControlVm_channel); rc = visorchipset_file_init(MajorDev, &ControlVm_channel);
if (rc < 0) { if (rc < 0) {
...@@ -2795,12 +2741,10 @@ visorchipset_exit(void) ...@@ -2795,12 +2741,10 @@ visorchipset_exit(void)
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER)); memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
proc_DeInit(); proc_DeInit();
if (ControlVm_channel != NULL) { LOGINF("Channel %s (ControlVm) disconnected",
LOGINF("Channel %s (ControlVm) disconnected", visorchannel_id(ControlVm_channel, s));
visorchannel_id(ControlVm_channel, s)); visorchannel_destroy(ControlVm_channel);
visorchannel_destroy(ControlVm_channel);
ControlVm_channel = NULL;
}
visorchipset_file_cleanup(); visorchipset_file_cleanup();
POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO); POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
LOGINF("chipset driver unloaded"); LOGINF("chipset driver unloaded");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment