Skip to contentSkip to conversation

add SMBIOS information to /proc/smbios -- UPDATED

PATCH In review Michael Brown 3 participants 4 messages Apr 30, 2004 – May 3, 2004 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 add SMBIOS information to /proc/smbios -- UPDATED

Marcelo, Al,
Below is an updated patch to add SMBIOS information to /proc/smbios.
Updates have been made per Al's previous comments. Please apply.

For reference, here are previous postings:
Previous 2.4 thread:
http://marc.theaimsgroup.com/?t=108321757100001&r=1&w=1

Previous 2.6 thread:
http://marc.theaimsgroup.com/?t=108311959700002&r=1&w=1

Thank you,
Michael Brown

# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet

#   2004/04/29 21:11:19-05:00 [email protected] 
#   Updates per Al Viro: 
#   	-- remove MOD_{INC,DEC}_USE_COUNT
#   	-- use normal read call instead of proc read call
# 
# drivers/char/smbios.c
#   2004/04/29 21:11:17-05:00 [email protected] +35 -47
#   Updates per comments from Al Viro.
# 
# ChangeSet
#   2004/04/29 00:16:35-05:00 [email protected] 
#   rename smbios to proper smbios.c
# 
# drivers/char/Makefile
#   2004/04/29 00:09:15-05:00 [email protected] +1 -1
#   rename smbios driver to 'smbios'.
# 
# drivers/char/smbios.c
#   2004/04/29 00:08:51-05:00 [email protected] +0 -0
#   Rename: drivers/char/procsmbios.c -> drivers/char/smbios.c
# 
# ChangeSet
#   2004/04/28 23:51:19-05:00 [email protected] 
#   Add SMBIOS driver that exports system SMBIOS information as files in /proc/smbios.
# 
# drivers/char/smbios.h
#   2004/04/28 23:50:15-05:00 [email protected] +53 -0
# 
# drivers/char/procsmbios.c
#   2004/04/28 23:50:15-05:00 [email protected] +251 -0
# 
# drivers/char/smbios.h
#   2004/04/28 23:50:15-05:00 [email protected] +0 -0
#   BitKeeper file /home/michael_e_brown/kernel/bk/subtrees/smbios-24-driver/drivers/char/smbios.h
# 
# drivers/char/procsmbios.c
#   2004/04/28 23:50:15-05:00 [email protected] +0 -0
#   BitKeeper file /home/michael_e_brown/kernel/bk/subtrees/smbios-24-driver/drivers/char/procsmbios.c
# 
# drivers/char/Makefile
#   2004/04/28 23:50:15-05:00 [email protected] +1 -0
#   Add SMBIOS driver to build system
# 
# drivers/char/Config.in
#   2004/04/28 23:50:15-05:00 [email protected] +1 -0
#   Add config option to turn on SMBIOS proc driver
# 
# Documentation/Configure.help
#   2004/04/28 23:50:15-05:00 [email protected] +14 -0
#   Add help text for SMBIOS driver
# 
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Thu Apr 29 21:13:45 2004
+++ b/Documentation/Configure.help	Thu Apr 29 21:13:45 2004
@@ -19914,6 +19914,20 @@

If unsure, say N.

+SMBIOS table information in /proc
+CONFIG_SMBIOS

+  This driver creates two files in /proc, /proc/smbios/table_entry_point
+  and /proc/smbios/table. These two files contain the contents of the 
+  BIOS-generated SMBIOS tables. Generally, PC-like architectures made
+  after 1997 have this, it is safe to enable on any system.
+  
+  To compile this driver as a module ( = code which can be inserted in
+  and removed from the running kernel whenever you want), say M here
+  and read <file:Documentation/modules.txt>. The module will be called
+  smbios.o.

+
+ If unsure, say N.
+
Sony Vaio Programmable I/O Control Device support CONFIG_SONYPI
This driver enables access to the Sony Programmable I/O Control

drivers/char/Config.in +1 -0
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
@@ -333,6 +333,7 @@
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
    dep_tristate 'Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)' CONFIG_SONYPI $CONFIG_PCI
 fi
+tristate 'SMBIOS table information in /proc' CONFIG_SMBIOS
 
 mainmenu_option next_comment
 comment 'Ftape, the floppy tape device driver'
drivers/char/Makefile +1 -0
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
@@ -265,6 +265,7 @@
 obj-$(CONFIG_HW_RANDOM) += hw_random.o
 obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
 obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
+obj-$(CONFIG_SMBIOS) += smbios.o
 
 obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o
drivers/char/smbios.c new file +239 -0

239 lines not on this page · raw message

drivers/char/smbios.h new file +53 -0

53 lines not on this page · raw message

#1 lore raw

drivers/char/smbios.c line 78

Quoted 9 lines · Michael Brown
drivers/char/smbios.c new file +9 -0
+	u32 fp = 0xF0000;
+	while (fp < 0xFFFFF) {
+		isa_memcpy_fromio(table_eps, fp, sizeof(*table_eps));
+		if (memcmp(table_eps->anchor, "_SM_", 4)==0 &&
+					checksum_eps(table_eps)) {
+			return 0;
+		}
+		fp += 16;
+	}

Stilistic note:

	for (fp = 0xf0000; fp < 0xfffff; fp += 16) {
		isa_memcpy_fromio(table_eps, fp, sizeof(*table_eps));
		if (memcmp(table_eps->anchor, "_SM_", 4) != 0)
			continue;
		if (checksum_eps(table_eps))
			return 0;
	}

drivers/char/smbios.c line 107

Quoted 8 lines
drivers/char/smbios.c new file +8 -0
+	while(keep_going && ((ptr - buf) <= max_length) && count < max_count){
+		if (ptr[0] == 0x7F)   /* ptr[0] is type */
+			keep_going = 0;
+
+		ptr += ptr[1]; /* ptr[1] is length, skip structure */
+		/* skip strings at end of structure */
+		while((ptr-buf) < max_length && (ptr[0] || ptr[1]))
+			++ptr;

It looks like an off-by-one - if ptr reaches buf + max_length - 1, ptr[1] appears to be beyond the area it's OK to dereference.

drivers/char/smbios.c line 160

Quoted 8 lines
drivers/char/smbios.c new file +8 -0
+                size_t count, loff_t *ppos)
+{
+	unsigned long origppos = *ppos;
+	unsigned long max_off = the_smbios_device.smbios_table_real_length;
+	u8 *ptr;
+
+	if(*ppos >= max_off)
+		return 0;

Note that *ppos is signed here. llseek() to negative and you've got a problem.

drivers/char/smbios.c line 172

Quoted 4 lines
drivers/char/smbios.c new file +4 -0
+	while (*ppos < max_off) {
+		put_user(readb(ptr + *ppos), buf);
+		++(*ppos); ++buf;
+	}

Eeek...

a) that's called copy_to_user()
b) you'd better check the return value (either of put_user() or
copy_to_user()).

#2 lore raw

Good stuff! Thanks for the feedback Al. Give me a few minutes and I will send an updated patch.

Comments/Questions below.

Quoted 12 lines · On Thu, 2004-04-29 at 22:34, [email protected] wrote:

drivers/char/smbios.c line 78

Quoted 9 lines · Michael Brown
drivers/char/smbios.c new file +9 -0
+	u32 fp = 0xF0000;
+	while (fp < 0xFFFFF) {
+		isa_memcpy_fromio(table_eps, fp, sizeof(*table_eps));
+		if (memcmp(table_eps->anchor, "_SM_", 4)==0 &&
+					checksum_eps(table_eps)) {
+			return 0;
+		}
+		fp += 16;
+	}

Stilistic note:

Quoted 7 lines
	for (fp = 0xf0000; fp < 0xfffff; fp += 16) {
		isa_memcpy_fromio(table_eps, fp, sizeof(*table_eps));
		if (memcmp(table_eps->anchor, "_SM_", 4) != 0)
			continue;
		if (checksum_eps(table_eps))
			return 0;
	}

Will change. I like your version.

Originally copied from Alan Cox's stuff, so if Alan's style is off, oh well... :-)

Quoted 12 lines

drivers/char/smbios.c line 107

Quoted 9 lines
drivers/char/smbios.c new file +8 -0
+	while(keep_going && ((ptr - buf) <= max_length) && count < max_count){
+		if (ptr[0] == 0x7F)   /* ptr[0] is type */
+			keep_going = 0;
+
+		ptr += ptr[1]; /* ptr[1] is length, skip structure */
+		/* skip strings at end of structure */
+		while((ptr-buf) < max_length && (ptr[0] || ptr[1]))
+			++ptr;

It looks like an off-by-one - if ptr reaches buf + max_length - 1, ptr[1] appears to be beyond the area it's OK to dereference.

Great spot. Updating, changed "<= max_length" to "<= (max_length-1)".

Quoted 11 lines

drivers/char/smbios.c line 160

Quoted 9 lines
drivers/char/smbios.c new file +8 -0
+                size_t count, loff_t *ppos)
+{
+	unsigned long origppos = *ppos;
+	unsigned long max_off = the_smbios_device.smbios_table_real_length;
+	u8 *ptr;
+
+	if(*ppos >= max_off)
+		return 0;

Note that *ppos is signed here. llseek() to negative and you've got a problem.

Added "|| *ppos < 0" to the check.

Quoted 11 lines

drivers/char/smbios.c line 172

Quoted 5 lines
drivers/char/smbios.c new file +4 -0
+	while (*ppos < max_off) {
+		put_user(readb(ptr + *ppos), buf);
+		++(*ppos); ++buf;
+	}

Eeek...

a) that's called copy_to_user()
b) you'd better check the return value (either of put_user() or
copy_to_user()).

Ok, will update, but I have one question. for (A), is this equivalent to copy_to_user() even with the readb() in there? Sorry if this is a stupid question.

If I get a bad return from either of these, is "return -EINVAL" appropriate?
--
Michael