summaryrefslogtreecommitdiff
path: root/drivers/ptp/ptp_chardev.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2020-08-25 13:01:46 +0300
committerMark Brown <broonie@kernel.org>2020-08-25 13:01:46 +0300
commit3bec5b6aae830355e786e204b20a7cea38c3a8ed (patch)
treefd597b87faf55ceb2a207ee94f4feca6276696db /drivers/ptp/ptp_chardev.c
parenta577f3456c0a2fac3dee037c483753e6e68f3e49 (diff)
parentd012a7190fc1fd72ed48911e77ca97ba4521bccd (diff)
downloadlinux-3bec5b6aae830355e786e204b20a7cea38c3a8ed.tar.xz
Merge tag 'v5.9-rc2' into regulator-5.9
Linux 5.9-rc2
Diffstat (limited to 'drivers/ptp/ptp_chardev.c')
-rw-r--r--drivers/ptp/ptp_chardev.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 375cd6e4aade..af3bc65c4595 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -191,12 +191,46 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
- if (((req.perout.flags & ~PTP_PEROUT_VALID_FLAGS) ||
- req.perout.rsv[0] || req.perout.rsv[1] ||
- req.perout.rsv[2] || req.perout.rsv[3]) &&
- cmd == PTP_PEROUT_REQUEST2) {
- err = -EINVAL;
- break;
+ if (cmd == PTP_PEROUT_REQUEST2) {
+ struct ptp_perout_request *perout = &req.perout;
+
+ if (perout->flags & ~PTP_PEROUT_VALID_FLAGS) {
+ err = -EINVAL;
+ break;
+ }
+ /*
+ * The "on" field has undefined meaning if
+ * PTP_PEROUT_DUTY_CYCLE isn't set, we must still treat
+ * it as reserved, which must be set to zero.
+ */
+ if (!(perout->flags & PTP_PEROUT_DUTY_CYCLE) &&
+ (perout->rsv[0] || perout->rsv[1] ||
+ perout->rsv[2] || perout->rsv[3])) {
+ err = -EINVAL;
+ break;
+ }
+ if (perout->flags & PTP_PEROUT_DUTY_CYCLE) {
+ /* The duty cycle must be subunitary. */
+ if (perout->on.sec > perout->period.sec ||
+ (perout->on.sec == perout->period.sec &&
+ perout->on.nsec > perout->period.nsec)) {
+ err = -ERANGE;
+ break;
+ }
+ }
+ if (perout->flags & PTP_PEROUT_PHASE) {
+ /*
+ * The phase should be specified modulo the
+ * period, therefore anything equal or larger
+ * than 1 period is invalid.
+ */
+ if (perout->phase.sec > perout->period.sec ||
+ (perout->phase.sec == perout->period.sec &&
+ perout->phase.nsec >= perout->period.nsec)) {
+ err = -ERANGE;
+ break;
+ }
+ }
} else if (cmd == PTP_PEROUT_REQUEST) {
req.perout.flags &= PTP_PEROUT_V1_VALID_FLAGS;
req.perout.rsv[0] = 0;