There are two methods for signaling the host: the monitor page mechanism and hypercalls. The monitor page mechanism is used by performance critical channels (storage, networking, etc.) because it provides improved throughput. However, latency is increased. Monitor pages are allocated to these channels. Monitor pages are not allocated to channels that do not use the monitor page mechanism. Therefore, these channels do not have a valid monitor id or valid monitor page data. In these cases, some of the "_show" functions return incorrect data. They return an invalid monitor id and data that is beyond the bounds of the hv_monitor_page array fields. The "channel->offermsg.monitor_allocated" value can be used to determine whether monitor pages have been allocated to a channel. In the affected "_show" functions, verify that "channel->offermsg.monitor_allocated" is set before accessing the monitor id or the monitor page data. If "channel->offermsg.monitor_allocated" is not set, return -EINVAL. Signed-off-by: Kimberly Brown <kimbrownkd@xxxxxxxxx> --- Documentation/ABI/stable/sysfs-bus-vmbus | 15 ++++++++-- drivers/hv/vmbus_drv.c | 37 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus index 3fed8fdb873d..9e8a7a29b3ff 100644 --- a/Documentation/ABI/stable/sysfs-bus-vmbus +++ b/Documentation/ABI/stable/sysfs-bus-vmbus @@ -81,7 +81,10 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/latency Date: September. 2017 KernelVersion: 4.14 Contact: Stephen Hemminger <sthemmin@xxxxxxxxxxxxx> -Description: Channel signaling latency +Description: Channel signaling latency. The monitor page mechanism is used + for performance critical channels (storage, network, etc.). + Channels that do not use the monitor page mechanism will return + EINVAL. Users: Debugging tools What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_mask @@ -95,7 +98,10 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/pending Date: September. 2017 KernelVersion: 4.14 Contact: Stephen Hemminger <sthemmin@xxxxxxxxxxxxx> -Description: Channel interrupt pending state +Description: Channel interrupt pending state. The monitor page mechanism is + used for performance critical channels (storage, network, + etc.). Channels that do not use the monitor page mechanism will + return EINVAL. Users: Debugging tools What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/read_avail @@ -137,7 +143,10 @@ What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/monitor_id Date: January. 2018 KernelVersion: 4.16 Contact: Stephen Hemminger <sthemmin@xxxxxxxxxxxxx> -Description: Monitor bit associated with channel +Description: Monitor bit associated with channel. The monitor page mechanism + is used for performance critical channels (storage, network, + etc.). Channels that do not use the monitor page mechanism will + return EINVAL. Users: Debugging tools and userspace drivers What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/ring diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index f2a79f5129d7..0ff9a09a3f71 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -171,6 +171,10 @@ static ssize_t monitor_id_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", hv_dev->channel->offermsg.monitorid); } static DEVICE_ATTR_RO(monitor_id); @@ -232,6 +236,10 @@ static ssize_t server_monitor_pending_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_pending(hv_dev->channel, vmbus_connection.monitor_pages[0])); @@ -246,6 +254,10 @@ static ssize_t client_monitor_pending_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_pending(hv_dev->channel, vmbus_connection.monitor_pages[1])); @@ -260,6 +272,10 @@ static ssize_t server_monitor_latency_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_latency(hv_dev->channel, vmbus_connection.monitor_pages[0])); @@ -274,6 +290,10 @@ static ssize_t client_monitor_latency_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_latency(hv_dev->channel, vmbus_connection.monitor_pages[1])); @@ -288,6 +308,10 @@ static ssize_t server_monitor_conn_id_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_conn_id(hv_dev->channel, vmbus_connection.monitor_pages[0])); @@ -302,6 +326,10 @@ static ssize_t client_monitor_conn_id_show(struct device *dev, if (!hv_dev->channel) return -ENODEV; + + if (!hv_dev->channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_conn_id(hv_dev->channel, vmbus_connection.monitor_pages[1])); @@ -1469,6 +1497,9 @@ static VMBUS_CHAN_ATTR(cpu, S_IRUGO, show_target_cpu, NULL); static ssize_t channel_pending_show(const struct vmbus_channel *channel, char *buf) { + if (!channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_pending(channel, vmbus_connection.monitor_pages[1])); @@ -1478,6 +1509,9 @@ static VMBUS_CHAN_ATTR(pending, S_IRUGO, channel_pending_show, NULL); static ssize_t channel_latency_show(const struct vmbus_channel *channel, char *buf) { + if (!channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%d\n", channel_latency(channel, vmbus_connection.monitor_pages[1])); @@ -1499,6 +1533,9 @@ static VMBUS_CHAN_ATTR(events, S_IRUGO, channel_events_show, NULL); static ssize_t subchannel_monitor_id_show(const struct vmbus_channel *channel, char *buf) { + if (!channel->offermsg.monitor_allocated) + return -EINVAL; + return sprintf(buf, "%u\n", channel->offermsg.monitorid); } static VMBUS_CHAN_ATTR(monitor_id, S_IRUGO, subchannel_monitor_id_show, NULL); -- 2.17.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel