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: <20060725174100.GA4608@hmsreliant.homelinux.net>
Date:	Tue, 25 Jul 2006 13:41:00 -0400
From:	Neil Horman <nhorman@...driver.com>
To:	linux-kernel@...r.kernel.org
Cc:	a.zummo@...ertech.it, jg@...edesktop.org, nhorman@...driver.com
Subject: [PATCH] RTC: Add mmap method to rtc character driver

Hey-
	At OLS last week, During Dave Jones Userspace Sucks presentation, Jim
Geddys and some of the Xorg guys noted that they would be able to stop using gettimeofday
so frequently, if they had some other way to get a millisecond resolution timer
in userspace, one that they could perhaps read from a memory mapped page.  I was
right behind them and though that seemed like a reasonable request,  so I've
taken a stab at it.  This patch allows for a page to be mmaped from /dev/rtc
character interface, the first 4 bytes of which provide a regularly increasing
count, once every rtc interrupt.  The frequency is of course controlled by the
regular ioctls provided by the rtc driver. I've done some basic testing on it,
and it seems to work well.

Thanks And Regards
Neil

Signed-off-by: Neil Horman


 
 rtc.c |   41 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 40 insertions(+), 1 deletion(-)


diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 6e6a7c7..4ed673e 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -48,9 +48,10 @@
  *		CONFIG_HPET_EMULATE_RTC
  *	1.12a	Maciej W. Rozycki: Handle memory-mapped chips properly.
  *	1.12ac	Alan Cox: Allow read access to the day of week register
+ *	1.12b   Neil Horman: Allow memory mapping of /dev/rtc	
  */
 
-#define RTC_VERSION		"1.12ac"
+#define RTC_VERSION		"1.12b"
 
 /*
  *	Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
@@ -183,6 +184,8 @@ static int rtc_proc_open(struct inode *i
  */
 static unsigned long rtc_status = 0;	/* bitmapped status byte.	*/
 static unsigned long rtc_freq = 0;	/* Current periodic IRQ rate	*/
+#define BUF_SIZE (PAGE_SIZE/sizeof(unsigned long))
+static unsigned long rtc_irq_buf[BUF_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
 static unsigned long rtc_irq_data = 0;	/* our output to the world	*/
 static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */
 
@@ -230,6 +233,7 @@ static inline unsigned char rtc_is_updat
 
 irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	unsigned long *count_ptr = (unsigned long *)rtc_irq_buf;
 	/*
 	 *	Can be an alarm interrupt, update complete interrupt,
 	 *	or a periodic interrupt. We store the status in the
@@ -265,6 +269,7 @@ irqreturn_t rtc_interrupt(int irq, void 
 
 	kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
 
+	*count_ptr = (*count_ptr)++;
 	return IRQ_HANDLED;
 }
 #endif
@@ -389,6 +394,37 @@ static ssize_t rtc_read(struct file *fil
 #endif
 }
 
+static int rtc_mmap(struct file *file, struct vm_area_struct *vma)
+{
+        unsigned long rtc_addr;
+	unsigned long *count_ptr = rtc_irq_buf;
+
+        if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+                return -EINVAL;
+
+        if (vma->vm_flags & VM_WRITE)
+                return -EPERM;
+
+        if (PAGE_SIZE > (1 << 16))
+                return -ENOSYS;
+
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+        rtc_addr = __pa(rtc_irq_buf);
+        rtc_addr &= ~(PAGE_SIZE - 1);
+        rtc_addr &= -1;
+
+        if (remap_pfn_range(vma, vma->vm_start, rtc_addr >> PAGE_SHIFT,
+                                        PAGE_SIZE, vma->vm_page_prot)) {
+                printk(KERN_ERR "remap_pfn_range failed in rtc.c\n");
+                return -EAGAIN;
+        }
+
+	*count_ptr = 0;
+        return 0;
+
+}
+
 static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
 {
 	struct rtc_time wtime; 
@@ -890,6 +926,7 @@ static const struct file_operations rtc_
 	.owner		= THIS_MODULE,
 	.llseek		= no_llseek,
 	.read		= rtc_read,
+	.mmap		= rtc_mmap,
 #ifdef RTC_IRQ
 	.poll		= rtc_poll,
 #endif
@@ -1082,6 +1119,8 @@ no_irq:
 no_irq2:
 #endif
 
+	memset(rtc_irq_buf,0,PAGE_SIZE);
+
 	(void) init_sysctl();
 
 	printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
-- 
/***************************************************
 *Neil Horman
 *Software Engineer
 *gpg keyid: 1024D / 0x92A74FA1 - http://pgp.mit.edu
 ***************************************************/
-
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