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: <20080113203223.GA6723@cvg>
Date:	Sun, 13 Jan 2008 23:32:23 +0300
From:	Cyrill Gorcunov <gorcunov@...il.com>
To:	Paul Gortmaker <p_gortmaker@...oo.com>
Cc:	LKML <linux-kernel@...r.kernel.org>, Andi Kleen <ak@...e.de>
Subject: [PATCH] driver: ip27-rtc - convert ioctl to unlocked_ioctl

This patch converts ioctl call to unlocked_ioctl form with
explicit big-kernel-lock. Also it makes a bit of cleanup
converting miscdevice structure initialization to C99 form.

Signed-off-by: Cyrill Gorcunov <gorcunov@...il.com>
---

Any comments are welcome.
This is untested code - i've no such chip on my laptop.

Andi, i think we could use mutex to eliminate BKL, but not sure.


 drivers/char/ip27-rtc.c |   86 ++++++++++++++++++++++++++++-------------------
 1 files changed, 51 insertions(+), 35 deletions(-)

diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index 932264a..1d83e16 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -46,8 +46,8 @@
 #include <asm/sn/sn0/hub.h>
 #include <asm/sn/sn_private.h>
 
-static int rtc_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg);
+static long rtc_ioctl(struct file *file, unsigned int cmd,
+		      unsigned long arg);
 
 static int rtc_read_proc(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
@@ -62,7 +62,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm);
 #define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
 
 static unsigned char rtc_status;	/* bitmapped status byte.	*/
-static unsigned long rtc_freq;	/* Current periodic IRQ rate	*/
+static unsigned long rtc_freq;		/* Current periodic IRQ rate	*/
 static struct m48t35_rtc *rtc;
 
 /*
@@ -75,30 +75,34 @@ static unsigned long epoch = 1970;	/* year corresponding to 0x00	*/
 static const unsigned char days_in_mo[] =
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		     unsigned long arg)
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-
 	struct rtc_time wtime;
+	int err;
+
+	lock_kernel();
 
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
-	{
 		get_rtc_time(&wtime);
+		err = copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
 		break;
-	}
 	case RTC_SET_TIME:	/* Set the RTC */
 	{
 		struct rtc_time rtc_tm;
 		unsigned char mon, day, hrs, min, sec, leap_yr;
 		unsigned int yrs;
 
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
+		if (!capable(CAP_SYS_TIME)) {
+			err = -EACCES;
+			goto unlock;
+		}
 
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
-				   sizeof(struct rtc_time)))
-			return -EFAULT;
+				   sizeof(struct rtc_time))) {
+			err = -EFAULT;
+			goto unlock;
+		}
 
 		yrs = rtc_tm.tm_year + 1900;
 		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
@@ -107,25 +111,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		min = rtc_tm.tm_min;
 		sec = rtc_tm.tm_sec;
 
+		err = -EINVAL;
+
 		if (yrs < 1970)
-			return -EINVAL;
+			goto unlock;
 
 		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
 
 		if ((mon > 12) || (day == 0))
-			return -EINVAL;
+			goto unlock;
 
 		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-			return -EINVAL;
+			goto unlock;
 
 		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-			return -EINVAL;
+			goto unlock;
 
 		if ((yrs -= epoch) > 255)    /* They are unsigned */
-			return -EINVAL;
+			goto unlock;
 
 		if (yrs > 169)
-			return -EINVAL;
+			goto unlock;
 
 		if (yrs >= 100)
 			yrs -= 100;
@@ -148,12 +154,18 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		rtc->control &= ~M48T35_RTC_SET;
 		spin_unlock_irq(&rtc_lock);
 
-		return 0;
+		err = 0;
+		break;
 	}
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		break;
 	}
-	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+
+ unlock:
+	unlock_kernel();
+
+	return err;
 }
 
 /*
@@ -170,8 +182,8 @@ static int rtc_open(struct inode *inode, struct file *file)
 		spin_unlock_irq(&rtc_lock);
 		return -EBUSY;
 	}
-
 	rtc_status |= RTC_IS_OPEN;
+
 	spin_unlock_irq(&rtc_lock);
 
 	return 0;
@@ -197,16 +209,15 @@ static int rtc_release(struct inode *inode, struct file *file)
 
 static const struct file_operations rtc_fops = {
 	.owner		= THIS_MODULE,
-	.ioctl		= rtc_ioctl,
+	.unlocked_ioctl	= rtc_ioctl,
 	.open		= rtc_open,
 	.release	= rtc_release,
 };
 
-static struct miscdevice rtc_dev=
-{
-	RTC_MINOR,
-	"rtc",
-	&rtc_fops
+static struct miscdevice rtc_dev = {
+	.minor		= RTC_MINOR,
+	.name		= "rtc",
+	.fops		= &rtc_fops,
 };
 
 static int __init rtc_init(void)
@@ -229,16 +240,15 @@ static int __init rtc_init(void)
 
 	return 0;
 }
+module_init(rtc_init);
 
-static void __exit rtc_exit (void)
+static void __exit rtc_exit(void)
 {
 	/* interrupts and timer disabled at this point by rtc_release */
 
 	remove_proc_entry ("rtc", NULL);
 	misc_deregister(&rtc_dev);
 }
-
-module_init(rtc_init);
 module_exit(rtc_exit);
 
 /*
@@ -274,14 +284,20 @@ static int rtc_get_status(char *buf)
 }
 
 static int rtc_read_proc(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+			 int count, int *eof, void *data)
 {
         int len = rtc_get_status(page);
-        if (len <= off+count) *eof = 1;
+
+        if (len <= off + count)
+		*eof = 1;
+
         *start = page + off;
         len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
+        if (len > count)
+		len = count;
+        if (len < 0)
+		len = 0;
+
         return len;
 }
 
--
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