staging: unisys: Use size of channel defined in the channel.

The size of the channel should be pulled from the channel header, not
from the message. All channels must be at least the size of the
channel_header.

Signed-off-by: David Kershner <david.kershner@unisys.com>
Reviewed-by: Tim Sell <timothy.sell@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
David Kershner 2017-08-30 13:36:31 -04:00 committed by Greg Kroah-Hartman
parent ebef2610b7
commit d7f1589a1d
3 changed files with 22 additions and 50 deletions

View File

@ -38,12 +38,10 @@ int visorbus_init(void);
void visorbus_exit(void);
/* visorchannel access functions */
struct visorchannel *visorchannel_create(u64 physaddr,
unsigned long channel_bytes,
gfp_t gfp, const guid_t *guid);
struct visorchannel *visorchannel_create_with_lock(u64 physaddr,
unsigned long channel_bytes,
gfp_t gfp, const guid_t *guid);
struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
const guid_t *guid);
struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp,
const guid_t *guid);
void visorchannel_destroy(struct visorchannel *channel);
int visorchannel_read(struct visorchannel *channel, ulong offset,
void *dest, ulong nbytes);

View File

@ -363,17 +363,8 @@ static int signalinsert_inner(struct visorchannel *channel, u32 queue,
* for a data area in memory, but does NOT modify
* this data area
* @physaddr: physical address of start of channel
* @channel_bytes: size of the channel in bytes; this may 0 if the channel has
* already been initialized in memory (which is true for all
* channels provided to guest environments by the s-Par
* back-end), in which case the actual channel size will be
* read from the channel header in memory
* @gfp: gfp_t to use when allocating memory for the data struct
* @guid: GUID that identifies channel type; this may 0 if the channel
* has already been initialized in memory (which is true for all
* channels provided to guest environments by the s-Par
* back-end), in which case the actual channel guid will be
* read from the channel header in memory
* @guid: GUID that identifies channel type;
* @needs_lock: must specify true if you have multiple threads of execution
* that will be calling visorchannel methods of this
* visorchannel at the same time
@ -381,11 +372,9 @@ static int signalinsert_inner(struct visorchannel *channel, u32 queue,
* Return: pointer to visorchannel that was created if successful,
* otherwise NULL
*/
static struct visorchannel *visorchannel_create_guts(
u64 physaddr,
unsigned long channel_bytes,
gfp_t gfp, const guid_t *guid,
bool needs_lock)
static struct visorchannel *visorchannel_create_guts(u64 physaddr, gfp_t gfp,
const guid_t *guid,
bool needs_lock)
{
struct visorchannel *channel;
int err;
@ -423,35 +412,28 @@ static struct visorchannel *visorchannel_create_guts(
channel->physaddr = physaddr;
channel->nbytes = size;
err = visorchannel_read(channel, 0, &channel->chan_hdr,
sizeof(struct channel_header));
err = visorchannel_read(channel, 0, &channel->chan_hdr, size);
if (err)
goto err_destroy_channel;
/* we had better be a CLIENT of this channel */
if (channel_bytes == 0)
channel_bytes = (ulong)channel->chan_hdr.size;
if (guid_is_null(guid))
guid = &channel->chan_hdr.chtype;
size = (ulong)channel->chan_hdr.size;
memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
channel->mapped = NULL;
channel->requested = request_mem_region(channel->physaddr,
channel_bytes, VISOR_DRV_NAME);
channel->requested = request_mem_region(channel->physaddr, size,
VISOR_DRV_NAME);
if (!channel->requested && !guid_equal(guid, &visor_video_guid))
/* we only care about errors if this is not the video channel */
goto err_destroy_channel;
channel->mapped = memremap(channel->physaddr, channel_bytes,
MEMREMAP_WB);
channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB);
if (!channel->mapped) {
release_mem_region(channel->physaddr, channel_bytes);
release_mem_region(channel->physaddr, size);
goto err_destroy_channel;
}
channel->nbytes = channel_bytes;
channel->nbytes = size;
guid_copy(&channel->guid, guid);
return channel;
@ -460,20 +442,16 @@ err_destroy_channel:
return NULL;
}
struct visorchannel *visorchannel_create(u64 physaddr,
unsigned long channel_bytes,
gfp_t gfp, const guid_t *guid)
struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp,
const guid_t *guid)
{
return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
false);
return visorchannel_create_guts(physaddr, gfp, guid, false);
}
struct visorchannel *visorchannel_create_with_lock(u64 physaddr,
unsigned long channel_bytes,
gfp_t gfp, const guid_t *guid)
struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp,
const guid_t *guid)
{
return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid,
true);
return visorchannel_create_guts(physaddr, gfp, guid, true);
}
/**

View File

@ -567,7 +567,6 @@ static int visorbus_create(struct controlvm_message *inmsg)
}
visorchannel = visorchannel_create(cmd->create_bus.channel_addr,
cmd->create_bus.channel_bytes,
GFP_KERNEL,
&cmd->create_bus.bus_data_type_guid);
if (!visorchannel) {
@ -789,7 +788,6 @@ static int visorbus_device_create(struct controlvm_message *inmsg)
visorchannel =
visorchannel_create_with_lock(cmd->create_device.channel_addr,
cmd->create_device.channel_bytes,
GFP_KERNEL,
&cmd->create_device.data_type_guid);
if (!visorchannel) {
@ -1326,7 +1324,6 @@ static int controlvm_channel_create(struct visorchipset_device *dev)
{
struct visorchannel *chan;
u64 addr;
u32 size;
int err;
err = unisys_vmcall(VMCALL_CONTROLVM_ADDR,
@ -1334,8 +1331,7 @@ static int controlvm_channel_create(struct visorchipset_device *dev)
if (err)
return err;
addr = dev->controlvm_params.address;
size = dev->controlvm_params.channel_bytes;
chan = visorchannel_create_with_lock(addr, size, GFP_KERNEL,
chan = visorchannel_create_with_lock(addr, GFP_KERNEL,
&visor_controlvm_channel_guid);
if (!chan)
return -ENOMEM;