mirror of https://gitee.com/openkylin/linux.git
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: Benjamin Romer <benjamin.romer@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
524b0b63a1
commit
8a1182eb34
|
@ -576,8 +576,6 @@ static void
|
|||
controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
|
||||
{
|
||||
CONTROLVM_MESSAGE outmsg;
|
||||
if (!ControlVm_channel)
|
||||
return;
|
||||
controlvm_init_response(&outmsg, msgHdr, response);
|
||||
/* For DiagPool channel DEVICE_CHANGESTATE, we need to send
|
||||
* back the deviceChangeState structure in the packet. */
|
||||
|
@ -604,8 +602,6 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
|
|||
ULTRA_CHIPSET_FEATURE features)
|
||||
{
|
||||
CONTROLVM_MESSAGE outmsg;
|
||||
if (!ControlVm_channel)
|
||||
return;
|
||||
controlvm_init_response(&outmsg, msgHdr, response);
|
||||
outmsg.cmd.initChipset.features = features;
|
||||
if (!visorchannel_signalinsert(ControlVm_channel,
|
||||
|
@ -620,8 +616,6 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
|
|||
int response, ULTRA_SEGMENT_STATE state)
|
||||
{
|
||||
CONTROLVM_MESSAGE outmsg;
|
||||
if (!ControlVm_channel)
|
||||
return;
|
||||
controlvm_init_response(&outmsg, msgHdr, response);
|
||||
outmsg.cmd.deviceChangeState.state = state;
|
||||
outmsg.cmd.deviceChangeState.flags.physicalDevice = 1;
|
||||
|
@ -739,9 +733,6 @@ device_changestate_responder(CONTROLVM_ID cmdId,
|
|||
VISORCHIPSET_DEVICE_INFO *p = NULL;
|
||||
CONTROLVM_MESSAGE outmsg;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return;
|
||||
|
||||
p = finddevice(&DevInfoList, busNo, devNo);
|
||||
if (!p) {
|
||||
LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
|
||||
|
@ -1855,7 +1846,6 @@ controlvm_periodic_work(struct work_struct *work)
|
|||
{
|
||||
VISORCHIPSET_CHANNEL_INFO chanInfo;
|
||||
CONTROLVM_MESSAGE inmsg;
|
||||
char s[99];
|
||||
BOOL gotACommand = FALSE;
|
||||
BOOL handle_command_failed = FALSE;
|
||||
static U64 Poll_Count;
|
||||
|
@ -1870,32 +1860,9 @@ controlvm_periodic_work(struct work_struct *work)
|
|||
goto Away;
|
||||
|
||||
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++;
|
||||
if ((ControlVm_channel != NULL) || (Poll_Count >= 250))
|
||||
if (Poll_Count >= 250)
|
||||
; /* keep going */
|
||||
else
|
||||
goto Away;
|
||||
|
@ -1914,54 +1881,46 @@ controlvm_periodic_work(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
if (ControlVm_channel) {
|
||||
while (visorchannel_signalremove(ControlVm_channel,
|
||||
CONTROLVM_QUEUE_RESPONSE,
|
||||
&inmsg)) {
|
||||
if (inmsg.hdr.PayloadMaxBytes != 0) {
|
||||
LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
|
||||
(ulong) inmsg.hdr.PayloadMaxBytes,
|
||||
(ulong) inmsg.hdr.PayloadVmOffset,
|
||||
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);
|
||||
while (visorchannel_signalremove(ControlVm_channel,
|
||||
CONTROLVM_QUEUE_RESPONSE,
|
||||
&inmsg)) {
|
||||
if (inmsg.hdr.PayloadMaxBytes != 0) {
|
||||
LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
|
||||
(ulong) inmsg.hdr.PayloadMaxBytes,
|
||||
(ulong) inmsg.hdr.PayloadVmOffset,
|
||||
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);
|
||||
}
|
||||
|
||||
handle_command_failed = FALSE;
|
||||
while (gotACommand && (!handle_command_failed)) {
|
||||
Most_recent_message_jiffies = jiffies;
|
||||
if (ControlVm_channel) {
|
||||
if (handle_command(inmsg,
|
||||
visorchannel_get_physaddr
|
||||
(ControlVm_channel)))
|
||||
gotACommand = read_controlvm_event(&inmsg);
|
||||
else {
|
||||
/* this is a scenario where throttling
|
||||
* is required, but probably NOT an
|
||||
* error...; we stash the current
|
||||
* controlvm msg so we will attempt to
|
||||
* reprocess it on our next loop
|
||||
*/
|
||||
handle_command_failed = TRUE;
|
||||
ControlVm_Pending_Msg = inmsg;
|
||||
ControlVm_Pending_Msg_Valid = TRUE;
|
||||
}
|
||||
|
||||
} else {
|
||||
handle_command(inmsg, 0);
|
||||
gotACommand = FALSE;
|
||||
if (handle_command(inmsg,
|
||||
visorchannel_get_physaddr
|
||||
(ControlVm_channel)))
|
||||
gotACommand = read_controlvm_event(&inmsg);
|
||||
else {
|
||||
/* this is a scenario where throttling
|
||||
* is required, but probably NOT an
|
||||
* error...; we stash the current
|
||||
* controlvm msg so we will attempt to
|
||||
* reprocess it on our next loop
|
||||
*/
|
||||
handle_command_failed = TRUE;
|
||||
ControlVm_Pending_Msg = inmsg;
|
||||
ControlVm_Pending_Msg_Valid = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1998,7 +1957,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
|
|||
CONTROLVM_MESSAGE localCrashCreateBusMsg;
|
||||
CONTROLVM_MESSAGE localCrashCreateDevMsg;
|
||||
CONTROLVM_MESSAGE msg;
|
||||
HOSTADDRESS host_addr;
|
||||
U32 localSavedCrashMsgOffset;
|
||||
U16 localSavedCrashMsgCount;
|
||||
|
||||
|
@ -2021,26 +1979,6 @@ setup_crash_devices_work_queue(struct work_struct *work)
|
|||
|
||||
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 */
|
||||
if (visorchannel_read(ControlVm_channel,
|
||||
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
|
||||
|
@ -2331,9 +2269,6 @@ proc_read_installer(struct file *file, char __user *buf,
|
|||
char *vbuf;
|
||||
loff_t pos = *offset;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2383,9 +2318,6 @@ proc_write_installer(struct file *file,
|
|||
U16 remainingSteps;
|
||||
U32 error, textId;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check to make sure there is no buffer overflow */
|
||||
if (count > (sizeof(buf) - 1))
|
||||
return -EINVAL;
|
||||
|
@ -2447,9 +2379,6 @@ proc_read_toolaction(struct file *file, char __user *buf,
|
|||
char *vbuf;
|
||||
loff_t pos = *offset;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2488,9 +2417,6 @@ proc_write_toolaction(struct file *file,
|
|||
char buf[3];
|
||||
U8 toolAction;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check to make sure there is no buffer overflow */
|
||||
if (count > (sizeof(buf) - 1))
|
||||
return -EINVAL;
|
||||
|
@ -2530,9 +2456,6 @@ proc_read_bootToTool(struct file *file, char __user *buf,
|
|||
char *vbuf;
|
||||
loff_t pos = *offset;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -2571,9 +2494,6 @@ proc_write_bootToTool(struct file *file,
|
|||
int inputVal;
|
||||
ULTRA_EFI_SPAR_INDICATION efiSparIndication;
|
||||
|
||||
if (!ControlVm_channel)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check to make sure there is no buffer overflow */
|
||||
if (count > (sizeof(buf) - 1))
|
||||
return -EINVAL;
|
||||
|
@ -2612,9 +2532,11 @@ static int __init
|
|||
visorchipset_init(void)
|
||||
{
|
||||
int rc = 0, x = 0;
|
||||
char s[64];
|
||||
struct proc_dir_entry *installer_file;
|
||||
struct proc_dir_entry *toolaction_file;
|
||||
struct proc_dir_entry *bootToTool_file;
|
||||
HOSTADDRESS addr;
|
||||
|
||||
if (!unisys_spar_platform)
|
||||
return -ENODEV;
|
||||
|
@ -2646,6 +2568,30 @@ visorchipset_init(void)
|
|||
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);
|
||||
rc = visorchipset_file_init(MajorDev, &ControlVm_channel);
|
||||
if (rc < 0) {
|
||||
|
@ -2795,12 +2741,10 @@ visorchipset_exit(void)
|
|||
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
|
||||
|
||||
proc_DeInit();
|
||||
if (ControlVm_channel != NULL) {
|
||||
LOGINF("Channel %s (ControlVm) disconnected",
|
||||
visorchannel_id(ControlVm_channel, s));
|
||||
visorchannel_destroy(ControlVm_channel);
|
||||
ControlVm_channel = NULL;
|
||||
}
|
||||
LOGINF("Channel %s (ControlVm) disconnected",
|
||||
visorchannel_id(ControlVm_channel, s));
|
||||
visorchannel_destroy(ControlVm_channel);
|
||||
|
||||
visorchipset_file_cleanup();
|
||||
POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
|
||||
LOGINF("chipset driver unloaded");
|
||||
|
|
Loading…
Reference in New Issue