aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ptp
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2012-11-25 20:44:35 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-26 17:22:14 -0500
commitc3484c275db5abe88e01a7e1a80932112c9bbf69 (patch)
tree0113d9e291e5fcf3d3ba7bd70d7c8ccf9b885e30 /drivers/ptp
parentc7ec0badcc54508d3ab052bb425cc677521a89be (diff)
ptp: reduce stack usage when measuring the system time offset
This patch removes the large buffer from the stack of the system offset ioctl and replaces it with a kmalloced buffer. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp')
-rw-r--r--drivers/ptp/ptp_chardev.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 9d7542efb175..34a0c607318e 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -34,7 +34,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
34{ 34{
35 struct ptp_clock_caps caps; 35 struct ptp_clock_caps caps;
36 struct ptp_clock_request req; 36 struct ptp_clock_request req;
37 struct ptp_sys_offset sysoff; 37 struct ptp_sys_offset *sysoff = NULL;
38 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); 38 struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
39 struct ptp_clock_info *ops = ptp->info; 39 struct ptp_clock_info *ops = ptp->info;
40 struct ptp_clock_time *pct; 40 struct ptp_clock_time *pct;
@@ -94,17 +94,22 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
94 break; 94 break;
95 95
96 case PTP_SYS_OFFSET: 96 case PTP_SYS_OFFSET:
97 if (copy_from_user(&sysoff, (void __user *)arg, 97 sysoff = kmalloc(sizeof(*sysoff), GFP_KERNEL);
98 sizeof(sysoff))) { 98 if (!sysoff) {
99 err = -ENOMEM;
100 break;
101 }
102 if (copy_from_user(sysoff, (void __user *)arg,
103 sizeof(*sysoff))) {
99 err = -EFAULT; 104 err = -EFAULT;
100 break; 105 break;
101 } 106 }
102 if (sysoff.n_samples > PTP_MAX_SAMPLES) { 107 if (sysoff->n_samples > PTP_MAX_SAMPLES) {
103 err = -EINVAL; 108 err = -EINVAL;
104 break; 109 break;
105 } 110 }
106 pct = &sysoff.ts[0]; 111 pct = &sysoff->ts[0];
107 for (i = 0; i < sysoff.n_samples; i++) { 112 for (i = 0; i < sysoff->n_samples; i++) {
108 getnstimeofday(&ts); 113 getnstimeofday(&ts);
109 pct->sec = ts.tv_sec; 114 pct->sec = ts.tv_sec;
110 pct->nsec = ts.tv_nsec; 115 pct->nsec = ts.tv_nsec;
@@ -117,7 +122,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
117 getnstimeofday(&ts); 122 getnstimeofday(&ts);
118 pct->sec = ts.tv_sec; 123 pct->sec = ts.tv_sec;
119 pct->nsec = ts.tv_nsec; 124 pct->nsec = ts.tv_nsec;
120 if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff))) 125 if (copy_to_user((void __user *)arg, sysoff, sizeof(*sysoff)))
121 err = -EFAULT; 126 err = -EFAULT;
122 break; 127 break;
123 128
@@ -125,6 +130,8 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
125 err = -ENOTTY; 130 err = -ENOTTY;
126 break; 131 break;
127 } 132 }
133
134 kfree(sysoff);
128 return err; 135 return err;
129} 136}
130 137