lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1284987540.2242.29.camel@morgan.silverblock.net>
Date:	Mon, 20 Sep 2010 08:59:00 -0400
From:	Andy Walls <awalls@...metrocast.net>
To:	linux-kernel@...r.kernel.org
Cc:	dri-devel@...ts.freedesktop.org, Dave Airlie <airlied@...hat.com>,
	Jon Smirl <jonsmirl@...il.com>,
	Greg Kroah-Hartman <greg@...ah.com>
Subject: [PATCH] drm/sysfs: Provide per connector control of DRM KMS polling

DRM KMS polling of connections providing errant EDID responses, or
polling of "connectors" that have chips responding on DDC I2C bus
address 0xA0/0xA1 with no actual physical connector nor EDID EEPROM,
will create perpetual noise in dmesg and the system log every 10
seconds.  Currently the user has apparently little recourse to silence
these messages aside from replacing the offending cable, monitor, or
graphics adapter.  That recourse is impossible for an unused DVI-D
"connector" of an internal graphics processor on a motherboard that
provides no physical DVI-D connector.

This change allows the root user to disable (and re-enable) DRM KMS
connector polling on a per connector basis via sysfs, like so:

        # cat /sys/class/drm/card0/card0-DVI-D-1/polled
        [hotplug_detectable] connect disconnect
        
        # echo > /sys/class/drm/card0/card0-DVI-D-1/polled
        # cat /sys/class/drm/card0/card0-DVI-D-1/polled
        hotplug_detectable connect disconnect
        
        # echo " connect  hotplug_detectable " > \
        	/sys/class/drm/card0/card0-DVI-D-1/polled
        # cat /sys/class/drm/card0/card0-DVI-D-1/polled
        [hotplug_detectable] [connect] disconnect
        
        # echo > /sys/class/drm/card0/card0-DVI-D-1/polled
        # cat /sys/class/drm/card0/card0-DVI-D-1/polled
        hotplug_detectable connect disconnect

with the enabled poll types for the connector denoted in brackets: [].
This allows the root user to silence DRM KMS log spam for locally known
uncorrectable conditions.

Signed-off-by Andy Walls <awalls@...metrocast.net>

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 86118a7..8e0807d 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -318,11 +318,80 @@ static ssize_t select_subconnector_show(struct device *device,
 			drm_get_dvi_i_select_name((int)subconnector));
 }
 
+static const struct {
+	uint8_t mask;
+	const char *name;
+} polled_bit_names[] = {
+	{ DRM_CONNECTOR_POLL_HPD,        "hotplug_detectable" },
+	{ DRM_CONNECTOR_POLL_CONNECT,    "connect"            },
+	{ DRM_CONNECTOR_POLL_DISCONNECT, "disconnect"         },
+};
+
+/*
+ * Return the decoded contents of connector->polled, using the names of the
+ * all the bit masks.  Bits that are set, have their names enclosed in brackets.
+ */
+static ssize_t polled_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct drm_connector *connector = to_drm_connector(dev);
+	char *tmp;
+	int i;
+
+	tmp = buf;
+	for (i = 0; i < ARRAY_SIZE(polled_bit_names); i++) {
+		if (connector->polled & polled_bit_names[i].mask)
+			tmp += sprintf(tmp, "[%s] ", polled_bit_names[i].name);
+		else
+			tmp += sprintf(tmp, "%s ", polled_bit_names[i].name);
+	}
+
+	if (tmp != buf)
+		*(tmp - 1) = '\n';
+	return tmp - buf;
+}
+
+/*
+ * Change the state of connector->polled, given input bit-mask name-strings
+ * that are separated by space or newline.
+ */
+static ssize_t polled_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct drm_connector *connector = to_drm_connector(dev);
+	const char *tmp;
+	int i;
+	uint8_t polled;
+
+	/* Polling of this connector will cease, if no match is made below */
+	polled = 0;
+
+	/* Incrementally split and parse the input */
+	while ((tmp = strsep((char **) &buf, " \n")) != NULL) {
+
+		/* Don't waste effort on multiple adjacent separators */
+		if (*tmp == '\0')
+			continue;
+
+		/* Check for a match with a connector poll type name */
+		for (i = 0; i < ARRAY_SIZE(polled_bit_names); i++) {
+			if (!strncasecmp(tmp, polled_bit_names[i].name,
+					 strlen(polled_bit_names[i].name))) {
+				polled |= polled_bit_names[i].mask;
+				break;
+			}
+		}
+	}
+	connector->polled = polled;
+	return count;
+}
+
 static struct device_attribute connector_attrs[] = {
 	__ATTR_RO(status),
 	__ATTR_RO(enabled),
 	__ATTR_RO(dpms),
 	__ATTR_RO(modes),
+	__ATTR(polled, 0644, polled_show, polled_store),
 };
 
 /* These attributes are for both DVI-I connectors and all types of tv-out. */


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ