Re: [PATCH 0/5] RFC: Offer a way for userspace to request real deletion of files
Alexander Holler ahsoftware.de> writes: > > Hello. > > I've set up a repository at github which contains the 3 pathches to add > limited support to the Linux kernel for wiping files on ext4 and (v)fat > with 3 small patches and a total of "9 files changed, 101 insertions(+), > 8 deletions(-)" here: > > https://github.com/aholler/wipe_lnx > > Feel free to send me any comments, patches or even flames in privat > (off-list)! because I don't want to become involved in annoying > discussions here anymore. > > Alexander Holler > This is certainly a case of "The Emperor's New Clothes". Lets say I use vim to edit my file containing my deep dark secrets. Lets strace it and see what happens when I edit it and save a new copy: rename("secure_document.txt", "secure_document.txt~") = 0 open("secure_document.txt", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 3 write(3, "secrete:s\n", 10) = 10 fsync(3)= 0 close(3)= 0 chmod("secure_document.txt", 0100664) = 0 setxattr("secure_document.txt", "system.posix_acl_access", "\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x06\x00\xff\xff\xff\x ff \x00\x04\x00\xff\xff\xff\xff", 28, 0) = 0 unlink("secure_document.txt~") = 0 You'll find that just about every program that deals with files properly does something like this. If it didn't, there'd be a good chance of losing all your work if the computer or program crashed while saving your file. This is layer one of the problem. Layer 2 is filesystems, as others have noted, filesystems have all sorts of paths for blocks no longer being associated with inodes. Log structured file systems doubly so. And layer 3, media, which we have no control over and may be storing duplicate copies of the data for any number of reasons. But as you've pointed out, is likely to require significant funds to get at. As pointed out, the best you could do is some sort of flag on the inode that instructed the filesystem to wipe blocks before separating them from the inode. Programs would need to be modified though as you can see in the vim case, any copying of file mode bits are only done after data has been written to disk. Luckily there is an easy solution out there that solves all these problems. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/5] RFC: Offer a way for userspace to request real deletion of files
Alexander Holler holler at ahsoftware.de writes: Hello. I've set up a repository at github which contains the 3 pathches to add limited support to the Linux kernel for wiping files on ext4 and (v)fat with 3 small patches and a total of 9 files changed, 101 insertions(+), 8 deletions(-) here: https://github.com/aholler/wipe_lnx Feel free to send me any comments, patches or even flames in privat (off-list)! because I don't want to become involved in annoying discussions here anymore. Alexander Holler This is certainly a case of The Emperor's New Clothes. Lets say I use vim to edit my file containing my deep dark secrets. Lets strace it and see what happens when I edit it and save a new copy: rename(secure_document.txt, secure_document.txt~) = 0 open(secure_document.txt, O_WRONLY|O_CREAT|O_TRUNC, 0664) = 3 write(3, secrete:s\n, 10) = 10 fsync(3)= 0 close(3)= 0 chmod(secure_document.txt, 0100664) = 0 setxattr(secure_document.txt, system.posix_acl_access, \x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x06\x00\xff\xff\xff\x ff \x00\x04\x00\xff\xff\xff\xff, 28, 0) = 0 unlink(secure_document.txt~) = 0 You'll find that just about every program that deals with files properly does something like this. If it didn't, there'd be a good chance of losing all your work if the computer or program crashed while saving your file. This is layer one of the problem. Layer 2 is filesystems, as others have noted, filesystems have all sorts of paths for blocks no longer being associated with inodes. Log structured file systems doubly so. And layer 3, media, which we have no control over and may be storing duplicate copies of the data for any number of reasons. But as you've pointed out, is likely to require significant funds to get at. As pointed out, the best you could do is some sort of flag on the inode that instructed the filesystem to wipe blocks before separating them from the inode. Programs would need to be modified though as you can see in the vim case, any copying of file mode bits are only done after data has been written to disk. Luckily there is an easy solution out there that solves all these problems. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] usb: serial: Perform verification for FTDI FT232R devices
v2: Perform check using product ID instead of vendor ID and update half word before checksum rather than checksum itself. This patch provides the FTDI genuine product verification steps as contained within the new 2.12.00 official release. It ensures that counterfeiters don't exploit engineering investment made by FTDI. Counterfeit ICs are destroying innovation in the industry. FTDI recommends that to guarantee genuine FTDI products please purchase either from FTDI directly or an authorised distributor. This is definitely not targeting end users - if you're unsure if ICs are genuine then please don't use the drivers. Signed-off-by: Russ Dill --- drivers/usb/serial/ftdi_sio.c | 113 +- drivers/usb/serial/ftdi_sio.h | 41 +++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dc72b924c399..c7041fd9e213 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1377,6 +1377,48 @@ static int read_latency_timer(struct usb_serial_port *port) return rv; } +static int write_eeprom(struct usb_serial_port *port, u8 addr, u16 data) +{ + struct usb_device *udev = port->serial->dev; + int rv; + + rv = usb_control_msg(udev, +usb_sndctrlpipe(udev, 0), +FTDI_SIO_WRITE_EEPROM_REQUEST, +FTDI_SIO_WRITE_EEPROM_REQUEST_TYPE, +data, addr, +NULL, 0, WDR_TIMEOUT); + if (rv < 0) + dev_err(>dev, "Unable to write EEPROM: %i\n", rv); + return rv; +} + +static int read_eeprom(struct usb_serial_port *port, u8 addr, u16 *data) +{ + struct usb_device *udev = port->serial->dev; + u16 *buf; + int rv; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + rv = usb_control_msg(udev, +usb_rcvctrlpipe(udev, 0), +FTDI_SIO_READ_EEPROM_REQUEST, +FTDI_SIO_READ_EEPROM_REQUEST_TYPE, +0, addr, +buf, 2, WDR_TIMEOUT); + if (rv < 0) + dev_err(>dev, "Unable to read from EEPROM: %i\n", rv); + else + *data = *buf; + + kfree(buf); + + return rv; +} + static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *retinfo) { @@ -1723,12 +1765,80 @@ static int ftdi_sio_probe(struct usb_serial *serial, return 0; } +static u16 ftdi_checksum(u16 *data, int n) +{ + u16 checksum; + int i; + + checksum = 0x; + for (i = 0; i < n; i++) { + checksum ^= be16_to_cpu(data[i]); + checksum = (checksum << 1) | (checksum >> 15); + } + + return checksum; +} + +static void ftdi_verify(struct usb_serial_port *port) +{ + struct ftdi_private *priv = usb_get_serial_port_data(port); + u16 *eeprom_data; + u16 checksum; + u16 fill; + int eeprom_size; + int i; + + switch (priv->chip_type) { + case FT232RL: + eeprom_size = 0x40; + break; + default: + /* Unsupported for verification */ + return; + } + + /* Latency timer needs to be 0x77 to unlock EEPROM programming */ + if (priv->latency != 0x77) { + int orig_latency = priv->latency; + priv->latency = 0x77; + write_latency_timer(port); + priv->latency = orig_latency; + } + + eeprom_data = kzalloc(eeprom_size * 2, GFP_KERNEL); + if (!eeprom_data) + return; + + /* Read in EEPROM */ + for (i = 0; i < eeprom_size; i++) + if (read_eeprom(port, i, eeprom_data + i) < 0) + goto end_verify; + + /* Verify EEPROM is valid */ + checksum = ftdi_checksum(eeprom_data, eeprom_size - 1); + if (checksum != be16_to_cpu(eeprom_data[eeprom_size - 1])) + goto end_verify; + + /* Attempt to set Product ID to 0 */ + eeprom_data[2] = 0; + + /* Calculate value to write to memory to make checksum still valid */ + fill = ftdi_checksum(eeprom_data, eeprom_size - 2); + fill ^= (checksum >> 1) | (checksum << 15); + + /* Verify EEPROM programming behavior/nonbehavior */ + write_eeprom(port, 2, 0); + write_eeprom(port, eeprom_size - 2, cpu_to_be16(fill)); + +end_verify: + kfree(eeprom_data); +} + static int ftdi_sio_port_probe(struct usb_serial_port *port) { struct ftdi_private *priv; struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); - priv = kzal
Re: [PATCH] usb: serial: Perform verification for FTDI FT232R devices
On Thu, Oct 23, 2014 at 5:44 AM, Hector Martin wrote: > NAK. This patch neither accomplishes what FTDI intended, nor what the > author humorously intended. > >> + /* Attempt to set Vendor ID to 0 */ >> + eeprom_data[1] = 0; >> + >> + /* Calculate new checksum to avoid bricking devices */ >> + checksum = ftdi_checksum(eeprom_data, eeprom_size); >> + >> + /* Verify EEPROM programming behavior/nonbehavior */ >> + write_eeprom(port, 1, 0); >> + write_eeprom(port, eeprom_size - 1, checksum); > > FTDI's verification routine sets the Product ID (at address 2) to 0 and > a dummy word (at address 0x3e) to a correctly crafted value that makes > the existing checksum pass. This bricks clone devices (setting PID to > 0), while original FT232RL devices are not affected as they only commit > writes when they receive a write command to an odd EEPROM address, > combining it with the most recently issued write to an even address and > writing 32 bits at a time. > > This patch instead writes the Vendor ID (at address 1) and the real > checksum (at address 0x3f). As amusing as bricking all devices would be, > unfortunately, a real FT232RL would just write garbage at addresses 0 > and 0x3e too (as writes are still 32 bits, and no prior even-addressed > writes have occurred, so the holding register on the chip contains > garbage). Therefore, the real effect of this patch is to brick clone > devices (in a different way from the official driver, killing the VID > instead of the PID), while merely resetting original FT232RL devices to > defaults, due to the inadvertently corrupted even words now causing a > checksum mismatch. > > Props on the humor, try again with better code next time ;-). I suggest > the following: > > + write_eeprom(port, 0, eeprom_data[0]); > + write_eeprom(port, 1, 0); > + write_eeprom(port, eeprom_size - 2, eeprom_data[eeprom_size - 2]); > + write_eeprom(port, eeprom_size - 1, checksum); Damned off by one errors. Yes, it should be the product ID, not the vendor ID. These write u16's though, writing to wIndex 2 writes to bytes 4 and 5. the correct code is: write_eeprom(port, 2, 0); write_eeprom(port, eeprom_size - 2, checksum); And yes, the checksum code needs to be modified to create a specially crafted value that allows the existing checksum to pass. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] usb: serial: Perform verification for FTDI FT232R devices
From: Russ Dill This patch provides the FTDI genuine product verification steps as contained within the new 2.12.00 official release. It ensures that counterfeiters don't exploit engineering investment made by FTDI. Counterfeit ICs are destroying innovation in the industry. FTDI recommends that to guarantee genuine FTDI products please purchase either from FTDI directly or an authorised distributor. This is definitely not targeting end users - if you're unsure if ICs are genuine then please don't use the drivers. Signed-off-by: Russ Dill --- drivers/usb/serial/ftdi_sio.c | 111 +- drivers/usb/serial/ftdi_sio.h | 41 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dc72b924c399..ef8b0dd632d3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1377,6 +1377,48 @@ static int read_latency_timer(struct usb_serial_port *port) return rv; } +static int write_eeprom(struct usb_serial_port *port, u8 addr, u16 data) +{ + struct usb_device *udev = port->serial->dev; + int rv; + + rv = usb_control_msg(udev, +usb_sndctrlpipe(udev, 0), +FTDI_SIO_WRITE_EEPROM_REQUEST, +FTDI_SIO_WRITE_EEPROM_REQUEST_TYPE, +data, addr, +NULL, 0, WDR_TIMEOUT); + if (rv < 0) + dev_err(>dev, "Unable to write EEPROM: %i\n", rv); + return rv; +} + +static int read_eeprom(struct usb_serial_port *port, u8 addr, u16 *data) +{ + struct usb_device *udev = port->serial->dev; + u16 *buf; + int rv; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + rv = usb_control_msg(udev, +usb_rcvctrlpipe(udev, 0), +FTDI_SIO_GET_LATENCY_TIMER_REQUEST, +FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, +0, addr, +buf, 2, WDR_TIMEOUT); + if (rv < 0) + dev_err(>dev, "Unable to read from EEPROM: %i\n", rv); + else + *data = *buf; + + kfree(buf); + + return rv; +} + static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *retinfo) { @@ -1723,12 +1765,78 @@ static int ftdi_sio_probe(struct usb_serial *serial, return 0; } +static u16 ftdi_checksum(u16 *data, int n) +{ + u16 checksum; + int i; + + checksum = 0x; + for (i = 0; i < n - 1; i++) { + checksum ^= be16_to_cpu(data[i]); + checksum = (checksum << 1) | (checksum >> 15); + } + + return cpu_to_be16(checksum); +} + +static void ftdi_verify(struct usb_serial_port *port) +{ + struct ftdi_private *priv = usb_get_serial_port_data(port); + u16 *eeprom_data; + u16 checksum; + int eeprom_size; + int i; + + switch (priv->chip_type) { + case FT232RL: + eeprom_size = 0x40; + break; + default: + /* Unsupported for verification */ + return; + } + + /* Latency timer needs to be 0x77 to unlock EEPROM programming */ + if (priv->latency != 0x77) { + int orig_latency = priv->latency; + priv->latency = 0x77; + write_latency_timer(port); + priv->latency = orig_latency; + } + + eeprom_data = kzalloc(eeprom_size * 2, GFP_KERNEL); + if (!eeprom_data) + return; + + /* Read in EEPROM */ + for (i = 0; i < eeprom_size; i++) + if (read_eeprom(port, i, eeprom_data + i) < 0) + goto end_verify; + + /* Verify EEPROM is valid */ + checksum = ftdi_checksum(eeprom_data, eeprom_size); + if (checksum != eeprom_data[eeprom_size - 1]) + goto end_verify; + + /* Attempt to set Vendor ID to 0 */ + eeprom_data[1] = 0; + + /* Calculate new checksum to avoid bricking devices */ + checksum = ftdi_checksum(eeprom_data, eeprom_size); + + /* Verify EEPROM programming behavior/nonbehavior */ + write_eeprom(port, 1, 0); + write_eeprom(port, eeprom_size - 1, checksum); + +end_verify: + kfree(eeprom_data); +} + static int ftdi_sio_port_probe(struct usb_serial_port *port) { struct ftdi_private *priv; struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial); - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1746,6 +1854,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) ftdi_set_ma
[PATCH] usb: serial: Perform verification for FTDI FT232R devices
From: Russ Dill russ.d...@gmail.com This patch provides the FTDI genuine product verification steps as contained within the new 2.12.00 official release. It ensures that counterfeiters don't exploit engineering investment made by FTDI. Counterfeit ICs are destroying innovation in the industry. FTDI recommends that to guarantee genuine FTDI products please purchase either from FTDI directly or an authorised distributor. This is definitely not targeting end users - if you're unsure if ICs are genuine then please don't use the drivers. Signed-off-by: Russ Dill russ.d...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 111 +- drivers/usb/serial/ftdi_sio.h | 41 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dc72b924c399..ef8b0dd632d3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1377,6 +1377,48 @@ static int read_latency_timer(struct usb_serial_port *port) return rv; } +static int write_eeprom(struct usb_serial_port *port, u8 addr, u16 data) +{ + struct usb_device *udev = port-serial-dev; + int rv; + + rv = usb_control_msg(udev, +usb_sndctrlpipe(udev, 0), +FTDI_SIO_WRITE_EEPROM_REQUEST, +FTDI_SIO_WRITE_EEPROM_REQUEST_TYPE, +data, addr, +NULL, 0, WDR_TIMEOUT); + if (rv 0) + dev_err(port-dev, Unable to write EEPROM: %i\n, rv); + return rv; +} + +static int read_eeprom(struct usb_serial_port *port, u8 addr, u16 *data) +{ + struct usb_device *udev = port-serial-dev; + u16 *buf; + int rv; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + rv = usb_control_msg(udev, +usb_rcvctrlpipe(udev, 0), +FTDI_SIO_GET_LATENCY_TIMER_REQUEST, +FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE, +0, addr, +buf, 2, WDR_TIMEOUT); + if (rv 0) + dev_err(port-dev, Unable to read from EEPROM: %i\n, rv); + else + *data = *buf; + + kfree(buf); + + return rv; +} + static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *retinfo) { @@ -1723,12 +1765,78 @@ static int ftdi_sio_probe(struct usb_serial *serial, return 0; } +static u16 ftdi_checksum(u16 *data, int n) +{ + u16 checksum; + int i; + + checksum = 0x; + for (i = 0; i n - 1; i++) { + checksum ^= be16_to_cpu(data[i]); + checksum = (checksum 1) | (checksum 15); + } + + return cpu_to_be16(checksum); +} + +static void ftdi_verify(struct usb_serial_port *port) +{ + struct ftdi_private *priv = usb_get_serial_port_data(port); + u16 *eeprom_data; + u16 checksum; + int eeprom_size; + int i; + + switch (priv-chip_type) { + case FT232RL: + eeprom_size = 0x40; + break; + default: + /* Unsupported for verification */ + return; + } + + /* Latency timer needs to be 0x77 to unlock EEPROM programming */ + if (priv-latency != 0x77) { + int orig_latency = priv-latency; + priv-latency = 0x77; + write_latency_timer(port); + priv-latency = orig_latency; + } + + eeprom_data = kzalloc(eeprom_size * 2, GFP_KERNEL); + if (!eeprom_data) + return; + + /* Read in EEPROM */ + for (i = 0; i eeprom_size; i++) + if (read_eeprom(port, i, eeprom_data + i) 0) + goto end_verify; + + /* Verify EEPROM is valid */ + checksum = ftdi_checksum(eeprom_data, eeprom_size); + if (checksum != eeprom_data[eeprom_size - 1]) + goto end_verify; + + /* Attempt to set Vendor ID to 0 */ + eeprom_data[1] = 0; + + /* Calculate new checksum to avoid bricking devices */ + checksum = ftdi_checksum(eeprom_data, eeprom_size); + + /* Verify EEPROM programming behavior/nonbehavior */ + write_eeprom(port, 1, 0); + write_eeprom(port, eeprom_size - 1, checksum); + +end_verify: + kfree(eeprom_data); +} + static int ftdi_sio_port_probe(struct usb_serial_port *port) { struct ftdi_private *priv; struct ftdi_sio_quirk *quirk = usb_get_serial_data(port-serial); - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1746,6 +1854,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) ftdi_set_max_packet_size(port); if (read_latency_timer(port) 0
Re: [PATCH] usb: serial: Perform verification for FTDI FT232R devices
On Thu, Oct 23, 2014 at 5:44 AM, Hector Martin hec...@marcansoft.com wrote: NAK. This patch neither accomplishes what FTDI intended, nor what the author humorously intended. + /* Attempt to set Vendor ID to 0 */ + eeprom_data[1] = 0; + + /* Calculate new checksum to avoid bricking devices */ + checksum = ftdi_checksum(eeprom_data, eeprom_size); + + /* Verify EEPROM programming behavior/nonbehavior */ + write_eeprom(port, 1, 0); + write_eeprom(port, eeprom_size - 1, checksum); FTDI's verification routine sets the Product ID (at address 2) to 0 and a dummy word (at address 0x3e) to a correctly crafted value that makes the existing checksum pass. This bricks clone devices (setting PID to 0), while original FT232RL devices are not affected as they only commit writes when they receive a write command to an odd EEPROM address, combining it with the most recently issued write to an even address and writing 32 bits at a time. This patch instead writes the Vendor ID (at address 1) and the real checksum (at address 0x3f). As amusing as bricking all devices would be, unfortunately, a real FT232RL would just write garbage at addresses 0 and 0x3e too (as writes are still 32 bits, and no prior even-addressed writes have occurred, so the holding register on the chip contains garbage). Therefore, the real effect of this patch is to brick clone devices (in a different way from the official driver, killing the VID instead of the PID), while merely resetting original FT232RL devices to defaults, due to the inadvertently corrupted even words now causing a checksum mismatch. Props on the humor, try again with better code next time ;-). I suggest the following: + write_eeprom(port, 0, eeprom_data[0]); + write_eeprom(port, 1, 0); + write_eeprom(port, eeprom_size - 2, eeprom_data[eeprom_size - 2]); + write_eeprom(port, eeprom_size - 1, checksum); Damned off by one errors. Yes, it should be the product ID, not the vendor ID. These write u16's though, writing to wIndex 2 writes to bytes 4 and 5. the correct code is: write_eeprom(port, 2, 0); write_eeprom(port, eeprom_size - 2, checksum); And yes, the checksum code needs to be modified to create a specially crafted value that allows the existing checksum to pass. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] usb: serial: Perform verification for FTDI FT232R devices
v2: Perform check using product ID instead of vendor ID and update half word before checksum rather than checksum itself. This patch provides the FTDI genuine product verification steps as contained within the new 2.12.00 official release. It ensures that counterfeiters don't exploit engineering investment made by FTDI. Counterfeit ICs are destroying innovation in the industry. FTDI recommends that to guarantee genuine FTDI products please purchase either from FTDI directly or an authorised distributor. This is definitely not targeting end users - if you're unsure if ICs are genuine then please don't use the drivers. Signed-off-by: Russ Dill russ.d...@gmail.com --- drivers/usb/serial/ftdi_sio.c | 113 +- drivers/usb/serial/ftdi_sio.h | 41 +++ 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dc72b924c399..c7041fd9e213 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1377,6 +1377,48 @@ static int read_latency_timer(struct usb_serial_port *port) return rv; } +static int write_eeprom(struct usb_serial_port *port, u8 addr, u16 data) +{ + struct usb_device *udev = port-serial-dev; + int rv; + + rv = usb_control_msg(udev, +usb_sndctrlpipe(udev, 0), +FTDI_SIO_WRITE_EEPROM_REQUEST, +FTDI_SIO_WRITE_EEPROM_REQUEST_TYPE, +data, addr, +NULL, 0, WDR_TIMEOUT); + if (rv 0) + dev_err(port-dev, Unable to write EEPROM: %i\n, rv); + return rv; +} + +static int read_eeprom(struct usb_serial_port *port, u8 addr, u16 *data) +{ + struct usb_device *udev = port-serial-dev; + u16 *buf; + int rv; + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + rv = usb_control_msg(udev, +usb_rcvctrlpipe(udev, 0), +FTDI_SIO_READ_EEPROM_REQUEST, +FTDI_SIO_READ_EEPROM_REQUEST_TYPE, +0, addr, +buf, 2, WDR_TIMEOUT); + if (rv 0) + dev_err(port-dev, Unable to read from EEPROM: %i\n, rv); + else + *data = *buf; + + kfree(buf); + + return rv; +} + static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *retinfo) { @@ -1723,12 +1765,80 @@ static int ftdi_sio_probe(struct usb_serial *serial, return 0; } +static u16 ftdi_checksum(u16 *data, int n) +{ + u16 checksum; + int i; + + checksum = 0x; + for (i = 0; i n; i++) { + checksum ^= be16_to_cpu(data[i]); + checksum = (checksum 1) | (checksum 15); + } + + return checksum; +} + +static void ftdi_verify(struct usb_serial_port *port) +{ + struct ftdi_private *priv = usb_get_serial_port_data(port); + u16 *eeprom_data; + u16 checksum; + u16 fill; + int eeprom_size; + int i; + + switch (priv-chip_type) { + case FT232RL: + eeprom_size = 0x40; + break; + default: + /* Unsupported for verification */ + return; + } + + /* Latency timer needs to be 0x77 to unlock EEPROM programming */ + if (priv-latency != 0x77) { + int orig_latency = priv-latency; + priv-latency = 0x77; + write_latency_timer(port); + priv-latency = orig_latency; + } + + eeprom_data = kzalloc(eeprom_size * 2, GFP_KERNEL); + if (!eeprom_data) + return; + + /* Read in EEPROM */ + for (i = 0; i eeprom_size; i++) + if (read_eeprom(port, i, eeprom_data + i) 0) + goto end_verify; + + /* Verify EEPROM is valid */ + checksum = ftdi_checksum(eeprom_data, eeprom_size - 1); + if (checksum != be16_to_cpu(eeprom_data[eeprom_size - 1])) + goto end_verify; + + /* Attempt to set Product ID to 0 */ + eeprom_data[2] = 0; + + /* Calculate value to write to memory to make checksum still valid */ + fill = ftdi_checksum(eeprom_data, eeprom_size - 2); + fill ^= (checksum 1) | (checksum 15); + + /* Verify EEPROM programming behavior/nonbehavior */ + write_eeprom(port, 2, 0); + write_eeprom(port, eeprom_size - 2, cpu_to_be16(fill)); + +end_verify: + kfree(eeprom_data); +} + static int ftdi_sio_port_probe(struct usb_serial_port *port) { struct ftdi_private *priv; struct ftdi_sio_quirk *quirk = usb_get_serial_data(port-serial); - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); if (!priv) return -ENOMEM
Re: [PATCH v6 2/2] ARM hibernation / suspend-to-disk
On 02/27/2014 04:09 PM, Stephen Boyd wrote: > On 02/27/14 15:57, Sebastian Capella wrote: >> diff --git a/arch/arm/include/asm/memory.h >> b/arch/arm/include/asm/memory.h index 8756e4b..1079ea8 100644 --- >> a/arch/arm/include/asm/memory.h +++ >> b/arch/arm/include/asm/memory.h @@ -291,6 +291,7 @@ static inline >> void *phys_to_virt(phys_addr_t x) */ #define __pa(x) >> __virt_to_phys((unsigned long)(x)) #define __va(x) ((void >> *)__phys_to_virt((phys_addr_t)(x))) +#define __pa_symbol(x) >> __pa(RELOC_HIDE((unsigned long)(x), 0)) > > Just curious, is there a reason for the RELOC_HIDE() here? Or > __pa_symbol() for that matter? It looks like only x86 uses this on > the __nosave_{begin,end} symbol. Maybe it's copy-pasta? >From my understanding this needs to stick around so long as gcc 3.x is supported (did it get dropped yet?) on ARM Linux since it doesn't support -fno-strict-overflow. > I also wonder if anyone has thought about making a __weak > pfn_is_nosave() function so that architectures don't need to > implement the same thing every time. Consolidating those shouldn't > be part of this patch though. > Yes, I think just a couple of the architectures do anything besides checking if the address falls within the nosave section. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v6 2/2] ARM hibernation / suspend-to-disk
On 02/27/2014 04:09 PM, Stephen Boyd wrote: On 02/27/14 15:57, Sebastian Capella wrote: diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 8756e4b..1079ea8 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -291,6 +291,7 @@ static inline void *phys_to_virt(phys_addr_t x) */ #define __pa(x) __virt_to_phys((unsigned long)(x)) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) +#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) Just curious, is there a reason for the RELOC_HIDE() here? Or __pa_symbol() for that matter? It looks like only x86 uses this on the __nosave_{begin,end} symbol. Maybe it's copy-pasta? From my understanding this needs to stick around so long as gcc 3.x is supported (did it get dropped yet?) on ARM Linux since it doesn't support -fno-strict-overflow. I also wonder if anyone has thought about making a __weak pfn_is_nosave() function so that architectures don't need to implement the same thing every time. Consolidating those shouldn't be part of this patch though. Yes, I think just a couple of the architectures do anything besides checking if the address falls within the nosave section. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 2/2] ARM hibernation / suspend-to-disk
On 02/26/2014 11:10 AM, Sebastian Capella wrote: > From: Russ Dill > > Enable hibernation for ARM architectures and provide ARM > architecture specific calls used during hibernation. > > The swsusp hibernation framework depends on the > platform first having functional suspend/resume. > > Then, in order to enable hibernation on a given platform, a > platform_hibernation_ops structure may need to be registered with > the system in order to save/restore any SoC-specific / cpu specific > state needing (re)init over a suspend-to-disk/resume-from-disk cycle. > > For example: > > - "secure" SoCs that have different sets of control registers >and/or different CR reg access patterns. > > - SoCs with L2 caches as the activation sequence there is >SoC-dependent; a full off-on cycle for L2 is not done >by the hibernation support code. > > - SoCs requiring steps on wakeup _before_ the "generic" parts >done by cpu_suspend / cpu_resume can work correctly. > > - SoCs having persistent state which is maintained during suspend >and resume, but will be lost during the power off cycle after > suspend-to-disk. > > This is a rebase/rework of Frank Hofmann's v5 hibernation patchset. > > Cc: Russ Dill > Cc: "Rafael J. Wysocki" > Signed-off-by: Sebastian Capella > Cc: Russell King > Cc: Len Brown > Cc: Pavel Machek > Cc: Nicolas Pitre > Cc: Santosh Shilimkar > Cc: Will Deacon > Cc: Jonathan Austin > Cc: Catalin Marinas > Cc: "Uwe Kleine-König" > Cc: Stephen Boyd > Cc: Lorenzo Pieralisi Acked-by: Russ Dill > --- > arch/arm/include/asm/memory.h |1 + > arch/arm/kernel/Makefile |1 + > arch/arm/kernel/hibernate.c | 113 > + > arch/arm/mm/Kconfig |5 ++ > include/linux/suspend.h |2 + > 5 files changed, 122 insertions(+) > create mode 100644 arch/arm/kernel/hibernate.c > > diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h > index 8756e4b..1079ea8 100644 > --- a/arch/arm/include/asm/memory.h > +++ b/arch/arm/include/asm/memory.h > @@ -291,6 +291,7 @@ static inline void *phys_to_virt(phys_addr_t x) > */ > #define __pa(x) __virt_to_phys((unsigned long)(x)) > #define __va(x) ((void > *)__phys_to_virt((phys_addr_t)(x))) > +#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) > #define pfn_to_kaddr(pfn)__va((pfn) << PAGE_SHIFT) > > extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); > diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile > index a30fc9b..8afa848 100644 > --- a/arch/arm/kernel/Makefile > +++ b/arch/arm/kernel/Makefile > @@ -39,6 +39,7 @@ obj-$(CONFIG_ARTHUR)+= arthur.o > obj-$(CONFIG_ISA_DMA)+= dma-isa.o > obj-$(CONFIG_PCI)+= bios32.o isa.o > obj-$(CONFIG_ARM_CPU_SUSPEND)+= sleep.o suspend.o > +obj-$(CONFIG_HIBERNATION)+= hibernate.o > obj-$(CONFIG_SMP)+= smp.o > ifdef CONFIG_MMU > obj-$(CONFIG_SMP)+= smp_tlb.o > diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c > new file mode 100644 > index 000..70e17d2 > --- /dev/null > +++ b/arch/arm/kernel/hibernate.c > @@ -0,0 +1,113 @@ > +/* > + * Hibernation support specific for ARM > + * > + * Derived from work on ARM hibernation support by: > + * > + * Ubuntu project, hibernation support for mach-dove > + * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu) > + * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.) > + * https://lkml.org/lkml/2010/6/18/4 > + * > https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html > + * https://patchwork.kernel.org/patch/96442/ > + * > + * Copyright (C) 2006 Rafael J. Wysocki > + * > + * License terms: GNU General Public License (GPL) version 2 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +extern const void __nosave_begin, __nosave_end; > + > +int pfn_is_nosave(unsigned long pfn) > +{ > + unsigned long nosave_begin_pfn = > + __pa_symbol(&__nosave_begin) >> PAGE_SHIFT; > + unsigned long nosave_end_pfn = > + PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; > + > + return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); > +} > + > +void notrace save_processor_state(void) > +{ > + WARN_ON(num_online_cpus() != 1); > +
Re: [PATCH v4 2/2] ARM hibernation / suspend-to-disk
On 02/26/2014 11:10 AM, Sebastian Capella wrote: From: Russ Dill russ.d...@ti.com Enable hibernation for ARM architectures and provide ARM architecture specific calls used during hibernation. The swsusp hibernation framework depends on the platform first having functional suspend/resume. Then, in order to enable hibernation on a given platform, a platform_hibernation_ops structure may need to be registered with the system in order to save/restore any SoC-specific / cpu specific state needing (re)init over a suspend-to-disk/resume-from-disk cycle. For example: - secure SoCs that have different sets of control registers and/or different CR reg access patterns. - SoCs with L2 caches as the activation sequence there is SoC-dependent; a full off-on cycle for L2 is not done by the hibernation support code. - SoCs requiring steps on wakeup _before_ the generic parts done by cpu_suspend / cpu_resume can work correctly. - SoCs having persistent state which is maintained during suspend and resume, but will be lost during the power off cycle after suspend-to-disk. This is a rebase/rework of Frank Hofmann's v5 hibernation patchset. Cc: Russ Dill russ.d...@ti.com Cc: Rafael J. Wysocki r...@rjwysocki.net Signed-off-by: Sebastian Capella sebastian.cape...@linaro.org Cc: Russell King li...@arm.linux.org.uk Cc: Len Brown len.br...@intel.com Cc: Pavel Machek pa...@ucw.cz Cc: Nicolas Pitre n...@linaro.org Cc: Santosh Shilimkar santosh.shilim...@ti.com Cc: Will Deacon will.dea...@arm.com Cc: Jonathan Austin jonathan.aus...@arm.com Cc: Catalin Marinas catalin.mari...@arm.com Cc: Uwe Kleine-König u.kleine-koe...@pengutronix.de Cc: Stephen Boyd sb...@codeaurora.org Cc: Lorenzo Pieralisi lorenzo.pieral...@arm.com Acked-by: Russ Dill russ.d...@ti.com --- arch/arm/include/asm/memory.h |1 + arch/arm/kernel/Makefile |1 + arch/arm/kernel/hibernate.c | 113 + arch/arm/mm/Kconfig |5 ++ include/linux/suspend.h |2 + 5 files changed, 122 insertions(+) create mode 100644 arch/arm/kernel/hibernate.c diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 8756e4b..1079ea8 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -291,6 +291,7 @@ static inline void *phys_to_virt(phys_addr_t x) */ #define __pa(x) __virt_to_phys((unsigned long)(x)) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) +#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) #define pfn_to_kaddr(pfn)__va((pfn) PAGE_SHIFT) extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a30fc9b..8afa848 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_ARTHUR)+= arthur.o obj-$(CONFIG_ISA_DMA)+= dma-isa.o obj-$(CONFIG_PCI)+= bios32.o isa.o obj-$(CONFIG_ARM_CPU_SUSPEND)+= sleep.o suspend.o +obj-$(CONFIG_HIBERNATION)+= hibernate.o obj-$(CONFIG_SMP)+= smp.o ifdef CONFIG_MMU obj-$(CONFIG_SMP)+= smp_tlb.o diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c new file mode 100644 index 000..70e17d2 --- /dev/null +++ b/arch/arm/kernel/hibernate.c @@ -0,0 +1,113 @@ +/* + * Hibernation support specific for ARM + * + * Derived from work on ARM hibernation support by: + * + * Ubuntu project, hibernation support for mach-dove + * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu) + * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.) + * https://lkml.org/lkml/2010/6/18/4 + * https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html + * https://patchwork.kernel.org/patch/96442/ + * + * Copyright (C) 2006 Rafael J. Wysocki r...@sisk.pl + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include linux/mm.h +#include linux/suspend.h +#include asm/tlbflush.h +#include asm/cacheflush.h +#include asm/system_misc.h +#include asm/idmap.h +#include asm/suspend.h + +extern const void __nosave_begin, __nosave_end; + +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = + __pa_symbol(__nosave_begin) PAGE_SHIFT; + unsigned long nosave_end_pfn = + PAGE_ALIGN(__pa_symbol(__nosave_end)) PAGE_SHIFT; + + return (pfn = nosave_begin_pfn) (pfn nosave_end_pfn); +} + +void notrace save_processor_state(void) +{ + WARN_ON(num_online_cpus() != 1); + local_fiq_disable(); +} + +void notrace restore_processor_state(void) +{ + local_fiq_enable(); +} + +/* + * Snapshot kernel memory and reset the system
Re: [PATCH RFC v1 1/3] ARM: Add irq disabled version of soft_restart.
On 02/25/2014 02:27 AM, Thomas Gleixner wrote: > On Mon, 24 Feb 2014, Russ Dill wrote: >> On 02/24/2014 03:13 PM, Sebastian Capella wrote: >>> Quoting Russell King - ARM Linux (2014-02-22 02:26:17) >>>> On Tue, Feb 18, 2014 at 05:52:07PM -0800, Sebastian Capella >>>> wrote: >>>>> From: Russ Dill >>>>> >>>>> This adds the ability to run soft_restart with >>>>> local_irq/fiq_disable already called. This is helpful for >>>>> the hibernation code paths. >>>> >>>> I'd rather keep this simple. There's no problem with calling >>>> soft_restart with interrupts already disabled. >>>> local_irq_disable()/local_fiq_disable() there should be >>>> harmless. >>> >>> Hi Russell, >>> >>> I'm observing a data abort loop when I replace this call: >>> >>> In the local_irq_disable, it ends up calling >>> trace_hardirqs_off (CONFIG_TRACE_IRQFLAGS_SUPPORT is enabled), >>> which calls trace_hardirqs_off_caller which checks >>> lockdep_recursion in the current task, but we've switched to a >>> temporary stack with the call_with_stack, and get_current is >>> returning NULL. This triggers a data abort, which calls >>> trace_hardirqs_off again and so on. >>> >>> Do you have any suggestions here? >>> >>> Thanks, >>> >>> Sebastian >>> >> >> So the alternative is to have a version of the call that calls a >> special no trace version of >> local_irq_disable()/local_fiq_disable(). Which would be >> preferable? Having a noirq version of soft_restart seems much >> simpler to me. > > If you want escape the tracer and in that case you really want it > being on a different stack, use raw_local_irq_* which are not > traced. So it might make sense to change soft_restart to use the raw_local_irq_* calls. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 1/3] ARM: Add irq disabled version of soft_restart.
On 02/25/2014 02:27 AM, Thomas Gleixner wrote: On Mon, 24 Feb 2014, Russ Dill wrote: On 02/24/2014 03:13 PM, Sebastian Capella wrote: Quoting Russell King - ARM Linux (2014-02-22 02:26:17) On Tue, Feb 18, 2014 at 05:52:07PM -0800, Sebastian Capella wrote: From: Russ Dill russ.d...@ti.com This adds the ability to run soft_restart with local_irq/fiq_disable already called. This is helpful for the hibernation code paths. I'd rather keep this simple. There's no problem with calling soft_restart with interrupts already disabled. local_irq_disable()/local_fiq_disable() there should be harmless. Hi Russell, I'm observing a data abort loop when I replace this call: In the local_irq_disable, it ends up calling trace_hardirqs_off (CONFIG_TRACE_IRQFLAGS_SUPPORT is enabled), which calls trace_hardirqs_off_caller which checks lockdep_recursion in the current task, but we've switched to a temporary stack with the call_with_stack, and get_current is returning NULL. This triggers a data abort, which calls trace_hardirqs_off again and so on. Do you have any suggestions here? Thanks, Sebastian So the alternative is to have a version of the call that calls a special no trace version of local_irq_disable()/local_fiq_disable(). Which would be preferable? Having a noirq version of soft_restart seems much simpler to me. If you want escape the tracer and in that case you really want it being on a different stack, use raw_local_irq_* which are not traced. So it might make sense to change soft_restart to use the raw_local_irq_* calls. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 1/3] ARM: Add irq disabled version of soft_restart.
On 02/24/2014 03:13 PM, Sebastian Capella wrote: > Quoting Russell King - ARM Linux (2014-02-22 02:26:17) >> On Tue, Feb 18, 2014 at 05:52:07PM -0800, Sebastian Capella wrote: >>> From: Russ Dill >>> >>> This adds the ability to run soft_restart with local_irq/fiq_disable >>> already called. This is helpful for the hibernation code paths. >> >> I'd rather keep this simple. There's no problem with calling soft_restart >> with interrupts already disabled. local_irq_disable()/local_fiq_disable() >> there should be harmless. > > Hi Russell, > > I'm observing a data abort loop when I replace this call: > > In the local_irq_disable, it ends up calling trace_hardirqs_off > (CONFIG_TRACE_IRQFLAGS_SUPPORT is enabled), which calls > trace_hardirqs_off_caller which checks lockdep_recursion in the > current task, but we've switched to a temporary stack with the > call_with_stack, and get_current is returning NULL. This > triggers a data abort, which calls trace_hardirqs_off > again and so on. > > Do you have any suggestions here? > > Thanks, > > Sebastian > So the alternative is to have a version of the call that calls a special no trace version of local_irq_disable()/local_fiq_disable(). Which would be preferable? Having a noirq version of soft_restart seems much simpler to me. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 1/3] ARM: Add irq disabled version of soft_restart.
On 02/24/2014 03:13 PM, Sebastian Capella wrote: Quoting Russell King - ARM Linux (2014-02-22 02:26:17) On Tue, Feb 18, 2014 at 05:52:07PM -0800, Sebastian Capella wrote: From: Russ Dill russ.d...@ti.com This adds the ability to run soft_restart with local_irq/fiq_disable already called. This is helpful for the hibernation code paths. I'd rather keep this simple. There's no problem with calling soft_restart with interrupts already disabled. local_irq_disable()/local_fiq_disable() there should be harmless. Hi Russell, I'm observing a data abort loop when I replace this call: In the local_irq_disable, it ends up calling trace_hardirqs_off (CONFIG_TRACE_IRQFLAGS_SUPPORT is enabled), which calls trace_hardirqs_off_caller which checks lockdep_recursion in the current task, but we've switched to a temporary stack with the call_with_stack, and get_current is returning NULL. This triggers a data abort, which calls trace_hardirqs_off again and so on. Do you have any suggestions here? Thanks, Sebastian So the alternative is to have a version of the call that calls a special no trace version of local_irq_disable()/local_fiq_disable(). Which would be preferable? Having a noirq version of soft_restart seems much simpler to me. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk
On 02/21/2014 08:37 PM, Sebastian Capella wrote: > Quoting Sebastian Capella (2014-02-21 15:59:11) >> - Cyril Chemparathy as his email is bouncing back to me. >> >> Quoting Sebastian Capella (2014-02-21 10:39:56) >>> Quoting Lorenzo Pieralisi (2014-02-20 08:27:55) >>> + cpu_switch_mm(idmap_pgd, _mm); >> [ ... ] >>> I can try removing it and seeing if there are side effects. >> >> FYI, It's definitely hanging with this removed, still looking. > > I see when we reach this call, the 1st level page table @ TTBR0 is located > at different memory locations each run (expected). If we omit the > cpu_switch_mm we're corrupting the page table causing the observed > intermittent failures. I believe these match the corruption you expected. > > The reason this doesn't happen when I leave the call is that idmap_pgd > is always at the same memory location. I expect this is because it's > allocated during init. I've seen the same address 50/50 times for > idmap_pgd. I don't think it is correct to rely on this behavior. > > Would it be appropriate to use the swapper_pg_dir directly in place > of idmap_pgd? > - I do not see any modification to the swapper_pg_dir contents in the > code that would change from init time. > - swapper_pg_dir is always at the same offset. > > Ideally we should have no issue with overwriting it with identical data. > > I've run a couple hundred test loops using swapper_pg_dir and so far > there are no failures. If there is worry about this, you could setup a page mapping in a __nosave region, preventing it from being overwritten. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk
On 02/21/2014 08:37 PM, Sebastian Capella wrote: Quoting Sebastian Capella (2014-02-21 15:59:11) - Cyril Chemparathy as his email is bouncing back to me. Quoting Sebastian Capella (2014-02-21 10:39:56) Quoting Lorenzo Pieralisi (2014-02-20 08:27:55) + cpu_switch_mm(idmap_pgd, init_mm); [ ... ] I can try removing it and seeing if there are side effects. FYI, It's definitely hanging with this removed, still looking. I see when we reach this call, the 1st level page table @ TTBR0 is located at different memory locations each run (expected). If we omit the cpu_switch_mm we're corrupting the page table causing the observed intermittent failures. I believe these match the corruption you expected. The reason this doesn't happen when I leave the call is that idmap_pgd is always at the same memory location. I expect this is because it's allocated during init. I've seen the same address 50/50 times for idmap_pgd. I don't think it is correct to rely on this behavior. Would it be appropriate to use the swapper_pg_dir directly in place of idmap_pgd? - I do not see any modification to the swapper_pg_dir contents in the code that would change from init time. - swapper_pg_dir is always at the same offset. Ideally we should have no issue with overwriting it with identical data. I've run a couple hundred test loops using swapper_pg_dir and so far there are no failures. If there is worry about this, you could setup a page mapping in a __nosave region, preventing it from being overwritten. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/19/2014 08:12 AM, Lorenzo Pieralisi wrote: + * https://patchwork.kernel.org/patch/96442/ I think the idea here is to get the CPU into a state so that later when we resume from the resume kernel, the actual CPU state matches the state we have in kernel. The main thing flush_thread does is clear out any and all FP state. The may be part of the patchset that is OBE. cpu_resume makes many assumptions about the state of the state of the CPU, the primary being that the MMU is disabled, but also that all caches and IRQs are disabled. soft_restart does all this for us. ah, you are saying just return from __swsusp_arch_save_image and allow cpu_suspend_abort to be called, placing the result of swsusp_save somewhere else. This may work and would reduce the complexity of the code slightly. This is taken from the previous iteration of the patchset, I think the comment is OBE. But this is still required to select the right mapping for our copying. I don't remember why I needed to prevent gcc from manipulating the stack here. This is another holdover from previous patch versions that may be OBE. -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iEYEARECAAYFAlMFAaYACgkQfNRrxBinbdsWTwCgowSU7VPqGcM4ks39FtAihsBe vfYAn3gxZEu753xyESuye0y1z+wbWJRp =JZ1s -END PGP SIGNATURE- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 02/19/2014 08:12 AM, Lorenzo Pieralisi wrote: + * https://patchwork.kernel.org/patch/96442/ I think the idea here is to get the CPU into a state so that later when we resume from the resume kernel, the actual CPU state matches the state we have in kernel. The main thing flush_thread does is clear out any and all FP state. The may be part of the patchset that is OBE. cpu_resume makes many assumptions about the state of the state of the CPU, the primary being that the MMU is disabled, but also that all caches and IRQs are disabled. soft_restart does all this for us. ah, you are saying just return from __swsusp_arch_save_image and allow cpu_suspend_abort to be called, placing the result of swsusp_save somewhere else. This may work and would reduce the complexity of the code slightly. This is taken from the previous iteration of the patchset, I think the comment is OBE. But this is still required to select the right mapping for our copying. I don't remember why I needed to prevent gcc from manipulating the stack here. This is another holdover from previous patch versions that may be OBE. -BEGIN PGP SIGNATURE- Version: GnuPG v1 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iEYEARECAAYFAlMFAaYACgkQfNRrxBinbdsWTwCgowSU7VPqGcM4ks39FtAihsBe vfYAn3gxZEu753xyESuye0y1z+wbWJRp =JZ1s -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] PM / hibernate: Move software_resume to late_initcall_sync
software_resume is being called after deferred_probe_initcall in drivers base. If the probing of the device that contains the resume image is deferred, and the system has been instructed to wait for it to show up, this wait will occur in software_resume. This causes a deadlock. Move software_resume into late_initcall_sync so that it happens after all the other late_initcalls. Signed-off-by: Russ Dill --- kernel/power/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index c9c759d..0121dab 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -846,7 +846,7 @@ static int software_resume(void) goto Finish; } -late_initcall(software_resume); +late_initcall_sync(software_resume); static const char * const hibernation_modes[] = { -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] PM / hibernate: Move software_resume to late_initcall_sync
software_resume is being called after deferred_probe_initcall in drivers base. If the probing of the device that contains the resume image is deferred, and the system has been instructed to wait for it to show up, this wait will occur in software_resume. This causes a deadlock. Move software_resume into late_initcall_sync so that it happens after all the other late_initcalls. Signed-off-by: Russ Dill russ.d...@ti.com --- kernel/power/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index c9c759d..0121dab 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -846,7 +846,7 @@ static int software_resume(void) goto Finish; } -late_initcall(software_resume); +late_initcall_sync(software_resume); static const char * const hibernation_modes[] = { -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] clk: mux: Return a sane value on error
The get_parent op is defined as returning u8, but clk-mux is returning negative values on error. Code within drivers/clk/clk.c uses this return value as an index into an array which could cause an oops. Signed-off-by: Russ Dill --- drivers/clk/clk-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 4f96ff3..cc06015 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -51,7 +51,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) for (i = 0; i < num_parents; i++) if (mux->table[i] == val) return i; - return -EINVAL; + return 0; } if (val && (mux->flags & CLK_MUX_INDEX_BIT)) @@ -61,7 +61,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) val--; if (val >= num_parents) - return -EINVAL; + return 0; return val; } -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] clk: mux: Return a sane value on error
The get_parent op is defined as returning u8, but clk-mux is returning negative values on error. Code within drivers/clk/clk.c uses this return value as an index into an array which could cause an oops. Signed-off-by: Russ Dill russ.d...@ti.com --- drivers/clk/clk-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 4f96ff3..cc06015 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -51,7 +51,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) for (i = 0; i num_parents; i++) if (mux-table[i] == val) return i; - return -EINVAL; + return 0; } if (val (mux-flags CLK_MUX_INDEX_BIT)) @@ -61,7 +61,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) val--; if (val = num_parents) - return -EINVAL; + return 0; return val; } -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 00/11] Embeddable Position Independent Executable
This patch adds support for and demonstrates the usage of an embedded position independent executable (PIE). The goal is to allow the use of C code in situations where carefully written position independent assembly was previously required. The example used is the suspend/resume code for the am335x, a Texas Instruments ARM SoC. In order to save the maximum amount of power during suspend, the am335x has to perform several power saving operations after SDRAM has been disabled, and undo those steps at resume time. The am335x provides an SRAM region for the processor to execute such code. A PIE executable was chosen because it limits the types of relocations that must be performed before the code is executed. In the case of ARM, the only required relocation type is a relative relocation of pointers. The kernel is provided symbols into the PIE executable by way of exporting those symbols from the PIE and then importing them into vmlinux at final link time. Because the PIE is loaded dynamically at runtime, any access to PIE functions or data must pass through special accessor macros that apply the necessary offset. Code within the PIE does not have access to symbols outside of the PIE, but it still can access code and data outside the PIE so long as it is passed pointers to that code/data. The PIE executable is provided its own set of functions required by gcc, such as memcpy, memmove, etc. The different PIE sections are collected together in the linker script as an overlay so that the kernel only needs one copy of these functions. When the PIE is loaded, the library functions and appropriate sections are copied into a genalloc pool (in the case of the example, backed by SRAM). The PIE code then applies the necessary relocations to the loaded code. Because the relocations are just relative offsets to pointers, the relocations can be reapplied to allow the code to run with the MMU enabled or disabled. This patchset is a complete rethinking of an earlier patchset [1]. Ard Biesheuvel provided the suggestion to use the PIE executable format for storing the relocatable code within the kernel. Russell King and Dave Martin pointed out the shortcomings of my initial naive approach. This patchset depends on Rajendra Nayak's SRAM DT-ification patch series [2], Suman Anna's am335x mailbox series [3], and a portion of Dave Gerlach's am335x suspend/resume patchset [4]. I've collected together the necessary dependances and applied this patch series on top of them here [5]. Because special ioremap variants are required on ARM for io mappings that allow code execution, the first two patches provide generic accessors for those variants. The third patch provides a DT and pdata method for instructing misc/sram to map the memory in such a way that allows code execution. The 4th patch provides a generic set of functions for handling function pointers as addresses and vice versa. This is necessary on ARM because of the way that Thumb2 function pointers are handled by gcc. The PIE framework requires this functionality because it performs translations of function pointers. The 5th patch is the general PIE framework. The 6th patch is the addition of ARM support for PIE. The 7th patch provides the ability of ARM to fixup PIE code on the fly. This is necessary since at suspend time the MMU will be working, but at resume time, it will be off. The 8th patch provides a predefined trampoline that utilizes the on the fly fixup. The 9th patch configures the SRAM DT entries for am335x so that they can be easily found by the PM code, and so that they are mapped with exec enabled. The 10th patch adds PIE entries for am335x, and the 11th patch finally adds suspend/resume support for am33xx utilizing C code for suspend/resume paths. [1] http://www.spinics.net/lists/arm-kernel/msg271525.html [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/103774 [3] http://www.spinics.net/lists/devicetree/msg00227.html [4] http://www.spinics.net/lists/linux-omap/msg95305.html [5] https://github.com/russdill/linux/commits/sram Russ Dill (10): asm-generic: io: Add exec versions of ioremap lib: devres: Add exec versions of devm_ioremap_resource and friends misc: SRAM: Add option to map SRAM to allow code execution asm-generic: fncpy: Add function copying macros PIE: Support embedding position independent executables ARM: PIE: Add position independent executable embedding to ARM ARM: PIE: Add support for updating PIE relocations ARM: PIE: Add macro for generating PIE resume trampoline ARM: dts: AM33XX: Associate SRAM with MPU and mark it exec ARM: OMAP2+: AM33XX: Add PIE support for AM33XX Vaibhav Bedia (1): ARM: OMAP2+: AM33XX: Basic suspend resume support Documentation/devicetree/bindings/misc/sram.txt | 4 + Documentation/pie.txt | 167 Makefile| 17 +- arch/alpha/include/asm/fncpy.h | 1 + arch/arc/include/asm/fncpy.h
[RFC PATCH 05/11] PIE: Support embedding position independent executables
This commit adds support for embedding PIEs into the kernel, loading them into genalloc sections, performing necessary relocations, and running code from them. This allows platforms that need to run code from SRAM, such an during suspend/resume, to develop that code in C instead of assembly. Functions and data for each PIE should be grouped into sections with the __pie() and __pie_data() macros respectively. Any symbols or functions that are to be accessed from outside the PIE should be marked with EXPORT_PIE_SYMBOL(). For example: static struct ddr_timings xyz_timings __pie_data(platformxyz) = { [...] }; void __pie(platformxyz) xyz_ddr_on(void *addr) { [...] } EXPORT_PIE_SYMBOL(xyz_ddr_on); While the kernel can access exported symbols from the PIE, the PIE cannot access symbols from the kernel, but can access data from the kernel and call functions in the kernel so long as addresses are passed into the PIE. PIEs are loaded from the kernel into a genalloc pool with pie_load_sections. pie_load_sections allocates space within the pool, copies the neccesary code/data, and performs any necessary relocations. A chunk identifier is returned for removing the PIE from the pool, and for translating symbols. Because the PIEs are dynamically relocated, special accessors must be used to access PIE symbols from kernel code: - kern_to_pie(chunk, ptr): Translate a PIE symbol to the virtual address it is loaded into within the pool. - fn_to_pie(chunk, ptr): Same as above, but for function pointers. - sram_to_phys(chunk, addr): Translate a virtual address within a loaded PIE to a physical address. Loading a PIE involves three main steps. First a set of common functions to cover built-ins emitted by gcc (memcpy, memmove, etc) is copied into the pool. Then the actual PIE code and data is copied into the pool. Because the PIE code is contained within an overlay with other PIEs, offsets to the common functions are maintained. Finally, relocations are performed as necessary. Signed-off-by: Russ Dill --- Documentation/pie.txt | 167 Makefile | 17 +++- include/asm-generic/pie.lds.h | 82 include/asm-generic/vmlinux.lds.h | 1 + include/linux/pie.h | 196 ++ lib/Kconfig | 14 +++ lib/Makefile | 2 + lib/pie.c | 138 +++ pie/.gitignore| 3 + pie/Makefile | 85 + scripts/link-vmlinux.sh | 11 ++- 11 files changed, 711 insertions(+), 5 deletions(-) create mode 100644 Documentation/pie.txt create mode 100644 include/asm-generic/pie.lds.h create mode 100644 include/linux/pie.h create mode 100644 lib/pie.c create mode 100644 pie/.gitignore create mode 100644 pie/Makefile diff --git a/Documentation/pie.txt b/Documentation/pie.txt new file mode 100644 index 000..54a1646 --- /dev/null +++ b/Documentation/pie.txt @@ -0,0 +1,167 @@ +Position Independent Executables (PIEs) +=== + +About += + +The PIE framework is designed to allow normal C code from the kernel to be +embedded into the kernel, loaded at arbirary addresses, and executed. + +A PIE is a position independent executable is a piece of self contained code +that can be relocated to any address. Before the code is run, a simple list +of offset based relocations has to be performed. + +Copyright 2013 Texas Instruments, Inc + Russ Dill + +Motivation +== + +Without the PIE framework, the only way to support platforms that require +code loaded to and run from arbitrary addresses was to write the code in +assembly. For example, a platform may have suspend/resume steps that +disable/enable SDRAM and must be run from on chip SRAM. + +In addition to the SRAM virtual address not being known at compile time +for device tree platforms, the code must often run with the MMU enabled or +disabled (physical vs virtual address). + +Design +== + +The PIE code is separated into two main pieces. libpie satifies various +function calls emitted by gcc. The kernel contains only one copy of libpie +but whenever a PIE is loaded, a copy of libpie is copied along with the PIE +code. The second piece is the PIE code and data marked with special PIE +sections. At build time, libpie and the PIE sections are collected together +into a single PIE executable: + + +---+ + | __pie_common_start| + | | + | __pie_common_end | + +---+ + | __pie_overlay_start | + | +-+ | + | | __pie_groupxyz_start
[RFC PATCH 03/11] misc: SRAM: Add option to map SRAM to allow code execution
This is necessary for platforms that use SRAM to execute suspend/resume stubs. Signed-off-by: Russ Dill --- Documentation/devicetree/bindings/misc/sram.txt | 4 drivers/misc/sram.c | 13 - include/linux/platform_data/sram.h | 8 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 include/linux/platform_data/sram.h diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt index 4d0a00e..4fa9af3 100644 --- a/Documentation/devicetree/bindings/misc/sram.txt +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -8,6 +8,10 @@ Required properties: - reg : SRAM iomem address range +Optional properties: + +- map-exec: Map range to allow code execution + Example: sram: sram@5c00 { diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index d87cc91..baa5008 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -28,6 +28,7 @@ #include #include #include +#include #define SRAM_GRANULARITY 32 @@ -38,14 +39,24 @@ struct sram_dev { static int sram_probe(struct platform_device *pdev) { + struct sram_platform_data *pdata = pdev->dev.platform_data; void __iomem *virt_base; struct sram_dev *sram; struct resource *res; unsigned long size; + bool map_exec = false; int ret; + if (of_get_property(pdev->dev.of_node, "map-exec", NULL)) + map_exec = true; + if (pdata && pdata->map_exec) + map_exec |= true; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - virt_base = devm_ioremap_resource(>dev, res); + if (map_exec) + virt_base = devm_ioremap_exec_resource(>dev, res); + else + virt_base = devm_ioremap_resource(>dev, res); if (IS_ERR(virt_base)) return PTR_ERR(virt_base); diff --git a/include/linux/platform_data/sram.h b/include/linux/platform_data/sram.h new file mode 100644 index 000..8f5c4ba --- /dev/null +++ b/include/linux/platform_data/sram.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_SRAM_H +#define _LINUX_SRAM_H + +struct sram_platform_data { + bool map_exec; +}; + +#endif -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 02/11] lib: devres: Add exec versions of devm_ioremap_resource and friends
Now that there is an _exec version of ioremap, add devm support for it. Signed-off-by: Russ Dill --- include/linux/device.h | 17 - include/linux/io.h | 4 +++ lib/devres.c | 97 -- 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index 22b546a..204180a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -596,10 +596,25 @@ extern int devres_release_group(struct device *dev, void *id); extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); extern void devm_kfree(struct device *dev, void *p); -void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res, +bool exec); +static inline void __iomem *devm_ioremap_resource(struct device *dev, + struct resource *res) +{ + return __devm_ioremap_resource(dev, res, false); +} void __iomem *devm_request_and_ioremap(struct device *dev, struct resource *res); +static inline void __iomem *devm_ioremap_exec_resource(struct device *dev, + struct resource *res) +{ + return __devm_ioremap_resource(dev, res, true); +} + +void __iomem *devm_request_and_ioremap_exec(struct device *dev, + struct resource *res); + /* allows to add/remove a custom action to devres stack */ int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); diff --git a/include/linux/io.h b/include/linux/io.h index f4f42fa..582b207 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -62,6 +62,10 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, unsigned long size); void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, unsigned long size); +void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset, + unsigned long size); +void __iomem *devm_ioremap_exec_nocache(struct device *dev, resource_size_t offset, + unsigned long size); void devm_iounmap(struct device *dev, void __iomem *addr); int check_signature(const volatile void __iomem *io_addr, const unsigned char *signature, int length); diff --git a/lib/devres.c b/lib/devres.c index 8235331..06cafe5 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -72,6 +72,64 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, EXPORT_SYMBOL(devm_ioremap_nocache); /** + * devm_ioremap_exec - Managed ioremap_exec() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap_exec(). Map is automatically unmapped on driver detach. + */ +void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap_exec(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap_exec); + +/** + * devm_ioremap_exec_nocache - Managed ioremap_exec_nocache() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap_exec_nocache(). Map is automatically unmapped on driver + * detach. + */ +void __iomem *devm_ioremap_exec_nocache(struct device *dev, + resource_size_t offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap_exec_nocache(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap_exec_nocache); + +/** * devm_iounmap - Managed iounmap() * @dev: Generic device to unmap for * @addr: Address to unmap @@ -104,7 +162,8 @@ EXPORT_SYMBOL(devm_iounmap); * if (IS_ERR(base)) * return PTR_ERR(base); */ -void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res, + bool exec) { resource_size_t size; const
[RFC PATCH 01/11] asm-generic: io: Add exec versions of ioremap
If code is to be copied into and area (such as SRAM) and run, it needs to be marked as exec. Currently only an ARM version of this exists. Signed-off-by: Russ Dill --- arch/arm/include/asm/io.h | 2 ++ include/asm-generic/iomap.h | 5 + 2 files changed, 7 insertions(+) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index d070741..212d095 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -329,6 +329,8 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) #define ioremap_cached(cookie,size)__arm_ioremap((cookie), (size), MT_DEVICE_CACHED) #define ioremap_wc(cookie,size)__arm_ioremap((cookie), (size), MT_DEVICE_WC) +#define ioremap_exec(cookie,size) __arm_ioremap_exec((cookie), (size), true) +#define ioremap_exec_nocache(cookie,size) __arm_ioremap_exec((cookie), (size), false) #define iounmap__arm_iounmap /* diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index 6afd7d6..e72c451 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -66,6 +66,11 @@ extern void ioport_unmap(void __iomem *); #define ioremap_wc ioremap_nocache #endif +#ifndef ARCH_HAS_IOREMAP_EXEC +#define ioremap_exec ioremap +#define ioremap_exec_nocache ioremap_nocache +#endif + #ifdef CONFIG_PCI /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 04/11] asm-generic: fncpy: Add function copying macros
Under certain arches (ARM) function pointers cannot be used naively. Specifically, for thumb functions, their 0 bit is set, but they are contained on a word aligned address. Add a fncpy macro to perform function copies correctly along with two helpers, fnptr_to_address, and fnptr_translate. Signed-off-by: Russ Dill --- arch/alpha/include/asm/fncpy.h | 1 + arch/arc/include/asm/fncpy.h| 1 + arch/arm/include/asm/fncpy.h| 76 +++--- arch/arm/plat-omap/sram.c | 2 +- arch/arm64/include/asm/fncpy.h | 1 + arch/avr32/include/asm/fncpy.h | 1 + arch/blackfin/include/asm/fncpy.h | 1 + arch/c6x/include/asm/fncpy.h| 1 + arch/cris/include/asm/fncpy.h | 1 + arch/frv/include/asm/fncpy.h| 1 + arch/h8300/include/asm/fncpy.h | 1 + arch/hexagon/include/asm/fncpy.h| 1 + arch/ia64/include/asm/fncpy.h | 1 + arch/m32r/include/asm/fncpy.h | 1 + arch/m68k/include/asm/fncpy.h | 1 + arch/metag/include/asm/fncpy.h | 1 + arch/microblaze/include/asm/fncpy.h | 1 + arch/mips/include/asm/fncpy.h | 1 + arch/mn10300/include/asm/fncpy.h| 1 + arch/openrisc/include/asm/fncpy.h | 1 + arch/parisc/include/asm/fncpy.h | 1 + arch/powerpc/include/asm/fncpy.h| 1 + arch/s390/include/asm/fncpy.h | 1 + arch/score/include/asm/fncpy.h | 1 + arch/sh/include/asm/fncpy.h | 1 + arch/sparc/include/asm/fncpy.h | 1 + arch/tile/include/asm/fncpy.h | 1 + arch/um/include/asm/fncpy.h | 1 + arch/unicore32/include/asm/fncpy.h | 1 + arch/x86/include/asm/fncpy.h| 1 + arch/xtensa/include/asm/fncpy.h | 1 + include/asm-generic/fncpy.h | 104 32 files changed, 154 insertions(+), 57 deletions(-) create mode 100644 arch/alpha/include/asm/fncpy.h create mode 100644 arch/arc/include/asm/fncpy.h create mode 100644 arch/arm64/include/asm/fncpy.h create mode 100644 arch/avr32/include/asm/fncpy.h create mode 100644 arch/blackfin/include/asm/fncpy.h create mode 100644 arch/c6x/include/asm/fncpy.h create mode 100644 arch/cris/include/asm/fncpy.h create mode 100644 arch/frv/include/asm/fncpy.h create mode 100644 arch/h8300/include/asm/fncpy.h create mode 100644 arch/hexagon/include/asm/fncpy.h create mode 100644 arch/ia64/include/asm/fncpy.h create mode 100644 arch/m32r/include/asm/fncpy.h create mode 100644 arch/m68k/include/asm/fncpy.h create mode 100644 arch/metag/include/asm/fncpy.h create mode 100644 arch/microblaze/include/asm/fncpy.h create mode 100644 arch/mips/include/asm/fncpy.h create mode 100644 arch/mn10300/include/asm/fncpy.h create mode 100644 arch/openrisc/include/asm/fncpy.h create mode 100644 arch/parisc/include/asm/fncpy.h create mode 100644 arch/powerpc/include/asm/fncpy.h create mode 100644 arch/s390/include/asm/fncpy.h create mode 100644 arch/score/include/asm/fncpy.h create mode 100644 arch/sh/include/asm/fncpy.h create mode 100644 arch/sparc/include/asm/fncpy.h create mode 100644 arch/tile/include/asm/fncpy.h create mode 100644 arch/um/include/asm/fncpy.h create mode 100644 arch/unicore32/include/asm/fncpy.h create mode 100644 arch/x86/include/asm/fncpy.h create mode 100644 arch/xtensa/include/asm/fncpy.h create mode 100644 include/asm-generic/fncpy.h diff --git a/arch/alpha/include/asm/fncpy.h b/arch/alpha/include/asm/fncpy.h new file mode 100644 index 000..ee4741c --- /dev/null +++ b/arch/alpha/include/asm/fncpy.h @@ -0,0 +1 @@ +#include diff --git a/arch/arc/include/asm/fncpy.h b/arch/arc/include/asm/fncpy.h new file mode 100644 index 000..ee4741c --- /dev/null +++ b/arch/arc/include/asm/fncpy.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h index de53547..f165f20 100644 --- a/arch/arm/include/asm/fncpy.h +++ b/arch/arm/include/asm/fncpy.h @@ -17,16 +17,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __ASM_FNCPY_H +#define __ASM_FNCPY_H + +#include + /* - * These macros are intended for use when there is a need to copy a low-level - * function body into special memory. - * - * For example, when reconfiguring the SDRAM controller, the code doing the - * reconfiguration may need to run from SRAM. - * - * NOTE: that the copied function body must be entirely self-contained and - * position-independent in order for this to work properly. - * * NOTE: in order for embedded literals and data to get referenced correctly, * the alignment of functions must be preserved when copying. To ensure this, * the source and destination addresses for fncpy() must be aligned to a @@ -34,61 +30,29 @@ * You will typically need a ".align 3" directive in the assembler where the * function to be copied is defined, and ensure that your allocator for the * destination buffer returns 8-byte-aligne
[RFC PATCH 07/11] ARM: PIE: Add support for updating PIE relocations
This adds support for updating PIE relocations under ARM. This is necessary in the case that the same PIE must run both with virtual mapping (MMU enabled) and physical mapping (MMU disabled). Signed-off-by: Russ Dill --- arch/arm/include/asm/pie.h | 42 + arch/arm/kernel/pie.c | 9 ++ arch/arm/libpie/Makefile | 2 +- arch/arm/libpie/relocate.S | 76 ++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/pie.h create mode 100644 arch/arm/libpie/relocate.S diff --git a/arch/arm/include/asm/pie.h b/arch/arm/include/asm/pie.h new file mode 100644 index 000..977f11d --- /dev/null +++ b/arch/arm/include/asm/pie.h @@ -0,0 +1,42 @@ +/* + * arch/arm/include/asm/pie.h + * + * Copyright 2013 Texas Instruments, Inc + * Russ Dill + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ASMARM_PIE_H +#define _ASMARM_PIE_H + +#include + +#ifdef CONFIG_PIE +extern void __pie_relocate(void); +extern void __pie___pie_relocate(void); + +#define pie_relocate_from_pie() \ + __asm__ __volatile__("bl __pie_relocate\n" \ + : : : "cc", "memory", "lr", "r4", "r5", "r6", "r7", "r8", "r9"); + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ + void (*fn)(void) = fn_to_pie(chunk, &__pie___pie_relocate); + __asm__ __volatile__("" : : : "cc", "memory", "r4", "r5", "r6", + "r7", "r8", "r9"); + fn(); +} +#else + +#define pie_relocate_from_pie() do {} while(0) + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ +} + +#endif + +#endif diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c index 5dff5d6..598562f 100644 --- a/arch/arm/kernel/pie.c +++ b/arch/arm/kernel/pie.c @@ -12,10 +12,12 @@ #include #include +#include extern char __pie_rel_dyn_start[]; extern char __pie_rel_dyn_end[]; extern char __pie_tail_offset[]; +extern char __pie_reloc_offset[]; struct arm_pie_tail { int count; @@ -72,12 +74,19 @@ int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail, unsigned long offset) { struct arm_pie_tail *pie_tail = tail; + void *reloc; int i; /* Perform relocation fixups for given offset */ for (i = 0; i < pie_tail->count; i++) *((uintptr_t *) (pie_tail->offset[i] + base)) += offset; + /* Store the PIE offset to tail and recol func */ + *kern_to_pie(chunk, (uintptr_t *) __pie_tail_offset) = tail - base; + reloc = kern_to_pie(chunk, + (void *) fnptr_to_addr(&__pie___pie_relocate)); + *kern_to_pie(chunk, (uintptr_t *) __pie_reloc_offset) = reloc - base; + return 0; } EXPORT_SYMBOL_GPL(pie_arch_fixup); diff --git a/arch/arm/libpie/Makefile b/arch/arm/libpie/Makefile index 5662e99..b1ac52a 100644 --- a/arch/arm/libpie/Makefile +++ b/arch/arm/libpie/Makefile @@ -3,7 +3,7 @@ # ccflags-y := -fpic -mno-single-pic-base -fno-builtin -obj-y := empty.o +obj-y := relocate.o empty.o obj-y += lib1funcs.o ashldi3.o string.o # string library code (-Os is enforced to keep it much smaller) diff --git a/arch/arm/libpie/relocate.S b/arch/arm/libpie/relocate.S new file mode 100644 index 000..70cc36e --- /dev/null +++ b/arch/arm/libpie/relocate.S @@ -0,0 +1,76 @@ +/* + * arch/arm/libpie/relocate.S - Relocation updating for PIEs + * + * Copyright 2013 Texas Instruments, Inc. + * Russ Dill + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include + +/* + * Update relocations based on current pc + * + * On exit: + * r4-r9 corrupted + */ + +ENTRY(__pie_relocate) + /* Calculate offset of our code compared to existing relocations */ + ldr r4, pie_relocate_address + adr r5, __pie_relocate + subsr6, r5, r4 + moveq pc, lr /* 0 offset, no need to do anything */ + + /* Base of PIE group */ + ldr r7, reloc_offset + sub r5, r5, r7 + + /* Calculate address of tail */ + ldr r7, tail_offset + add r7, r7, r5 + + /* First byte of tail is number of entries */ + ldr r8, [r7], #4 + add r8, r7, r8, lsl #2 + + /* +* r5 - current base address of PIE
[RFC PATCH 09/11] ARM: dts: AM33XX: Associate SRAM with MPU and mark it exec
The SRAM is for use by the MPU. Marking it as such makes it easier for PM initialization code to locate the SRAM in order to load a PIE section into it. Additionally, set the map-exec flag to allow code to be run from SRAM. This is necessary for suspend/resume. Signed-off-by: Russ Dill --- arch/arm/boot/dts/am33xx.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 302463d..20942a2 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -62,6 +62,7 @@ mpu { compatible = "ti,omap3-mpu"; ti,hwmods = "mpu"; + sram = <>; }; }; @@ -507,6 +508,7 @@ ocmcram: ocmcram@4030 { compatible = "mmio-sram"; reg = <0x4030 0x1>; /* 64k */ + map-exec; }; wkup_m3: wkup_m3@44d0 { -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 06/11] ARM: PIE: Add position independent executable embedding to ARM
Add support to ARM for embedding PIEs into the kernel, loading them into genalloc pools (such as SRAM) and executing them. Support for ARM means performing R_ARM_RELATIVE fixups within the .rel.dyn section. Signed-off-by: Russ Dill --- arch/arm/Kconfig | 1 + arch/arm/Makefile | 5 +++ arch/arm/include/asm/elf.h| 1 + arch/arm/kernel/.gitignore| 1 + arch/arm/kernel/Makefile | 4 ++- arch/arm/kernel/pie.c | 83 +++ arch/arm/kernel/pie.lds.S | 40 + arch/arm/kernel/vmlinux.lds.S | 2 ++ arch/arm/libpie/.gitignore| 3 ++ arch/arm/libpie/Makefile | 32 + arch/arm/libpie/empty.S | 12 +++ 11 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 arch/arm/kernel/pie.c create mode 100644 arch/arm/kernel/pie.lds.S create mode 100644 arch/arm/libpie/.gitignore create mode 100644 arch/arm/libpie/Makefile create mode 100644 arch/arm/libpie/empty.S diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43594d5..de7b7603 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -49,6 +49,7 @@ config ARM select HAVE_MEMBLOCK select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PIE select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6fd2cea..a673d36 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -128,6 +128,8 @@ KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/uni CHECKFLAGS += -D__arm__ +OBJCOPY_OUTPUT_FORMAT := elf32-littlearm + #Default value head-y := arch/arm/kernel/head$(MMUEXT).o textofs-y := 0x8000 @@ -273,6 +275,9 @@ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ libs-y := arch/arm/lib/ $(libs-y) +PIE_LDS:= arch/arm/kernel/pie.lds +libpie-$(CONFIG_PIE) += arch/arm/libpie/ + # Default target when executing plain make ifeq ($(CONFIG_XIP_KERNEL),y) KBUILD_IMAGE := xipImage diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 56211f2..a8d036b 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS322 +#define R_ARM_RELATIVE 23 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_V4BX 40 diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore index c5f676c..a055a48 100644 --- a/arch/arm/kernel/.gitignore +++ b/arch/arm/kernel/.gitignore @@ -1 +1,2 @@ vmlinux.lds +pie.lds diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 86d10dd..652312e 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -96,4 +96,6 @@ obj-y += psci.o obj-$(CONFIG_SMP) += psci_smp.o endif -extra-y := $(head-y) vmlinux.lds +obj-$(CONFIG_PIE) += pie.o + +extra-y := $(head-y) vmlinux.lds pie.lds diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c new file mode 100644 index 000..5dff5d6 --- /dev/null +++ b/arch/arm/kernel/pie.c @@ -0,0 +1,83 @@ +/* + * Copyright 2013 Texas Instruments, Inc. + * Russ Dill + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include + +#include + +extern char __pie_rel_dyn_start[]; +extern char __pie_rel_dyn_end[]; +extern char __pie_tail_offset[]; + +struct arm_pie_tail { + int count; + uintptr_t offset[0]; +}; + +int pie_arch_fill_tail(void *tail, void *common_start, void *common_end, + void *overlay_start, void *code_start, void *code_end) +{ + Elf32_Rel *rel; + int records; + int i; + struct arm_pie_tail *pie_tail = tail; + int count; + + rel = (Elf32_Rel *) __pie_rel_dyn_start; + records = (__pie_rel_dyn_end - __pie_rel_dyn_start) / + sizeof(*rel); + + count = 0; + for (i = 0; i < records; i++, rel++) { + void *kern_off; + if (ELF32_R_TYPE(rel->r_info) != R_ARM_RELATIVE) + return -ENOEXEC; + + /* Adjust offset to match area in kernel */ + kern_off = common_start + rel->r_offset; + + if (kern_off >= common_start && kern_off < code_end) { + if (tail) + pie_tail->offset[count] = rel->r_offset; + count++; + } else if (kern_off >= c
[RFC PATCH 11/11] ARM: OMAP2+: AM33XX: Basic suspend resume support
From: Vaibhav Bedia AM335x supports various low power modes as documented in section 8.1.4.3 of the AM335x TRM which is available @ http://www.ti.com/litv/pdf/spruh73f DeepSleep0 mode offers the lowest power mode with limited wakeup sources without a system reboot and is mapped as the suspend state in the kernel. In this state, MPU and PER domains are turned off with the internal RAM held in retention to facilitate resume process. As part of the boot process, the assembly code is copied over to OCMCRAM using the OMAP SRAM code. AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU in DeepSleep0 entry and exit. WKUP_M3 takes care of the clockdomain and powerdomain transitions based on the intended low power state. MPU needs to load the appropriate WKUP_M3 binary onto the WKUP_M3 memory space before it can leverage any of the PM features like DeepSleep. The IPC mechanism between MPU and WKUP_M3 uses a mailbox sub-module and 8 IPC registers in the Control module. MPU uses the assigned Mailbox for issuing an interrupt to WKUP_M3 which then goes and checks the IPC registers for the payload. WKUP_M3 has the ability to trigger on interrupt to MPU by executing the "sev" instruction. In the current implementation when the suspend process is initiated MPU interrupts the WKUP_M3 to let it know about the intent of entering DeepSleep0 and waits for an ACK. When the ACK is received MPU continues with its suspend process to suspend all the drivers and then jumps to assembly in OCMC RAM. The assembly code puts the PLLs in bypass, puts the external RAM in self-refresh mode and then finally execute the WFI instruction. Execution of the WFI instruction triggers another interrupt to the WKUP_M3 which then continues wiht the power down sequence wherein the clockdomain and powerdomain transition takes place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt lines for the wakeup sources. WFI execution on WKUP_M3 causes the hardware to disable the main oscillator of the SoC. When a wakeup event occurs, WKUP_M3 starts the power-up sequence by switching on the power domains and finally enabling the clock to MPU. Since the MPU gets powered down as part of the sleep sequence in the resume path ROM code starts executing. The ROM code detects a wakeup from sleep and then jumps to the resume location in OCMC which was populated in one of the IPC registers as part of the suspend sequence. The low level code in OCMC relocks the PLLs, enables access to external RAM and then jumps to the cpu_resume code of the kernel to finish the resume process. Signed-off-by: Vaibhav Bedia Signed-off-by: Dave Gerlach Signed-off-by: Russ Dill Cc: Tony Lingren Cc: Santosh Shilimkar Cc: Benoit Cousson Cc: Paul Walmsley Cc: Kevin Hilman --- arch/arm/mach-omap2/Kconfig | 7 +- arch/arm/mach-omap2/Makefile| 2 + arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h| 10 + arch/arm/mach-omap2/io.c| 5 + arch/arm/mach-omap2/pm.c| 3 +- arch/arm/mach-omap2/pm33xx.c| 486 arch/arm/mach-omap2/pm33xx.h| 68 + arch/arm/mach-omap2/sleep33xx.c | 314 +++ arch/arm/mach-omap2/wkup_m3.c | 183 ++ 10 files changed, 1076 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-omap2/pm33xx.c create mode 100644 arch/arm/mach-omap2/pm33xx.h create mode 100644 arch/arm/mach-omap2/sleep33xx.c create mode 100644 arch/arm/mach-omap2/wkup_m3.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 3eed000..ef3fe40 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -67,11 +67,14 @@ config SOC_OMAP5 config SOC_AM33XX bool "AM33XX support" depends on ARCH_MULTI_V7 - select ARCH_OMAP2PLUS + default y select ARM_CPU_SUSPEND if PM + select COMMON_CLK select CPU_V7 + select MAILBOX if PM select MULTI_IRQ_HANDLER - select COMMON_CLK + select OMAP_MBOX_FWK if PM + select OMAP2PLUS_MBOX if PM config SOC_AM43XX bool "TI AM43x" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d4f6715..42442c4 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o obj-$(CONFIG_SOC_OMAP5)+= omap-mpuss-lowpower.o +obj-$(CONFIG_SOC_AM33XX) += pm33xx.o sleep33xx.o wkup_m3.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o @@ -94,6 +95,7 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3)+= smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-m
[RFC PATCH 08/11] ARM: PIE: Add macro for generating PIE resume trampoline
Add a helper that generates a short snippet of code that updates PIE relocations, loads the stack pointer and calls a C (or asm) function. The code gets placed into a PIE section. Signed-off-by: Russ Dill --- arch/arm/include/asm/suspend.h | 25 + 1 file changed, 25 insertions(+) diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index cd20029..92996f0 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARM_SUSPEND_H #define __ASM_ARM_SUSPEND_H +#include + struct sleep_save_sp { u32 *save_ptr_stash; u32 save_ptr_stash_phys; @@ -9,4 +11,27 @@ struct sleep_save_sp { extern void cpu_resume(void); extern int cpu_suspend(unsigned long, int (*)(unsigned long)); +/** + * ARM_PIE_RESUME - generate a PIE trampoline for resume + * @proc: SoC, should match argument used with PIE_OVERLAY_SECTION() + * @func: C or asm function to call at resume + * @stack: stack to use before calling func + */ +#define ARM_PIE_RESUME(proc, func, stack) \ +static void __naked __noreturn __pie(proc) proc##_resume_trampoline2(void) \ +{ \ + __asm__ __volatile__( \ + " mov sp, %0\n" \ + : : "r"((stack)) : "sp"); \ + \ + func(); \ +} \ + \ +void __naked __noreturn __pie(proc) proc##_resume_trampoline(void) \ +{ \ + pie_relocate_from_pie();\ + proc##_resume_trampoline2();\ +} \ +EXPORT_PIE_SYMBOL(proc##_resume_trampoline) + #endif -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 10/11] ARM: OMAP2+: AM33XX: Add PIE support for AM33XX
This enables CONFIG_PIE for omap2plus_defconfig and adds an am33xx PIE section group. This is necessary for am33xx suspend/resume code as it is written in C. Signed-off-by: Russ Dill --- arch/arm/configs/omap2plus_defconfig | 1 + arch/arm/kernel/pie.lds.S| 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 5d4c9b8..f342f85 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -102,6 +102,7 @@ CONFIG_SENSORS_TSL2550=m CONFIG_SENSORS_LIS3_I2C=m CONFIG_BMP085_I2C=m CONFIG_SRAM=y +CONFIG_PIE=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y diff --git a/arch/arm/kernel/pie.lds.S b/arch/arm/kernel/pie.lds.S index 4fd5ac5..92fba61 100644 --- a/arch/arm/kernel/pie.lds.S +++ b/arch/arm/kernel/pie.lds.S @@ -23,6 +23,7 @@ SECTIONS PIE_OVERLAY_START OVERLAY : NOCROSSREFS { + PIE_OVERLAY_SECTION(am33xx) } PIE_OVERLAY_SEND -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 10/11] ARM: OMAP2+: AM33XX: Add PIE support for AM33XX
This enables CONFIG_PIE for omap2plus_defconfig and adds an am33xx PIE section group. This is necessary for am33xx suspend/resume code as it is written in C. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/configs/omap2plus_defconfig | 1 + arch/arm/kernel/pie.lds.S| 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 5d4c9b8..f342f85 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -102,6 +102,7 @@ CONFIG_SENSORS_TSL2550=m CONFIG_SENSORS_LIS3_I2C=m CONFIG_BMP085_I2C=m CONFIG_SRAM=y +CONFIG_PIE=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y diff --git a/arch/arm/kernel/pie.lds.S b/arch/arm/kernel/pie.lds.S index 4fd5ac5..92fba61 100644 --- a/arch/arm/kernel/pie.lds.S +++ b/arch/arm/kernel/pie.lds.S @@ -23,6 +23,7 @@ SECTIONS PIE_OVERLAY_START OVERLAY : NOCROSSREFS { + PIE_OVERLAY_SECTION(am33xx) } PIE_OVERLAY_SEND -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 08/11] ARM: PIE: Add macro for generating PIE resume trampoline
Add a helper that generates a short snippet of code that updates PIE relocations, loads the stack pointer and calls a C (or asm) function. The code gets placed into a PIE section. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/include/asm/suspend.h | 25 + 1 file changed, 25 insertions(+) diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index cd20029..92996f0 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,6 +1,8 @@ #ifndef __ASM_ARM_SUSPEND_H #define __ASM_ARM_SUSPEND_H +#include asm/pie.h + struct sleep_save_sp { u32 *save_ptr_stash; u32 save_ptr_stash_phys; @@ -9,4 +11,27 @@ struct sleep_save_sp { extern void cpu_resume(void); extern int cpu_suspend(unsigned long, int (*)(unsigned long)); +/** + * ARM_PIE_RESUME - generate a PIE trampoline for resume + * @proc: SoC, should match argument used with PIE_OVERLAY_SECTION() + * @func: C or asm function to call at resume + * @stack: stack to use before calling func + */ +#define ARM_PIE_RESUME(proc, func, stack) \ +static void __naked __noreturn __pie(proc) proc##_resume_trampoline2(void) \ +{ \ + __asm__ __volatile__( \ + mov sp, %0\n \ + : : r((stack)) : sp); \ + \ + func(); \ +} \ + \ +void __naked __noreturn __pie(proc) proc##_resume_trampoline(void) \ +{ \ + pie_relocate_from_pie();\ + proc##_resume_trampoline2();\ +} \ +EXPORT_PIE_SYMBOL(proc##_resume_trampoline) + #endif -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 11/11] ARM: OMAP2+: AM33XX: Basic suspend resume support
From: Vaibhav Bedia vaibhav.be...@ti.com AM335x supports various low power modes as documented in section 8.1.4.3 of the AM335x TRM which is available @ http://www.ti.com/litv/pdf/spruh73f DeepSleep0 mode offers the lowest power mode with limited wakeup sources without a system reboot and is mapped as the suspend state in the kernel. In this state, MPU and PER domains are turned off with the internal RAM held in retention to facilitate resume process. As part of the boot process, the assembly code is copied over to OCMCRAM using the OMAP SRAM code. AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU in DeepSleep0 entry and exit. WKUP_M3 takes care of the clockdomain and powerdomain transitions based on the intended low power state. MPU needs to load the appropriate WKUP_M3 binary onto the WKUP_M3 memory space before it can leverage any of the PM features like DeepSleep. The IPC mechanism between MPU and WKUP_M3 uses a mailbox sub-module and 8 IPC registers in the Control module. MPU uses the assigned Mailbox for issuing an interrupt to WKUP_M3 which then goes and checks the IPC registers for the payload. WKUP_M3 has the ability to trigger on interrupt to MPU by executing the sev instruction. In the current implementation when the suspend process is initiated MPU interrupts the WKUP_M3 to let it know about the intent of entering DeepSleep0 and waits for an ACK. When the ACK is received MPU continues with its suspend process to suspend all the drivers and then jumps to assembly in OCMC RAM. The assembly code puts the PLLs in bypass, puts the external RAM in self-refresh mode and then finally execute the WFI instruction. Execution of the WFI instruction triggers another interrupt to the WKUP_M3 which then continues wiht the power down sequence wherein the clockdomain and powerdomain transition takes place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt lines for the wakeup sources. WFI execution on WKUP_M3 causes the hardware to disable the main oscillator of the SoC. When a wakeup event occurs, WKUP_M3 starts the power-up sequence by switching on the power domains and finally enabling the clock to MPU. Since the MPU gets powered down as part of the sleep sequence in the resume path ROM code starts executing. The ROM code detects a wakeup from sleep and then jumps to the resume location in OCMC which was populated in one of the IPC registers as part of the suspend sequence. The low level code in OCMC relocks the PLLs, enables access to external RAM and then jumps to the cpu_resume code of the kernel to finish the resume process. Signed-off-by: Vaibhav Bedia vaibhav.be...@ti.com Signed-off-by: Dave Gerlach d-gerl...@ti.com Signed-off-by: Russ Dill russ.d...@ti.com Cc: Tony Lingren t...@atomide.com Cc: Santosh Shilimkar santosh.shilim...@ti.com Cc: Benoit Cousson benoit.cous...@linaro.org Cc: Paul Walmsley p...@pwsan.com Cc: Kevin Hilman khil...@linaro.org --- arch/arm/mach-omap2/Kconfig | 7 +- arch/arm/mach-omap2/Makefile| 2 + arch/arm/mach-omap2/board-generic.c | 1 + arch/arm/mach-omap2/common.h| 10 + arch/arm/mach-omap2/io.c| 5 + arch/arm/mach-omap2/pm.c| 3 +- arch/arm/mach-omap2/pm33xx.c| 486 arch/arm/mach-omap2/pm33xx.h| 68 + arch/arm/mach-omap2/sleep33xx.c | 314 +++ arch/arm/mach-omap2/wkup_m3.c | 183 ++ 10 files changed, 1076 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-omap2/pm33xx.c create mode 100644 arch/arm/mach-omap2/pm33xx.h create mode 100644 arch/arm/mach-omap2/sleep33xx.c create mode 100644 arch/arm/mach-omap2/wkup_m3.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 3eed000..ef3fe40 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -67,11 +67,14 @@ config SOC_OMAP5 config SOC_AM33XX bool AM33XX support depends on ARCH_MULTI_V7 - select ARCH_OMAP2PLUS + default y select ARM_CPU_SUSPEND if PM + select COMMON_CLK select CPU_V7 + select MAILBOX if PM select MULTI_IRQ_HANDLER - select COMMON_CLK + select OMAP_MBOX_FWK if PM + select OMAP2PLUS_MBOX if PM config SOC_AM43XX bool TI AM43x diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d4f6715..42442c4 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o obj-$(CONFIG_SOC_OMAP5)+= omap-mpuss-lowpower.o +obj-$(CONFIG_SOC_AM33XX) += pm33xx.o sleep33xx.o wkup_m3.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o @@ -94,6 +95,7 @@ obj
[RFC PATCH 06/11] ARM: PIE: Add position independent executable embedding to ARM
Add support to ARM for embedding PIEs into the kernel, loading them into genalloc pools (such as SRAM) and executing them. Support for ARM means performing R_ARM_RELATIVE fixups within the .rel.dyn section. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/Kconfig | 1 + arch/arm/Makefile | 5 +++ arch/arm/include/asm/elf.h| 1 + arch/arm/kernel/.gitignore| 1 + arch/arm/kernel/Makefile | 4 ++- arch/arm/kernel/pie.c | 83 +++ arch/arm/kernel/pie.lds.S | 40 + arch/arm/kernel/vmlinux.lds.S | 2 ++ arch/arm/libpie/.gitignore| 3 ++ arch/arm/libpie/Makefile | 32 + arch/arm/libpie/empty.S | 12 +++ 11 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 arch/arm/kernel/pie.c create mode 100644 arch/arm/kernel/pie.lds.S create mode 100644 arch/arm/libpie/.gitignore create mode 100644 arch/arm/libpie/Makefile create mode 100644 arch/arm/libpie/empty.S diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43594d5..de7b7603 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -49,6 +49,7 @@ config ARM select HAVE_MEMBLOCK select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PIE select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6fd2cea..a673d36 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -128,6 +128,8 @@ KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/uni CHECKFLAGS += -D__arm__ +OBJCOPY_OUTPUT_FORMAT := elf32-littlearm + #Default value head-y := arch/arm/kernel/head$(MMUEXT).o textofs-y := 0x8000 @@ -273,6 +275,9 @@ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ libs-y := arch/arm/lib/ $(libs-y) +PIE_LDS:= arch/arm/kernel/pie.lds +libpie-$(CONFIG_PIE) += arch/arm/libpie/ + # Default target when executing plain make ifeq ($(CONFIG_XIP_KERNEL),y) KBUILD_IMAGE := xipImage diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 56211f2..a8d036b 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS322 +#define R_ARM_RELATIVE 23 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_V4BX 40 diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore index c5f676c..a055a48 100644 --- a/arch/arm/kernel/.gitignore +++ b/arch/arm/kernel/.gitignore @@ -1 +1,2 @@ vmlinux.lds +pie.lds diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 86d10dd..652312e 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -96,4 +96,6 @@ obj-y += psci.o obj-$(CONFIG_SMP) += psci_smp.o endif -extra-y := $(head-y) vmlinux.lds +obj-$(CONFIG_PIE) += pie.o + +extra-y := $(head-y) vmlinux.lds pie.lds diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c new file mode 100644 index 000..5dff5d6 --- /dev/null +++ b/arch/arm/kernel/pie.c @@ -0,0 +1,83 @@ +/* + * Copyright 2013 Texas Instruments, Inc. + * Russ Dill russ.d...@ti.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/pie.h +#include linux/elf.h + +#include asm/elf.h + +extern char __pie_rel_dyn_start[]; +extern char __pie_rel_dyn_end[]; +extern char __pie_tail_offset[]; + +struct arm_pie_tail { + int count; + uintptr_t offset[0]; +}; + +int pie_arch_fill_tail(void *tail, void *common_start, void *common_end, + void *overlay_start, void *code_start, void *code_end) +{ + Elf32_Rel *rel; + int records; + int i; + struct arm_pie_tail *pie_tail = tail; + int count; + + rel = (Elf32_Rel *) __pie_rel_dyn_start; + records = (__pie_rel_dyn_end - __pie_rel_dyn_start) / + sizeof(*rel); + + count = 0; + for (i = 0; i records; i++, rel++) { + void *kern_off; + if (ELF32_R_TYPE(rel-r_info) != R_ARM_RELATIVE) + return -ENOEXEC; + + /* Adjust offset to match area in kernel */ + kern_off = common_start + rel-r_offset; + + if (kern_off = common_start kern_off code_end) { + if (tail) + pie_tail-offset[count] = rel-r_offset; + count
[RFC PATCH 09/11] ARM: dts: AM33XX: Associate SRAM with MPU and mark it exec
The SRAM is for use by the MPU. Marking it as such makes it easier for PM initialization code to locate the SRAM in order to load a PIE section into it. Additionally, set the map-exec flag to allow code to be run from SRAM. This is necessary for suspend/resume. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 302463d..20942a2 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -62,6 +62,7 @@ mpu { compatible = ti,omap3-mpu; ti,hwmods = mpu; + sram = ocmcram; }; }; @@ -507,6 +508,7 @@ ocmcram: ocmcram@4030 { compatible = mmio-sram; reg = 0x4030 0x1; /* 64k */ + map-exec; }; wkup_m3: wkup_m3@44d0 { -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 07/11] ARM: PIE: Add support for updating PIE relocations
This adds support for updating PIE relocations under ARM. This is necessary in the case that the same PIE must run both with virtual mapping (MMU enabled) and physical mapping (MMU disabled). Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/include/asm/pie.h | 42 + arch/arm/kernel/pie.c | 9 ++ arch/arm/libpie/Makefile | 2 +- arch/arm/libpie/relocate.S | 76 ++ 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/pie.h create mode 100644 arch/arm/libpie/relocate.S diff --git a/arch/arm/include/asm/pie.h b/arch/arm/include/asm/pie.h new file mode 100644 index 000..977f11d --- /dev/null +++ b/arch/arm/include/asm/pie.h @@ -0,0 +1,42 @@ +/* + * arch/arm/include/asm/pie.h + * + * Copyright 2013 Texas Instruments, Inc + * Russ Dill russ.d...@ti.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _ASMARM_PIE_H +#define _ASMARM_PIE_H + +#include linux/pie.h + +#ifdef CONFIG_PIE +extern void __pie_relocate(void); +extern void __pie___pie_relocate(void); + +#define pie_relocate_from_pie() \ + __asm__ __volatile__(bl __pie_relocate\n \ + : : : cc, memory, lr, r4, r5, r6, r7, r8, r9); + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ + void (*fn)(void) = fn_to_pie(chunk, __pie___pie_relocate); + __asm__ __volatile__( : : : cc, memory, r4, r5, r6, + r7, r8, r9); + fn(); +} +#else + +#define pie_relocate_from_pie() do {} while(0) + +static inline void pie_relocate_from_kern(struct pie_chunk *chunk) +{ +} + +#endif + +#endif diff --git a/arch/arm/kernel/pie.c b/arch/arm/kernel/pie.c index 5dff5d6..598562f 100644 --- a/arch/arm/kernel/pie.c +++ b/arch/arm/kernel/pie.c @@ -12,10 +12,12 @@ #include linux/elf.h #include asm/elf.h +#include asm/pie.h extern char __pie_rel_dyn_start[]; extern char __pie_rel_dyn_end[]; extern char __pie_tail_offset[]; +extern char __pie_reloc_offset[]; struct arm_pie_tail { int count; @@ -72,12 +74,19 @@ int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail, unsigned long offset) { struct arm_pie_tail *pie_tail = tail; + void *reloc; int i; /* Perform relocation fixups for given offset */ for (i = 0; i pie_tail-count; i++) *((uintptr_t *) (pie_tail-offset[i] + base)) += offset; + /* Store the PIE offset to tail and recol func */ + *kern_to_pie(chunk, (uintptr_t *) __pie_tail_offset) = tail - base; + reloc = kern_to_pie(chunk, + (void *) fnptr_to_addr(__pie___pie_relocate)); + *kern_to_pie(chunk, (uintptr_t *) __pie_reloc_offset) = reloc - base; + return 0; } EXPORT_SYMBOL_GPL(pie_arch_fixup); diff --git a/arch/arm/libpie/Makefile b/arch/arm/libpie/Makefile index 5662e99..b1ac52a 100644 --- a/arch/arm/libpie/Makefile +++ b/arch/arm/libpie/Makefile @@ -3,7 +3,7 @@ # ccflags-y := -fpic -mno-single-pic-base -fno-builtin -obj-y := empty.o +obj-y := relocate.o empty.o obj-y += lib1funcs.o ashldi3.o string.o # string library code (-Os is enforced to keep it much smaller) diff --git a/arch/arm/libpie/relocate.S b/arch/arm/libpie/relocate.S new file mode 100644 index 000..70cc36e --- /dev/null +++ b/arch/arm/libpie/relocate.S @@ -0,0 +1,76 @@ +/* + * arch/arm/libpie/relocate.S - Relocation updating for PIEs + * + * Copyright 2013 Texas Instruments, Inc. + * Russ Dill russ.d...@ti.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include linux/linkage.h + +/* + * Update relocations based on current pc + * + * On exit: + * r4-r9 corrupted + */ + +ENTRY(__pie_relocate) + /* Calculate offset of our code compared to existing relocations */ + ldr r4, pie_relocate_address + adr r5, __pie_relocate + subsr6, r5, r4 + moveq pc, lr /* 0 offset, no need to do anything */ + + /* Base of PIE group */ + ldr r7, reloc_offset + sub r5, r5, r7 + + /* Calculate address of tail */ + ldr r7, tail_offset + add r7, r7, r5 + + /* First byte of tail is number of entries */ + ldr r8, [r7], #4 + add r8, r7, r8, lsl #2 + + /* +* r5 - current base address of PIE group +* r6 - fixup offset needed for relocs +* r7 - relocs start +* r8 - relocs end +*/ + +1: + cmp r7, r8
[RFC PATCH 02/11] lib: devres: Add exec versions of devm_ioremap_resource and friends
Now that there is an _exec version of ioremap, add devm support for it. Signed-off-by: Russ Dill russ.d...@ti.com --- include/linux/device.h | 17 - include/linux/io.h | 4 +++ lib/devres.c | 97 -- 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index 22b546a..204180a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -596,10 +596,25 @@ extern int devres_release_group(struct device *dev, void *id); extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); extern void devm_kfree(struct device *dev, void *p); -void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res, +bool exec); +static inline void __iomem *devm_ioremap_resource(struct device *dev, + struct resource *res) +{ + return __devm_ioremap_resource(dev, res, false); +} void __iomem *devm_request_and_ioremap(struct device *dev, struct resource *res); +static inline void __iomem *devm_ioremap_exec_resource(struct device *dev, + struct resource *res) +{ + return __devm_ioremap_resource(dev, res, true); +} + +void __iomem *devm_request_and_ioremap_exec(struct device *dev, + struct resource *res); + /* allows to add/remove a custom action to devres stack */ int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); diff --git a/include/linux/io.h b/include/linux/io.h index f4f42fa..582b207 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -62,6 +62,10 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, unsigned long size); void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, unsigned long size); +void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset, + unsigned long size); +void __iomem *devm_ioremap_exec_nocache(struct device *dev, resource_size_t offset, + unsigned long size); void devm_iounmap(struct device *dev, void __iomem *addr); int check_signature(const volatile void __iomem *io_addr, const unsigned char *signature, int length); diff --git a/lib/devres.c b/lib/devres.c index 8235331..06cafe5 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -72,6 +72,64 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, EXPORT_SYMBOL(devm_ioremap_nocache); /** + * devm_ioremap_exec - Managed ioremap_exec() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap_exec(). Map is automatically unmapped on driver detach. + */ +void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap_exec(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap_exec); + +/** + * devm_ioremap_exec_nocache - Managed ioremap_exec_nocache() + * @dev: Generic device to remap IO address for + * @offset: BUS offset to map + * @size: Size of map + * + * Managed ioremap_exec_nocache(). Map is automatically unmapped on driver + * detach. + */ +void __iomem *devm_ioremap_exec_nocache(struct device *dev, + resource_size_t offset, + unsigned long size) +{ + void __iomem **ptr, *addr; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + addr = ioremap_exec_nocache(offset, size); + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} +EXPORT_SYMBOL(devm_ioremap_exec_nocache); + +/** * devm_iounmap - Managed iounmap() * @dev: Generic device to unmap for * @addr: Address to unmap @@ -104,7 +162,8 @@ EXPORT_SYMBOL(devm_iounmap); * if (IS_ERR(base)) * return PTR_ERR(base); */ -void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) +void __iomem *__devm_ioremap_resource(struct device *dev, struct resource *res, + bool exec) { resource_size_t
[RFC PATCH 01/11] asm-generic: io: Add exec versions of ioremap
If code is to be copied into and area (such as SRAM) and run, it needs to be marked as exec. Currently only an ARM version of this exists. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/arm/include/asm/io.h | 2 ++ include/asm-generic/iomap.h | 5 + 2 files changed, 7 insertions(+) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index d070741..212d095 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -329,6 +329,8 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) #define ioremap_cached(cookie,size)__arm_ioremap((cookie), (size), MT_DEVICE_CACHED) #define ioremap_wc(cookie,size)__arm_ioremap((cookie), (size), MT_DEVICE_WC) +#define ioremap_exec(cookie,size) __arm_ioremap_exec((cookie), (size), true) +#define ioremap_exec_nocache(cookie,size) __arm_ioremap_exec((cookie), (size), false) #define iounmap__arm_iounmap /* diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index 6afd7d6..e72c451 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -66,6 +66,11 @@ extern void ioport_unmap(void __iomem *); #define ioremap_wc ioremap_nocache #endif +#ifndef ARCH_HAS_IOREMAP_EXEC +#define ioremap_exec ioremap +#define ioremap_exec_nocache ioremap_nocache +#endif + #ifdef CONFIG_PCI /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev; -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 04/11] asm-generic: fncpy: Add function copying macros
Under certain arches (ARM) function pointers cannot be used naively. Specifically, for thumb functions, their 0 bit is set, but they are contained on a word aligned address. Add a fncpy macro to perform function copies correctly along with two helpers, fnptr_to_address, and fnptr_translate. Signed-off-by: Russ Dill russ.d...@ti.com --- arch/alpha/include/asm/fncpy.h | 1 + arch/arc/include/asm/fncpy.h| 1 + arch/arm/include/asm/fncpy.h| 76 +++--- arch/arm/plat-omap/sram.c | 2 +- arch/arm64/include/asm/fncpy.h | 1 + arch/avr32/include/asm/fncpy.h | 1 + arch/blackfin/include/asm/fncpy.h | 1 + arch/c6x/include/asm/fncpy.h| 1 + arch/cris/include/asm/fncpy.h | 1 + arch/frv/include/asm/fncpy.h| 1 + arch/h8300/include/asm/fncpy.h | 1 + arch/hexagon/include/asm/fncpy.h| 1 + arch/ia64/include/asm/fncpy.h | 1 + arch/m32r/include/asm/fncpy.h | 1 + arch/m68k/include/asm/fncpy.h | 1 + arch/metag/include/asm/fncpy.h | 1 + arch/microblaze/include/asm/fncpy.h | 1 + arch/mips/include/asm/fncpy.h | 1 + arch/mn10300/include/asm/fncpy.h| 1 + arch/openrisc/include/asm/fncpy.h | 1 + arch/parisc/include/asm/fncpy.h | 1 + arch/powerpc/include/asm/fncpy.h| 1 + arch/s390/include/asm/fncpy.h | 1 + arch/score/include/asm/fncpy.h | 1 + arch/sh/include/asm/fncpy.h | 1 + arch/sparc/include/asm/fncpy.h | 1 + arch/tile/include/asm/fncpy.h | 1 + arch/um/include/asm/fncpy.h | 1 + arch/unicore32/include/asm/fncpy.h | 1 + arch/x86/include/asm/fncpy.h| 1 + arch/xtensa/include/asm/fncpy.h | 1 + include/asm-generic/fncpy.h | 104 32 files changed, 154 insertions(+), 57 deletions(-) create mode 100644 arch/alpha/include/asm/fncpy.h create mode 100644 arch/arc/include/asm/fncpy.h create mode 100644 arch/arm64/include/asm/fncpy.h create mode 100644 arch/avr32/include/asm/fncpy.h create mode 100644 arch/blackfin/include/asm/fncpy.h create mode 100644 arch/c6x/include/asm/fncpy.h create mode 100644 arch/cris/include/asm/fncpy.h create mode 100644 arch/frv/include/asm/fncpy.h create mode 100644 arch/h8300/include/asm/fncpy.h create mode 100644 arch/hexagon/include/asm/fncpy.h create mode 100644 arch/ia64/include/asm/fncpy.h create mode 100644 arch/m32r/include/asm/fncpy.h create mode 100644 arch/m68k/include/asm/fncpy.h create mode 100644 arch/metag/include/asm/fncpy.h create mode 100644 arch/microblaze/include/asm/fncpy.h create mode 100644 arch/mips/include/asm/fncpy.h create mode 100644 arch/mn10300/include/asm/fncpy.h create mode 100644 arch/openrisc/include/asm/fncpy.h create mode 100644 arch/parisc/include/asm/fncpy.h create mode 100644 arch/powerpc/include/asm/fncpy.h create mode 100644 arch/s390/include/asm/fncpy.h create mode 100644 arch/score/include/asm/fncpy.h create mode 100644 arch/sh/include/asm/fncpy.h create mode 100644 arch/sparc/include/asm/fncpy.h create mode 100644 arch/tile/include/asm/fncpy.h create mode 100644 arch/um/include/asm/fncpy.h create mode 100644 arch/unicore32/include/asm/fncpy.h create mode 100644 arch/x86/include/asm/fncpy.h create mode 100644 arch/xtensa/include/asm/fncpy.h create mode 100644 include/asm-generic/fncpy.h diff --git a/arch/alpha/include/asm/fncpy.h b/arch/alpha/include/asm/fncpy.h new file mode 100644 index 000..ee4741c --- /dev/null +++ b/arch/alpha/include/asm/fncpy.h @@ -0,0 +1 @@ +#include asm-generic/fncpy.h diff --git a/arch/arc/include/asm/fncpy.h b/arch/arc/include/asm/fncpy.h new file mode 100644 index 000..ee4741c --- /dev/null +++ b/arch/arc/include/asm/fncpy.h @@ -0,0 +1 @@ +#include asm-generic/fncpy.h diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h index de53547..f165f20 100644 --- a/arch/arm/include/asm/fncpy.h +++ b/arch/arm/include/asm/fncpy.h @@ -17,16 +17,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __ASM_FNCPY_H +#define __ASM_FNCPY_H + +#include linux/types.h + /* - * These macros are intended for use when there is a need to copy a low-level - * function body into special memory. - * - * For example, when reconfiguring the SDRAM controller, the code doing the - * reconfiguration may need to run from SRAM. - * - * NOTE: that the copied function body must be entirely self-contained and - * position-independent in order for this to work properly. - * * NOTE: in order for embedded literals and data to get referenced correctly, * the alignment of functions must be preserved when copying. To ensure this, * the source and destination addresses for fncpy() must be aligned to a @@ -34,61 +30,29 @@ * You will typically need a .align 3 directive in the assembler where the * function to be copied is defined, and ensure that your allocator
[RFC PATCH 05/11] PIE: Support embedding position independent executables
This commit adds support for embedding PIEs into the kernel, loading them into genalloc sections, performing necessary relocations, and running code from them. This allows platforms that need to run code from SRAM, such an during suspend/resume, to develop that code in C instead of assembly. Functions and data for each PIE should be grouped into sections with the __pie(group) and __pie_data(group) macros respectively. Any symbols or functions that are to be accessed from outside the PIE should be marked with EXPORT_PIE_SYMBOL(sym). For example: static struct ddr_timings xyz_timings __pie_data(platformxyz) = { [...] }; void __pie(platformxyz) xyz_ddr_on(void *addr) { [...] } EXPORT_PIE_SYMBOL(xyz_ddr_on); While the kernel can access exported symbols from the PIE, the PIE cannot access symbols from the kernel, but can access data from the kernel and call functions in the kernel so long as addresses are passed into the PIE. PIEs are loaded from the kernel into a genalloc pool with pie_load_sections. pie_load_sections allocates space within the pool, copies the neccesary code/data, and performs any necessary relocations. A chunk identifier is returned for removing the PIE from the pool, and for translating symbols. Because the PIEs are dynamically relocated, special accessors must be used to access PIE symbols from kernel code: - kern_to_pie(chunk, ptr): Translate a PIE symbol to the virtual address it is loaded into within the pool. - fn_to_pie(chunk, ptr): Same as above, but for function pointers. - sram_to_phys(chunk, addr): Translate a virtual address within a loaded PIE to a physical address. Loading a PIE involves three main steps. First a set of common functions to cover built-ins emitted by gcc (memcpy, memmove, etc) is copied into the pool. Then the actual PIE code and data is copied into the pool. Because the PIE code is contained within an overlay with other PIEs, offsets to the common functions are maintained. Finally, relocations are performed as necessary. Signed-off-by: Russ Dill russ.d...@ti.com --- Documentation/pie.txt | 167 Makefile | 17 +++- include/asm-generic/pie.lds.h | 82 include/asm-generic/vmlinux.lds.h | 1 + include/linux/pie.h | 196 ++ lib/Kconfig | 14 +++ lib/Makefile | 2 + lib/pie.c | 138 +++ pie/.gitignore| 3 + pie/Makefile | 85 + scripts/link-vmlinux.sh | 11 ++- 11 files changed, 711 insertions(+), 5 deletions(-) create mode 100644 Documentation/pie.txt create mode 100644 include/asm-generic/pie.lds.h create mode 100644 include/linux/pie.h create mode 100644 lib/pie.c create mode 100644 pie/.gitignore create mode 100644 pie/Makefile diff --git a/Documentation/pie.txt b/Documentation/pie.txt new file mode 100644 index 000..54a1646 --- /dev/null +++ b/Documentation/pie.txt @@ -0,0 +1,167 @@ +Position Independent Executables (PIEs) +=== + +About += + +The PIE framework is designed to allow normal C code from the kernel to be +embedded into the kernel, loaded at arbirary addresses, and executed. + +A PIE is a position independent executable is a piece of self contained code +that can be relocated to any address. Before the code is run, a simple list +of offset based relocations has to be performed. + +Copyright 2013 Texas Instruments, Inc + Russ Dill russ.d...@ti.com + +Motivation +== + +Without the PIE framework, the only way to support platforms that require +code loaded to and run from arbitrary addresses was to write the code in +assembly. For example, a platform may have suspend/resume steps that +disable/enable SDRAM and must be run from on chip SRAM. + +In addition to the SRAM virtual address not being known at compile time +for device tree platforms, the code must often run with the MMU enabled or +disabled (physical vs virtual address). + +Design +== + +The PIE code is separated into two main pieces. libpie satifies various +function calls emitted by gcc. The kernel contains only one copy of libpie +but whenever a PIE is loaded, a copy of libpie is copied along with the PIE +code. The second piece is the PIE code and data marked with special PIE +sections. At build time, libpie and the PIE sections are collected together +into a single PIE executable: + + +---+ + | __pie_common_start| + | libpie| + | __pie_common_end | + +---+ + | __pie_overlay_start
[RFC PATCH 03/11] misc: SRAM: Add option to map SRAM to allow code execution
This is necessary for platforms that use SRAM to execute suspend/resume stubs. Signed-off-by: Russ Dill russ.d...@ti.com --- Documentation/devicetree/bindings/misc/sram.txt | 4 drivers/misc/sram.c | 13 - include/linux/platform_data/sram.h | 8 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 include/linux/platform_data/sram.h diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt index 4d0a00e..4fa9af3 100644 --- a/Documentation/devicetree/bindings/misc/sram.txt +++ b/Documentation/devicetree/bindings/misc/sram.txt @@ -8,6 +8,10 @@ Required properties: - reg : SRAM iomem address range +Optional properties: + +- map-exec: Map range to allow code execution + Example: sram: sram@5c00 { diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index d87cc91..baa5008 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/spinlock.h #include linux/genalloc.h +#include linux/platform_data/sram.h #define SRAM_GRANULARITY 32 @@ -38,14 +39,24 @@ struct sram_dev { static int sram_probe(struct platform_device *pdev) { + struct sram_platform_data *pdata = pdev-dev.platform_data; void __iomem *virt_base; struct sram_dev *sram; struct resource *res; unsigned long size; + bool map_exec = false; int ret; + if (of_get_property(pdev-dev.of_node, map-exec, NULL)) + map_exec = true; + if (pdata pdata-map_exec) + map_exec |= true; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - virt_base = devm_ioremap_resource(pdev-dev, res); + if (map_exec) + virt_base = devm_ioremap_exec_resource(pdev-dev, res); + else + virt_base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(virt_base)) return PTR_ERR(virt_base); diff --git a/include/linux/platform_data/sram.h b/include/linux/platform_data/sram.h new file mode 100644 index 000..8f5c4ba --- /dev/null +++ b/include/linux/platform_data/sram.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_SRAM_H +#define _LINUX_SRAM_H + +struct sram_platform_data { + bool map_exec; +}; + +#endif -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC PATCH 00/11] Embeddable Position Independent Executable
This patch adds support for and demonstrates the usage of an embedded position independent executable (PIE). The goal is to allow the use of C code in situations where carefully written position independent assembly was previously required. The example used is the suspend/resume code for the am335x, a Texas Instruments ARM SoC. In order to save the maximum amount of power during suspend, the am335x has to perform several power saving operations after SDRAM has been disabled, and undo those steps at resume time. The am335x provides an SRAM region for the processor to execute such code. A PIE executable was chosen because it limits the types of relocations that must be performed before the code is executed. In the case of ARM, the only required relocation type is a relative relocation of pointers. The kernel is provided symbols into the PIE executable by way of exporting those symbols from the PIE and then importing them into vmlinux at final link time. Because the PIE is loaded dynamically at runtime, any access to PIE functions or data must pass through special accessor macros that apply the necessary offset. Code within the PIE does not have access to symbols outside of the PIE, but it still can access code and data outside the PIE so long as it is passed pointers to that code/data. The PIE executable is provided its own set of functions required by gcc, such as memcpy, memmove, etc. The different PIE sections are collected together in the linker script as an overlay so that the kernel only needs one copy of these functions. When the PIE is loaded, the library functions and appropriate sections are copied into a genalloc pool (in the case of the example, backed by SRAM). The PIE code then applies the necessary relocations to the loaded code. Because the relocations are just relative offsets to pointers, the relocations can be reapplied to allow the code to run with the MMU enabled or disabled. This patchset is a complete rethinking of an earlier patchset [1]. Ard Biesheuvel provided the suggestion to use the PIE executable format for storing the relocatable code within the kernel. Russell King and Dave Martin pointed out the shortcomings of my initial naive approach. This patchset depends on Rajendra Nayak's SRAM DT-ification patch series [2], Suman Anna's am335x mailbox series [3], and a portion of Dave Gerlach's am335x suspend/resume patchset [4]. I've collected together the necessary dependances and applied this patch series on top of them here [5]. Because special ioremap variants are required on ARM for io mappings that allow code execution, the first two patches provide generic accessors for those variants. The third patch provides a DT and pdata method for instructing misc/sram to map the memory in such a way that allows code execution. The 4th patch provides a generic set of functions for handling function pointers as addresses and vice versa. This is necessary on ARM because of the way that Thumb2 function pointers are handled by gcc. The PIE framework requires this functionality because it performs translations of function pointers. The 5th patch is the general PIE framework. The 6th patch is the addition of ARM support for PIE. The 7th patch provides the ability of ARM to fixup PIE code on the fly. This is necessary since at suspend time the MMU will be working, but at resume time, it will be off. The 8th patch provides a predefined trampoline that utilizes the on the fly fixup. The 9th patch configures the SRAM DT entries for am335x so that they can be easily found by the PM code, and so that they are mapped with exec enabled. The 10th patch adds PIE entries for am335x, and the 11th patch finally adds suspend/resume support for am33xx utilizing C code for suspend/resume paths. [1] http://www.spinics.net/lists/arm-kernel/msg271525.html [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/103774 [3] http://www.spinics.net/lists/devicetree/msg00227.html [4] http://www.spinics.net/lists/linux-omap/msg95305.html [5] https://github.com/russdill/linux/commits/sram Russ Dill (10): asm-generic: io: Add exec versions of ioremap lib: devres: Add exec versions of devm_ioremap_resource and friends misc: SRAM: Add option to map SRAM to allow code execution asm-generic: fncpy: Add function copying macros PIE: Support embedding position independent executables ARM: PIE: Add position independent executable embedding to ARM ARM: PIE: Add support for updating PIE relocations ARM: PIE: Add macro for generating PIE resume trampoline ARM: dts: AM33XX: Associate SRAM with MPU and mark it exec ARM: OMAP2+: AM33XX: Add PIE support for AM33XX Vaibhav Bedia (1): ARM: OMAP2+: AM33XX: Basic suspend resume support Documentation/devicetree/bindings/misc/sram.txt | 4 + Documentation/pie.txt | 167 Makefile| 17 +- arch/alpha/include/asm/fncpy.h | 1 + arch/arc/include/asm/fncpy.h
Re: [PATCH 1/2] input: ti_tsc: Enable shared IRQ for TSC
On 08/05/2013 10:02 AM, Zubair Lutfullah : wrote: > On Mon, Aug 05, 2013 at 09:12:56AM -0700, Dmitry Torokhov wrote: Touchscreen and ADC share the same IRQ line from parent MFD core. Previously only Touchscreen was interrupt based. With continuous mode support added in ADC driver, driver requires interrupt to process the ADC samples, so enable shared IRQ flag bit for touchscreen. @@ -260,8 +260,18 @@ static irqreturn_t titsc_irq(int irq, void *dev) unsigned int fsm; + /* + * ADC and touchscreen share the IRQ line. + * FIFO1 threshold, FIFO1 Overrun and FIFO1 underflow + * interrupts are used by ADC, + * hence return from touchscreen IRQ handler if FIFO1 + * related interrupts occurred. + */ + if ((status & IRQENB_FIFO1THRES) || + (status & IRQENB_FIFO1OVRRUN) || + (status & IRQENB_FIFO1UNDRFLW)) + return IRQ_NONE; + else if (status & IRQENB_FIFO0THRES) { >> >> What happens if both parts have data at the same time? Can both >> IRQENB_FIFO1THRES and IRQENB_FIFO0THRES be signalled? What will happen >> in this case? > > If ADC is sampling and someone is touching the TSC, both interrupts > can signal so closely that for the purpose of the kernel, > they can be seen as signaled together. > > FIFO 1 used only by ADC and FIFO1THRES handler is inside the iio/adc driver > FIFO 0 used only by TSC and FIFO0THRES handler is inside the input/touchscreen > > Note: These are level interrupts. > > I would like some input on how to handle such a situation. > > Thanks > Zubair Lutfullah > As far as I know, if there are any bits you can handle and ack, do so and return IRQ_HANDLED. Otherwise, return IRQ_NONE. If there are still pending bits, the interrupt will fire again, your handler will be called again, return IRQ_NONE, and the next handler will be called. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] input: ti_tsc: Enable shared IRQ for TSC
On 08/05/2013 10:02 AM, Zubair Lutfullah : wrote: On Mon, Aug 05, 2013 at 09:12:56AM -0700, Dmitry Torokhov wrote: Touchscreen and ADC share the same IRQ line from parent MFD core. Previously only Touchscreen was interrupt based. With continuous mode support added in ADC driver, driver requires interrupt to process the ADC samples, so enable shared IRQ flag bit for touchscreen. @@ -260,8 +260,18 @@ static irqreturn_t titsc_irq(int irq, void *dev) unsigned int fsm; + /* + * ADC and touchscreen share the IRQ line. + * FIFO1 threshold, FIFO1 Overrun and FIFO1 underflow + * interrupts are used by ADC, + * hence return from touchscreen IRQ handler if FIFO1 + * related interrupts occurred. + */ + if ((status IRQENB_FIFO1THRES) || + (status IRQENB_FIFO1OVRRUN) || + (status IRQENB_FIFO1UNDRFLW)) + return IRQ_NONE; + else if (status IRQENB_FIFO0THRES) { What happens if both parts have data at the same time? Can both IRQENB_FIFO1THRES and IRQENB_FIFO0THRES be signalled? What will happen in this case? If ADC is sampling and someone is touching the TSC, both interrupts can signal so closely that for the purpose of the kernel, they can be seen as signaled together. FIFO 1 used only by ADC and FIFO1THRES handler is inside the iio/adc driver FIFO 0 used only by TSC and FIFO0THRES handler is inside the input/touchscreen Note: These are level interrupts. I would like some input on how to handle such a situation. Thanks Zubair Lutfullah As far as I know, if there are any bits you can handle and ack, do so and return IRQ_HANDLED. Otherwise, return IRQ_NONE. If there are still pending bits, the interrupt will fire again, your handler will be called again, return IRQ_NONE, and the next handler will be called. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3.8-stable] regulator: core: Log when a device causes a voltage
On 04/02/2013 01:02 PM, Greg KH wrote: > On Tue, Apr 02, 2013 at 06:30:42PM +0900, Jonghwan Choi wrote: >> 3.8-stable review patch. If anyone has any objections, please let us know. >> >> ------ >> >> From: "Russ Dill " >> >> commit 6e45eb12fd1c741d556bf264ee98853b5f3104e5 upstream. > > Wait, no, this is NOT the commit id of this patch, please don't get this > wrong. > > I've dropped this from my stable mbox, if Russ feels this should go to > 3.8-stable, please send me the correct git id of the patch to apply. 9c7b4e8a8ad2624106fbf690fa97ab9c8c9bfa88 is the proper upstream commit. This fixes a potential oops that was added in 3.8-rc4, and fixed upstream in 3.9-rc1. I do think it belongs in stable. Too bad I can't muck up the commit, then I'd owe you a beer. Might help that shoulder of yours. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3.8-stable] regulator: core: Log when a device causes a voltage
On 04/02/2013 01:02 PM, Greg KH wrote: On Tue, Apr 02, 2013 at 06:30:42PM +0900, Jonghwan Choi wrote: 3.8-stable review patch. If anyone has any objections, please let us know. -- From: Russ Dill russ.d...@ti.com commit 6e45eb12fd1c741d556bf264ee98853b5f3104e5 upstream. Wait, no, this is NOT the commit id of this patch, please don't get this wrong. I've dropped this from my stable mbox, if Russ feels this should go to 3.8-stable, please send me the correct git id of the patch to apply. 9c7b4e8a8ad2624106fbf690fa97ab9c8c9bfa88 is the proper upstream commit. This fixes a potential oops that was added in 3.8-rc4, and fixed upstream in 3.9-rc1. I do think it belongs in stable. Too bad I can't muck up the commit, then I'd owe you a beer. Might help that shoulder of yours. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Revert "random: Mix cputime from each thread that exits to the pool"
On Mon, Mar 4, 2013 at 9:05 AM, Theodore Ts'o wrote: > Russ, how about this patch instead? Can you verify whether or not > this fixes your issue? If so, I'll push it to Linus. > > - Ted Yup, fixes the circular locking dependency. Tested-by: russ.d...@gmail.com > From 24c598b5abd466f2bab954d0cc8c225e0d3a2a74 Mon Sep 17 00:00:00 2001 > From: Theodore Ts'o > Date: Mon, 4 Mar 2013 11:59:12 -0500 > Subject: [PATCH] random: fix locking dependency with the tasklist_lock > > Commit 6133705494bb introduced a circular lock dependency because > posix_cpu_timers_exit() is called by release_task(), which is holding > a writer lock on tasklist_lock, and this can cause a deadlock since > kill_fasync() gets called with nonblocking_pool.lock taken. > > There's no reason why kill_fasync() needs to be taken while the random > pool is locked, so move it out to fix this locking dependency. > > Signed-off-by: "Theodore Ts'o" > Reported-by: Russ Dill > Cc: sta...@kernel.org > --- > drivers/char/random.c | 12 > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/char/random.c b/drivers/char/random.c > index 85e81ec..57d4b15 100644 > --- a/drivers/char/random.c > +++ b/drivers/char/random.c > @@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t > nbytes, int min, > int reserved) > { > unsigned long flags; > + int wakeup_write = 0; > > /* Hold lock while accounting */ > spin_lock_irqsave(>lock, flags); > @@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t > nbytes, int min, > else > r->entropy_count = reserved; > > - if (r->entropy_count < random_write_wakeup_thresh) { > - wake_up_interruptible(_write_wait); > - kill_fasync(, SIGIO, POLL_OUT); > - } > + if (r->entropy_count < random_write_wakeup_thresh) > + wakeup_write = 1; > } > > DEBUG_ENT("debiting %zu entropy credits from %s%s\n", > @@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t > nbytes, int min, > > spin_unlock_irqrestore(>lock, flags); > > + if (wakeup_write) { > + wake_up_interruptible(_write_wait); > + kill_fasync(, SIGIO, POLL_OUT); > + } > + > return nbytes; > } > > -- > 1.7.12.rc0.22.gcdd159b > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Revert "random: Mix cputime from each thread that exits to the pool"
This reverts commit 6133705494bb02953e1e2cc3018a4373981b3c97. The above commit introduces a circular locking dependacy. Existing code takes nonblocking_port.lock and then tasklist_lock. The code in this commit takes nonblocking_port.lock while talklist_lock is already held leading to a potential deadlock. For now, simply revert the commit. Existing lock order: send_sigio /* takes read lock on tasklist_lock */ kill_fasync_rcu kill_fasync account /* takes nonblocking_pool.lock */ extract_entropy get_random_bytes create_elf_tables load_elf_binary load_elf_library search_binary_handler New code: mix_pool_bytes /* takes nonblocking_pool.lock */ add_device_randomness posix_cpu_timers_exit __exit_signal release_task /* takes write lock on tasklist_lock */ do_exit __module_put_and_exit cryptomgr_test Signed-off-by: Russ Dill --- kernel/posix-cpu-timers.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 942ca27..1f2ef3d 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -9,7 +9,6 @@ #include #include #include -#include /* * Called after updating RLIMIT_CPU to run cpu timer and update @@ -471,8 +470,6 @@ static void cleanup_timers(struct list_head *head, */ void posix_cpu_timers_exit(struct task_struct *tsk) { - add_device_randomness((const void*) >se.sum_exec_runtime, - sizeof(unsigned long long)); cleanup_timers(tsk->cpu_timers, tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Revert random: Mix cputime from each thread that exits to the pool
This reverts commit 6133705494bb02953e1e2cc3018a4373981b3c97. The above commit introduces a circular locking dependacy. Existing code takes nonblocking_port.lock and then tasklist_lock. The code in this commit takes nonblocking_port.lock while talklist_lock is already held leading to a potential deadlock. For now, simply revert the commit. Existing lock order: send_sigio /* takes read lock on tasklist_lock */ kill_fasync_rcu kill_fasync account /* takes nonblocking_pool.lock */ extract_entropy get_random_bytes create_elf_tables load_elf_binary load_elf_library search_binary_handler New code: mix_pool_bytes /* takes nonblocking_pool.lock */ add_device_randomness posix_cpu_timers_exit __exit_signal release_task /* takes write lock on tasklist_lock */ do_exit __module_put_and_exit cryptomgr_test Signed-off-by: Russ Dill russ.d...@gmail.com --- kernel/posix-cpu-timers.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 942ca27..1f2ef3d 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -9,7 +9,6 @@ #include asm/uaccess.h #include linux/kernel_stat.h #include trace/events/timer.h -#include linux/random.h /* * Called after updating RLIMIT_CPU to run cpu timer and update @@ -471,8 +470,6 @@ static void cleanup_timers(struct list_head *head, */ void posix_cpu_timers_exit(struct task_struct *tsk) { - add_device_randomness((const void*) tsk-se.sum_exec_runtime, - sizeof(unsigned long long)); cleanup_timers(tsk-cpu_timers, tsk-utime, tsk-stime, tsk-se.sum_exec_runtime); -- 1.8.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Revert random: Mix cputime from each thread that exits to the pool
On Mon, Mar 4, 2013 at 9:05 AM, Theodore Ts'o ty...@mit.edu wrote: Russ, how about this patch instead? Can you verify whether or not this fixes your issue? If so, I'll push it to Linus. - Ted Yup, fixes the circular locking dependency. Tested-by: russ.d...@gmail.com From 24c598b5abd466f2bab954d0cc8c225e0d3a2a74 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o ty...@mit.edu Date: Mon, 4 Mar 2013 11:59:12 -0500 Subject: [PATCH] random: fix locking dependency with the tasklist_lock Commit 6133705494bb introduced a circular lock dependency because posix_cpu_timers_exit() is called by release_task(), which is holding a writer lock on tasklist_lock, and this can cause a deadlock since kill_fasync() gets called with nonblocking_pool.lock taken. There's no reason why kill_fasync() needs to be taken while the random pool is locked, so move it out to fix this locking dependency. Signed-off-by: Theodore Ts'o ty...@mit.edu Reported-by: Russ Dill russ.d...@gmail.com Cc: sta...@kernel.org --- drivers/char/random.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 85e81ec..57d4b15 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, int reserved) { unsigned long flags; + int wakeup_write = 0; /* Hold lock while accounting */ spin_lock_irqsave(r-lock, flags); @@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, else r-entropy_count = reserved; - if (r-entropy_count random_write_wakeup_thresh) { - wake_up_interruptible(random_write_wait); - kill_fasync(fasync, SIGIO, POLL_OUT); - } + if (r-entropy_count random_write_wakeup_thresh) + wakeup_write = 1; } DEBUG_ENT(debiting %zu entropy credits from %s%s\n, @@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, spin_unlock_irqrestore(r-lock, flags); + if (wakeup_write) { + wake_up_interruptible(random_write_wait); + kill_fasync(fasync, SIGIO, POLL_OUT); + } + return nbytes; } -- 1.7.12.rc0.22.gcdd159b -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: fasync race in fs/fcntl.c
On Sat, Mar 2, 2013 at 4:09 PM, Russ Dill wrote: > On Sat, Mar 2, 2013 at 11:49 AM, Al Viro wrote: >> On Sat, Mar 02, 2013 at 03:00:28AM -0800, Russ Dill wrote: >>> I'm seeing a race in fs/fcntl.c. I'm not sure exactly how the race is >>> occurring, but the following is my best guess. A kernel log is >>> attached. >> >> [snip the analysis - it's a different lock anyway] >> >> The traces below are essentially sys_execve() getting to get_random_bytes(), >> to kill_fasync(), to send_sigio(), which spins on tasklist_lock. >> >> Could you rebuild it with lockdep enabled and try to reproduce that? >> I very much doubt that this execve() is a part of deadlock - it's >> getting caught on one, but it shouldn't be holding any locks that >> nest inside tasklist_lock at that point, so even it hadn't been there, >> the process holding tasklist_lock probably wouldn't have progressed any >> further... > > ok, I did screw up the analysis quite badly, luckily, lockdep got it right > away. > So lockdep gives some clues, but seems a bit confused, so here's what happened. mix_pool_bytes /* takes nonblocking_pool.lock */ add_device_randomness posix_cpu_timers_exit __exit_signal release_task /* takes write lock on tasklist_lock */ do_exit __module_put_and_exit cryptomgr_test send_sigio /* takes read lock on tasklist_lock */ kill_fasync_rcu kill_fasync account /* takes nonblocking_pool.lock */ extract_entropy get_random_bytes create_elf_tables load_elf_binary load_elf_library search_binary_handler This would mark the culprit as 613370549 'random: Mix cputime from each thread that exits to the pool'. So long as I'm not as crazy on the last analysis as this one, may I suggest a revert of this commit for 3.8.3? > [ 199.411236] > [ 199.411261] == > [ 199.411268] [ INFO: possible circular locking dependency detected ] > [ 199.411277] 3.8.0-9-generic #18 Not tainted > [ 199.411283] --- > [ 199.411290] slirp-wrapper.s/5574 is trying to acquire lock: > [ 199.411296] (&(>fa_lock)->rlock){-.-...}, at: > [] kill_fasync+0x69/0xe0 > [ 199.411332] > [ 199.411332] but task is already holding lock: > [ 199.411338] (_pool.lock){..}, at: > [] account+0x39/0x1d0 > [ 199.411364] > [ 199.411364] which lock already depends on the new lock. > [ 199.411364] > [ 199.411371] > [ 199.411371] the existing dependency chain (in reverse order) is: > [ 199.411379] > [ 199.411379] -> #2 (_pool.lock){..}: > [ 199.411400][] lock_acquire+0x98/0x120 > [ 199.411416][] _raw_spin_lock_irqsave+0x4e/0x70 > [ 199.411430][] > mix_pool_bytes.constprop.20+0x43/0xb0 > [ 199.411442][] add_device_randomness+0x64/0x90 > [ 199.411454][] posix_cpu_timers_exit+0x1e/0x50 > [ 199.411469][] release_task+0xe2/0x470 > [ 199.411484][] do_exit+0x5d7/0x9c0 > [ 199.411495][] __module_put_and_exit+0x1a/0x20 > [ 199.411509][] cryptomgr_test+0x25/0x30 > [ 199.411526][] kthread+0xea/0xf0 > [ 199.411537][] ret_from_fork+0x7c/0xb0 > [ 199.411550] > [ 199.411550] -> #1 (&(>siglock)->rlock){-.-...}: > [ 199.411689][] lock_acquire+0x98/0x120 > [ 199.411702][] _raw_spin_lock_irqsave+0x4e/0x70 > [ 199.411713][] vblank_disable_fn+0x60/0xd0 [drm] > [ 199.411768][] call_timer_fn+0x7a/0x180 > [ 199.411781][] run_timer_softirq+0x1fc/0x2a0 > [ 199.411794][] __do_softirq+0xe0/0x220 > [ 199.411807][] call_softirq+0x1c/0x30 > [ 199.411819][] do_softirq+0xa5/0xe0 > [ 199.411833][] irq_exit+0xb5/0xc0 > [ 199.411846][] smp_apic_timer_interrupt+0x6e/0x99 > [ 199.411859][] apic_timer_interrupt+0x72/0x80 > [ 199.411871][] cpuidle_enter_tk+0x10/0x20 > [ 199.411885][] cpuidle_idle_call+0xa5/0x270 > [ 199.411897][] cpu_idle+0xb5/0x120 > [ 199.411910][] rest_init+0xb4/0xc0 > [ 199.411924][] start_kernel+0x3ea/0x3f6 > [ 199.411939][] > x86_64_start_reservations+0x130/0x133 > [ 199.411952][] x86_64_start_kernel+0x100/0x10f > [ 199.411966] > [ 199.411966] -> #0 (&(>fa_lock)->rlock){-.-...}: > [ 199.411984][] __lock_acquire+0x1279/0x1aa0 > [ 199.411997][] lock_acquire+0x98/0x120 > [ 199.412103][] _raw_spin_lock_irqsave+0x4e/0x70 > [ 199.412115][] kill_fasync+0x69/0xe0 > [ 199.412127][] account+0x113/0x1d0 > [ 199.412138][] extract_entropy+0x65/0x140 > [ 199.412149][] get_random_bytes+0x20/0x30 > [ 199.412159]
Re: fasync race in fs/fcntl.c
On Sat, Mar 2, 2013 at 4:09 PM, Russ Dill russ.d...@gmail.com wrote: On Sat, Mar 2, 2013 at 11:49 AM, Al Viro v...@zeniv.linux.org.uk wrote: On Sat, Mar 02, 2013 at 03:00:28AM -0800, Russ Dill wrote: I'm seeing a race in fs/fcntl.c. I'm not sure exactly how the race is occurring, but the following is my best guess. A kernel log is attached. [snip the analysis - it's a different lock anyway] The traces below are essentially sys_execve() getting to get_random_bytes(), to kill_fasync(), to send_sigio(), which spins on tasklist_lock. Could you rebuild it with lockdep enabled and try to reproduce that? I very much doubt that this execve() is a part of deadlock - it's getting caught on one, but it shouldn't be holding any locks that nest inside tasklist_lock at that point, so even it hadn't been there, the process holding tasklist_lock probably wouldn't have progressed any further... ok, I did screw up the analysis quite badly, luckily, lockdep got it right away. So lockdep gives some clues, but seems a bit confused, so here's what happened. mix_pool_bytes /* takes nonblocking_pool.lock */ add_device_randomness posix_cpu_timers_exit __exit_signal release_task /* takes write lock on tasklist_lock */ do_exit __module_put_and_exit cryptomgr_test send_sigio /* takes read lock on tasklist_lock */ kill_fasync_rcu kill_fasync account /* takes nonblocking_pool.lock */ extract_entropy get_random_bytes create_elf_tables load_elf_binary load_elf_library search_binary_handler This would mark the culprit as 613370549 'random: Mix cputime from each thread that exits to the pool'. So long as I'm not as crazy on the last analysis as this one, may I suggest a revert of this commit for 3.8.3? [ 199.411236] [ 199.411261] == [ 199.411268] [ INFO: possible circular locking dependency detected ] [ 199.411277] 3.8.0-9-generic #18 Not tainted [ 199.411283] --- [ 199.411290] slirp-wrapper.s/5574 is trying to acquire lock: [ 199.411296] ((new-fa_lock)-rlock){-.-...}, at: [811b3fc9] kill_fasync+0x69/0xe0 [ 199.411332] [ 199.411332] but task is already holding lock: [ 199.411338] (nonblocking_pool.lock){..}, at: [81456789] account+0x39/0x1d0 [ 199.411364] [ 199.411364] which lock already depends on the new lock. [ 199.411364] [ 199.411371] [ 199.411371] the existing dependency chain (in reverse order) is: [ 199.411379] [ 199.411379] - #2 (nonblocking_pool.lock){..}: [ 199.411400][810bdd58] lock_acquire+0x98/0x120 [ 199.411416][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411430][81456543] mix_pool_bytes.constprop.20+0x43/0xb0 [ 199.411442][81456724] add_device_randomness+0x64/0x90 [ 199.411454][81081e0e] posix_cpu_timers_exit+0x1e/0x50 [ 199.411469][8105d0b2] release_task+0xe2/0x470 [ 199.411484][8105eb77] do_exit+0x5d7/0x9c0 [ 199.411495][810c6b4a] __module_put_and_exit+0x1a/0x20 [ 199.411509][8132b725] cryptomgr_test+0x25/0x30 [ 199.411526][8107f5ea] kthread+0xea/0xf0 [ 199.411537][8170146c] ret_from_fork+0x7c/0xb0 [ 199.411550] [ 199.411550] - #1 ((sighand-siglock)-rlock){-.-...}: [ 199.411689][810bdd58] lock_acquire+0x98/0x120 [ 199.411702][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411713][a0008200] vblank_disable_fn+0x60/0xd0 [drm] [ 199.411768][810695da] call_timer_fn+0x7a/0x180 [ 199.411781][8106aa2c] run_timer_softirq+0x1fc/0x2a0 [ 199.411794][81061580] __do_softirq+0xe0/0x220 [ 199.411807][81702a3c] call_softirq+0x1c/0x30 [ 199.411819][81016685] do_softirq+0xa5/0xe0 [ 199.411833][81061855] irq_exit+0xb5/0xc0 [ 199.411846][817033de] smp_apic_timer_interrupt+0x6e/0x99 [ 199.411859][817022f2] apic_timer_interrupt+0x72/0x80 [ 199.411871][8158e3c0] cpuidle_enter_tk+0x10/0x20 [ 199.411885][8158df95] cpuidle_idle_call+0xa5/0x270 [ 199.411897][8101d865] cpu_idle+0xb5/0x120 [ 199.411910][816d4d64] rest_init+0xb4/0xc0 [ 199.411924][81d22c07] start_kernel+0x3ea/0x3f6 [ 199.411939][81d22355] x86_64_start_reservations+0x130/0x133 [ 199.411952][81d22458] x86_64_start_kernel+0x100/0x10f [ 199.411966] [ 199.411966] - #0 ((new-fa_lock)-rlock){-.-...}: [ 199.411984][810bcfc9] __lock_acquire+0x1279/0x1aa0 [ 199.411997][810bdd58] lock_acquire+0x98/0x120 [ 199.412103][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.412115][811b3fc9] kill_fasync+0x69/0xe0
Re: fasync race in fs/fcntl.c
On Sat, Mar 2, 2013 at 11:49 AM, Al Viro wrote: > On Sat, Mar 02, 2013 at 03:00:28AM -0800, Russ Dill wrote: >> I'm seeing a race in fs/fcntl.c. I'm not sure exactly how the race is >> occurring, but the following is my best guess. A kernel log is >> attached. > > [snip the analysis - it's a different lock anyway] > > The traces below are essentially sys_execve() getting to get_random_bytes(), > to kill_fasync(), to send_sigio(), which spins on tasklist_lock. > > Could you rebuild it with lockdep enabled and try to reproduce that? > I very much doubt that this execve() is a part of deadlock - it's > getting caught on one, but it shouldn't be holding any locks that > nest inside tasklist_lock at that point, so even it hadn't been there, > the process holding tasklist_lock probably wouldn't have progressed any > further... ok, I did screw up the analysis quite badly, luckily, lockdep got it right away. [ 199.411236] [ 199.411261] == [ 199.411268] [ INFO: possible circular locking dependency detected ] [ 199.411277] 3.8.0-9-generic #18 Not tainted [ 199.411283] --- [ 199.411290] slirp-wrapper.s/5574 is trying to acquire lock: [ 199.411296] (&(>fa_lock)->rlock){-.-...}, at: [] kill_fasync+0x69/0xe0 [ 199.411332] [ 199.411332] but task is already holding lock: [ 199.411338] (_pool.lock){..}, at: [] account+0x39/0x1d0 [ 199.411364] [ 199.411364] which lock already depends on the new lock. [ 199.411364] [ 199.411371] [ 199.411371] the existing dependency chain (in reverse order) is: [ 199.411379] [ 199.411379] -> #2 (_pool.lock){..}: [ 199.411400][] lock_acquire+0x98/0x120 [ 199.411416][] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411430][] mix_pool_bytes.constprop.20+0x43/0xb0 [ 199.411442][] add_device_randomness+0x64/0x90 [ 199.411454][] posix_cpu_timers_exit+0x1e/0x50 [ 199.411469][] release_task+0xe2/0x470 [ 199.411484][] do_exit+0x5d7/0x9c0 [ 199.411495][] __module_put_and_exit+0x1a/0x20 [ 199.411509][] cryptomgr_test+0x25/0x30 [ 199.411526][] kthread+0xea/0xf0 [ 199.411537][] ret_from_fork+0x7c/0xb0 [ 199.411550] [ 199.411550] -> #1 (&(>siglock)->rlock){-.-...}: [ 199.411689][] lock_acquire+0x98/0x120 [ 199.411702][] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411713][] vblank_disable_fn+0x60/0xd0 [drm] [ 199.411768][] call_timer_fn+0x7a/0x180 [ 199.411781][] run_timer_softirq+0x1fc/0x2a0 [ 199.411794][] __do_softirq+0xe0/0x220 [ 199.411807][] call_softirq+0x1c/0x30 [ 199.411819][] do_softirq+0xa5/0xe0 [ 199.411833][] irq_exit+0xb5/0xc0 [ 199.411846][] smp_apic_timer_interrupt+0x6e/0x99 [ 199.411859][] apic_timer_interrupt+0x72/0x80 [ 199.411871][] cpuidle_enter_tk+0x10/0x20 [ 199.411885][] cpuidle_idle_call+0xa5/0x270 [ 199.411897][] cpu_idle+0xb5/0x120 [ 199.411910][] rest_init+0xb4/0xc0 [ 199.411924][] start_kernel+0x3ea/0x3f6 [ 199.411939][] x86_64_start_reservations+0x130/0x133 [ 199.411952][] x86_64_start_kernel+0x100/0x10f [ 199.411966] [ 199.411966] -> #0 (&(>fa_lock)->rlock){-.-...}: [ 199.411984][] __lock_acquire+0x1279/0x1aa0 [ 199.411997][] lock_acquire+0x98/0x120 [ 199.412103][] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.412115][] kill_fasync+0x69/0xe0 [ 199.412127][] account+0x113/0x1d0 [ 199.412138][] extract_entropy+0x65/0x140 [ 199.412149][] get_random_bytes+0x20/0x30 [ 199.412159][] create_elf_tables+0xaa/0x615 [ 199.412172][] load_elf_binary+0xae4/0xe00 [ 199.412185][] search_binary_handler+0x171/0x390 [ 199.412197][] load_script+0x265/0x2b0 [ 199.412208][] search_binary_handler+0x171/0x390 [ 199.412219][] do_execve_common.isra.23+0x405/0x4c0 [ 199.412230][] do_execve+0x18/0x20 [ 199.412240][] sys_execve+0x3d/0x60 [ 199.412251][] stub_execve+0x69/0xc0 [ 199.412263] [ 199.412263] other info that might help us debug this: [ 199.412263] [ 199.412271] Chain exists of: [ 199.412271] &(>fa_lock)->rlock --> &(>siglock)->rlock --> _pool.lock [ 199.412271] [ 199.412298] Possible unsafe locking scenario: [ 199.412298] [ 199.412305]CPU0CPU1 [ 199.412310] [ 199.412316] lock(_pool.lock); [ 199.412328]lock(&(>siglock)->rlock); [ 199.412339]lock(_pool.lock); [ 199.412452] lock(&(>fa_lock)->rlock); [ 199.412464] [ 199.412464] *** DEADLOCK *** [ 199.412464] [ 199.412473]
Re: fasync race in fs/fcntl.c
On Sat, Mar 2, 2013 at 11:49 AM, Al Viro v...@zeniv.linux.org.uk wrote: On Sat, Mar 02, 2013 at 03:00:28AM -0800, Russ Dill wrote: I'm seeing a race in fs/fcntl.c. I'm not sure exactly how the race is occurring, but the following is my best guess. A kernel log is attached. [snip the analysis - it's a different lock anyway] The traces below are essentially sys_execve() getting to get_random_bytes(), to kill_fasync(), to send_sigio(), which spins on tasklist_lock. Could you rebuild it with lockdep enabled and try to reproduce that? I very much doubt that this execve() is a part of deadlock - it's getting caught on one, but it shouldn't be holding any locks that nest inside tasklist_lock at that point, so even it hadn't been there, the process holding tasklist_lock probably wouldn't have progressed any further... ok, I did screw up the analysis quite badly, luckily, lockdep got it right away. [ 199.411236] [ 199.411261] == [ 199.411268] [ INFO: possible circular locking dependency detected ] [ 199.411277] 3.8.0-9-generic #18 Not tainted [ 199.411283] --- [ 199.411290] slirp-wrapper.s/5574 is trying to acquire lock: [ 199.411296] ((new-fa_lock)-rlock){-.-...}, at: [811b3fc9] kill_fasync+0x69/0xe0 [ 199.411332] [ 199.411332] but task is already holding lock: [ 199.411338] (nonblocking_pool.lock){..}, at: [81456789] account+0x39/0x1d0 [ 199.411364] [ 199.411364] which lock already depends on the new lock. [ 199.411364] [ 199.411371] [ 199.411371] the existing dependency chain (in reverse order) is: [ 199.411379] [ 199.411379] - #2 (nonblocking_pool.lock){..}: [ 199.411400][810bdd58] lock_acquire+0x98/0x120 [ 199.411416][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411430][81456543] mix_pool_bytes.constprop.20+0x43/0xb0 [ 199.411442][81456724] add_device_randomness+0x64/0x90 [ 199.411454][81081e0e] posix_cpu_timers_exit+0x1e/0x50 [ 199.411469][8105d0b2] release_task+0xe2/0x470 [ 199.411484][8105eb77] do_exit+0x5d7/0x9c0 [ 199.411495][810c6b4a] __module_put_and_exit+0x1a/0x20 [ 199.411509][8132b725] cryptomgr_test+0x25/0x30 [ 199.411526][8107f5ea] kthread+0xea/0xf0 [ 199.411537][8170146c] ret_from_fork+0x7c/0xb0 [ 199.411550] [ 199.411550] - #1 ((sighand-siglock)-rlock){-.-...}: [ 199.411689][810bdd58] lock_acquire+0x98/0x120 [ 199.411702][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.411713][a0008200] vblank_disable_fn+0x60/0xd0 [drm] [ 199.411768][810695da] call_timer_fn+0x7a/0x180 [ 199.411781][8106aa2c] run_timer_softirq+0x1fc/0x2a0 [ 199.411794][81061580] __do_softirq+0xe0/0x220 [ 199.411807][81702a3c] call_softirq+0x1c/0x30 [ 199.411819][81016685] do_softirq+0xa5/0xe0 [ 199.411833][81061855] irq_exit+0xb5/0xc0 [ 199.411846][817033de] smp_apic_timer_interrupt+0x6e/0x99 [ 199.411859][817022f2] apic_timer_interrupt+0x72/0x80 [ 199.411871][8158e3c0] cpuidle_enter_tk+0x10/0x20 [ 199.411885][8158df95] cpuidle_idle_call+0xa5/0x270 [ 199.411897][8101d865] cpu_idle+0xb5/0x120 [ 199.411910][816d4d64] rest_init+0xb4/0xc0 [ 199.411924][81d22c07] start_kernel+0x3ea/0x3f6 [ 199.411939][81d22355] x86_64_start_reservations+0x130/0x133 [ 199.411952][81d22458] x86_64_start_kernel+0x100/0x10f [ 199.411966] [ 199.411966] - #0 ((new-fa_lock)-rlock){-.-...}: [ 199.411984][810bcfc9] __lock_acquire+0x1279/0x1aa0 [ 199.411997][810bdd58] lock_acquire+0x98/0x120 [ 199.412103][816f8b1e] _raw_spin_lock_irqsave+0x4e/0x70 [ 199.412115][811b3fc9] kill_fasync+0x69/0xe0 [ 199.412127][81456863] account+0x113/0x1d0 [ 199.412138][81456e15] extract_entropy+0x65/0x140 [ 199.412149][81457120] get_random_bytes+0x20/0x30 [ 199.412159][816ee9b2] create_elf_tables+0xaa/0x615 [ 199.412172][811f9a94] load_elf_binary+0xae4/0xe00 [ 199.412185][811a9081] search_binary_handler+0x171/0x390 [ 199.412197][811f7515] load_script+0x265/0x2b0 [ 199.412208][811a9081] search_binary_handler+0x171/0x390 [ 199.412219][811aa305] do_execve_common.isra.23+0x405/0x4c0 [ 199.412230][811aa3d8] do_execve+0x18/0x20 [ 199.412240][811aa67d] sys_execve+0x3d/0x60 [ 199.412251][81701b19] stub_execve+0x69/0xc0 [ 199.412263] [ 199.412263] other info
[PATCH] regulator: Fix memory garbage dev_err printout.
commit dd8004af: 'regulator: core: Log when a device causes a voltage constraint fail', tried to print out some information about the check consumer min/max uV fixup, however, it uses a garbage pointer left over from list_for_each_entry leading to boot messages in the form: '[2.079890] : Restricting voltage, 3735899821-4294967295uV' Because it references regulator->dev, it could potentially read memory from anywhere causing a panic. This patch instead uses rdev and the updated min/max uV values. Signed-off-by: Russ Dill --- drivers/regulator/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2785843..5a0f54a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev, } if (*min_uV > *max_uV) { - dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n", - regulator->min_uV, regulator->max_uV); + rdev_err(rdev, "Restricting voltage, %u-%uuV\n", + *min_uV, *max_uV); return -EINVAL; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] regulator: Fix memory garbage dev_err printout.
commit dd8004af: 'regulator: core: Log when a device causes a voltage constraint fail', tried to print out some information about the check consumer min/max uV fixup, however, it uses a garbage pointer left over from list_for_each_entry leading to boot messages in the form: '[2.079890] RANDOM ASCII: Restricting voltage, 3735899821-4294967295uV' Because it references regulator-dev, it could potentially read memory from anywhere causing a panic. This patch instead uses rdev and the updated min/max uV values. Signed-off-by: Russ Dill russ.d...@ti.com --- drivers/regulator/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2785843..5a0f54a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -200,8 +200,8 @@ static int regulator_check_consumers(struct regulator_dev *rdev, } if (*min_uV *max_uV) { - dev_err(regulator-dev, Restricting voltage, %u-%uuV\n, - regulator-min_uV, regulator-max_uV); + rdev_err(rdev, Restricting voltage, %u-%uuV\n, + *min_uV, *max_uV); return -EINVAL; } -- 1.8.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Don't mark shared helper functions as inline
On Mon, Nov 26, 2012 at 11:57 AM, Mike Turquette wrote: > > Quoting Russ Dill (2012-11-26 11:20:09) > > The helper functions that access the opaque struct clk should > > not be marked inline since they are contained in clk.c, but expected > > to be used by other compilation units. This causes compile errors > > under gcc-4.7 > > > > In file included from arch/arm/mach-omap2/clockdomain.c:25:0: > > arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: > > include/linux/clk-provider.h:338:12: error: inlining failed in call to > > always_inline ‘__clk_get_enable_count’: function body not available > > arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here > > make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 > > make: *** [arch/arm/mach-omap2] Error 2 > > > > Hi Russ, > > A fix for this was merged into rc7. See 93532c8a, "clk: remove inline > usage from clk-provider.h". > > Regardless, I'm still considering this patch. I've heard many times > that we should trust the compiler to optimize for us and some folks look > down on inlining in general. If anyone has an opinion on removing > inlines from the common clk core then please do speak up. > > Russ, can you update to the latest rc and verify if that fix is enough > for you? Yes, that commit fixes the compile issue too. I'd go with the more complete removal of inlines though. If you have a declaration in a header, it makes no sense to call it inline in the .c > Regards, > Mike > > > > > Signed-off-by: Russ Dill > > --- > > drivers/clk/clk.c| 14 +++--- > > include/linux/clk-provider.h | 4 ++-- > > 2 files changed, 9 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > > index 56e4495e..ed01746 100644 > > --- a/drivers/clk/clk.c > > +++ b/drivers/clk/clk.c > > @@ -249,32 +249,32 @@ late_initcall(clk_disable_unused); > > > > /***helper functions ***/ > > > > -inline const char *__clk_get_name(struct clk *clk) > > +const char *__clk_get_name(struct clk *clk) > > { > > return !clk ? NULL : clk->name; > > } > > > > -inline struct clk_hw *__clk_get_hw(struct clk *clk) > > +struct clk_hw *__clk_get_hw(struct clk *clk) > > { > > return !clk ? NULL : clk->hw; > > } > > > > -inline u8 __clk_get_num_parents(struct clk *clk) > > +u8 __clk_get_num_parents(struct clk *clk) > > { > > return !clk ? -EINVAL : clk->num_parents; > > } > > > > -inline struct clk *__clk_get_parent(struct clk *clk) > > +struct clk *__clk_get_parent(struct clk *clk) > > { > > return !clk ? NULL : clk->parent; > > } > > > > -inline int __clk_get_enable_count(struct clk *clk) > > +int __clk_get_enable_count(struct clk *clk) > > { > > return !clk ? -EINVAL : clk->enable_count; > > } > > > > -inline int __clk_get_prepare_count(struct clk *clk) > > +int __clk_get_prepare_count(struct clk *clk) > > { > > return !clk ? -EINVAL : clk->prepare_count; > > } > > @@ -300,7 +300,7 @@ out: > > return ret; > > } > > > > -inline unsigned long __clk_get_flags(struct clk *clk) > > +unsigned long __clk_get_flags(struct clk *clk) > > { > > return !clk ? -EINVAL : clk->flags; > > } > > diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h > > index c127315..f9f5e9e 100644 > > --- a/include/linux/clk-provider.h > > +++ b/include/linux/clk-provider.h > > @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); > > struct clk_hw *__clk_get_hw(struct clk *clk); > > u8 __clk_get_num_parents(struct clk *clk); > > struct clk *__clk_get_parent(struct clk *clk); > > -inline int __clk_get_enable_count(struct clk *clk); > > -inline int __clk_get_prepare_count(struct clk *clk); > > +int __clk_get_enable_count(struct clk *clk); > > +int __clk_get_prepare_count(struct clk *clk); > > unsigned long __clk_get_rate(struct clk *clk); > > unsigned long __clk_get_flags(struct clk *clk); > > int __clk_is_enabled(struct clk *clk); > > -- > > 1.8.0 > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Don't mark shared helper functions as inline
On Mon, Nov 26, 2012 at 11:57 AM, Mike Turquette mturque...@ti.com wrote: Quoting Russ Dill (2012-11-26 11:20:09) The helper functions that access the opaque struct clk should not be marked inline since they are contained in clk.c, but expected to be used by other compilation units. This causes compile errors under gcc-4.7 In file included from arch/arm/mach-omap2/clockdomain.c:25:0: arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: include/linux/clk-provider.h:338:12: error: inlining failed in call to always_inline ‘__clk_get_enable_count’: function body not available arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 Hi Russ, A fix for this was merged into rc7. See 93532c8a, clk: remove inline usage from clk-provider.h. Regardless, I'm still considering this patch. I've heard many times that we should trust the compiler to optimize for us and some folks look down on inlining in general. If anyone has an opinion on removing inlines from the common clk core then please do speak up. Russ, can you update to the latest rc and verify if that fix is enough for you? Yes, that commit fixes the compile issue too. I'd go with the more complete removal of inlines though. If you have a declaration in a header, it makes no sense to call it inline in the .c Regards, Mike Signed-off-by: Russ Dill russ.d...@ti.com --- drivers/clk/clk.c| 14 +++--- include/linux/clk-provider.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 56e4495e..ed01746 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -249,32 +249,32 @@ late_initcall(clk_disable_unused); /***helper functions ***/ -inline const char *__clk_get_name(struct clk *clk) +const char *__clk_get_name(struct clk *clk) { return !clk ? NULL : clk-name; } -inline struct clk_hw *__clk_get_hw(struct clk *clk) +struct clk_hw *__clk_get_hw(struct clk *clk) { return !clk ? NULL : clk-hw; } -inline u8 __clk_get_num_parents(struct clk *clk) +u8 __clk_get_num_parents(struct clk *clk) { return !clk ? -EINVAL : clk-num_parents; } -inline struct clk *__clk_get_parent(struct clk *clk) +struct clk *__clk_get_parent(struct clk *clk) { return !clk ? NULL : clk-parent; } -inline int __clk_get_enable_count(struct clk *clk) +int __clk_get_enable_count(struct clk *clk) { return !clk ? -EINVAL : clk-enable_count; } -inline int __clk_get_prepare_count(struct clk *clk) +int __clk_get_prepare_count(struct clk *clk) { return !clk ? -EINVAL : clk-prepare_count; } @@ -300,7 +300,7 @@ out: return ret; } -inline unsigned long __clk_get_flags(struct clk *clk) +unsigned long __clk_get_flags(struct clk *clk) { return !clk ? -EINVAL : clk-flags; } diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c127315..f9f5e9e 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +int __clk_get_enable_count(struct clk *clk); +int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); int __clk_is_enabled(struct clk *clk); -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Don't mark shared helper functions as inline
The helper functions that access the opaque struct clk should not be marked inline since they are contained in clk.c, but expected to be used by other compilation units. This causes compile errors under gcc-4.7 In file included from arch/arm/mach-omap2/clockdomain.c:25:0: arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: include/linux/clk-provider.h:338:12: error: inlining failed in call to always_inline ‘__clk_get_enable_count’: function body not available arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 Signed-off-by: Russ Dill --- drivers/clk/clk.c| 14 +++--- include/linux/clk-provider.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 56e4495e..ed01746 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -249,32 +249,32 @@ late_initcall(clk_disable_unused); /***helper functions ***/ -inline const char *__clk_get_name(struct clk *clk) +const char *__clk_get_name(struct clk *clk) { return !clk ? NULL : clk->name; } -inline struct clk_hw *__clk_get_hw(struct clk *clk) +struct clk_hw *__clk_get_hw(struct clk *clk) { return !clk ? NULL : clk->hw; } -inline u8 __clk_get_num_parents(struct clk *clk) +u8 __clk_get_num_parents(struct clk *clk) { return !clk ? -EINVAL : clk->num_parents; } -inline struct clk *__clk_get_parent(struct clk *clk) +struct clk *__clk_get_parent(struct clk *clk) { return !clk ? NULL : clk->parent; } -inline int __clk_get_enable_count(struct clk *clk) +int __clk_get_enable_count(struct clk *clk) { return !clk ? -EINVAL : clk->enable_count; } -inline int __clk_get_prepare_count(struct clk *clk) +int __clk_get_prepare_count(struct clk *clk) { return !clk ? -EINVAL : clk->prepare_count; } @@ -300,7 +300,7 @@ out: return ret; } -inline unsigned long __clk_get_flags(struct clk *clk) +unsigned long __clk_get_flags(struct clk *clk) { return !clk ? -EINVAL : clk->flags; } diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c127315..f9f5e9e 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +int __clk_get_enable_count(struct clk *clk); +int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); int __clk_is_enabled(struct clk *clk); -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Don't mark shared helper functions as inline
The helper functions that access the opaque struct clk should not be marked inline since they are contained in clk.c, but expected to be used by other compilation units. This causes compile errors under gcc-4.7 In file included from arch/arm/mach-omap2/clockdomain.c:25:0: arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: include/linux/clk-provider.h:338:12: error: inlining failed in call to always_inline ‘__clk_get_enable_count’: function body not available arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 Signed-off-by: Russ Dill russ.d...@ti.com --- drivers/clk/clk.c| 14 +++--- include/linux/clk-provider.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 56e4495e..ed01746 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -249,32 +249,32 @@ late_initcall(clk_disable_unused); /***helper functions ***/ -inline const char *__clk_get_name(struct clk *clk) +const char *__clk_get_name(struct clk *clk) { return !clk ? NULL : clk-name; } -inline struct clk_hw *__clk_get_hw(struct clk *clk) +struct clk_hw *__clk_get_hw(struct clk *clk) { return !clk ? NULL : clk-hw; } -inline u8 __clk_get_num_parents(struct clk *clk) +u8 __clk_get_num_parents(struct clk *clk) { return !clk ? -EINVAL : clk-num_parents; } -inline struct clk *__clk_get_parent(struct clk *clk) +struct clk *__clk_get_parent(struct clk *clk) { return !clk ? NULL : clk-parent; } -inline int __clk_get_enable_count(struct clk *clk) +int __clk_get_enable_count(struct clk *clk) { return !clk ? -EINVAL : clk-enable_count; } -inline int __clk_get_prepare_count(struct clk *clk) +int __clk_get_prepare_count(struct clk *clk) { return !clk ? -EINVAL : clk-prepare_count; } @@ -300,7 +300,7 @@ out: return ret; } -inline unsigned long __clk_get_flags(struct clk *clk) +unsigned long __clk_get_flags(struct clk *clk) { return !clk ? -EINVAL : clk-flags; } diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c127315..f9f5e9e 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +int __clk_get_enable_count(struct clk *clk); +int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); int __clk_is_enabled(struct clk *clk); -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] Device Tree Overlays Proposal (Was Re: capebus moving omap_devices to mach-omap2)
On Mon, Nov 12, 2012 at 3:23 AM, Pantelis Antoniou wrote: > Hi Grant, > > Sorry for the late comments, travelling... > > On Nov 9, 2012, at 6:28 PM, Grant Likely wrote: > >> On Tue, Nov 6, 2012 at 10:37 PM, Stephen Warren >> wrote: >>> On 11/05/2012 01:40 PM, Grant Likely wrote: Hey folks, As promised, here is my early draft to try and capture what device tree overlays need to do and how to get there. Comments and suggestions greatly appreciated. >>> >>> Interesting. This just came up internally at NVIDIA within the last >>> couple weeks, and was discussed on the U-Boot mailing list very recently >>> too: >>> >>> http://lists.denx.de/pipermail/u-boot/2012-October/thread.html#138227 >>> (it spills into the November archive too) >>> For these cases it is proposed to implement an overlay feature for the so that the initial device tree data can be modified by userspace at >>> >>> I don't know if you're maintaining this as a document and taking patches >>> to it, but if so: >> >> Sure, why not... >> >> http://git.secretlab.ca/?p=devicetree-overlays.git;a=summary >> >>> >>> "for the so" split across those two lines. >> >> fixed >> - SHOULD reliably handle changes between different underlying overlays (ie. what happens to existing .dtb overly files if the structure of the dtb it is layered over changes. If not possible, then SHALL detect when the base tree doesn't match and refuse to apply the overlay. >>> >>> Perhaps use (versioned) DT bindings to represent the interface between >>> the two .dts files? See the links to the U-Boot mailing list discussions >>> below? >> >> Implementing versioning is conceptually a lot more complex than plain >> overlays since it means either the kernel or u-boot needs to start >> filtering the data that it's given. This can get really complex in a >> hurry. Mitch makes a valid point later in this thread that when it >> comes to manipulating the data depending on the board then the data >> overlay model alone doesn't handle it well. >> >> I'm not actually opposed to it, but it needs to be done in an elegant >> way. The DT data model already imposes more of a conceptual learning >> curve than I wish it did and I don't want to make that worse with a >> versioning model that is difficult to get ones head around. >> >> Suggestions and proposals are definitely welcome here. >> > > I didn't find versioning all that difficult TBH. > > Making the property access functions work sanely with versioning > should cover most (if not all) kernel users. > Keep non versioned property access function available to possibly > users with a prefix for those that need it. > >>> - What is the model for overlays? - Can an overlay modify existing properties? - Can an overlay add new properties to existing nodes? - Can an overlay delete existing nodes/properties? >>> >>> This proposal is very oriented at an overlay-based approach. I'm not >>> totally convinced that a pure overlay approach (as in how dtc does >>> overlayed DT nodes) will be flexible enough, but would love to be >>> persuaded. Again see below. >> >> The way I'm currently thinking about the overlay approach is as a >> discrete set of changes that all can be applied at once.* That >> certainly doesn't preclude the change being generated with a script or >> other tool in either firmware or userspace. For most changes it works >> really well. Of the scenarios that don't work well, I can think of >> two. The first is it moving or renaming existing nodes, and the second >> is if the structure of the base tree changes (say due to a firmware >> update). Although the second limitation is specifically with binary >> .dtb overlays. Recompiling the dts overlay against the new tree would >> work fine.** >> > > Atomicity should be handled correctly. I can't imagine how hard would > be to back out a semi-applied overlay without some kind of core DT > tracking support. Leaving it to the driver/user is too difficult to get > right. > > About moving and renaming nodes, I can't think of a user-case today that > needs it. Perhaps it can be handled by removal & re-insertion? > >> *with the caveat that not all types of changes are a good idea and we >> may disallow. For example, is changing properties in existing nodes a >> good idea? > > Yes, changing properties is something that we need. One such change is > the change of the bus controller 'status' properties to enabled upon > insertion of a child device node, and change back to 'on-demand' when > all the child device nodes are gone. Some devices will probably have to support on the fly changes that they may not have otherwise supported. An example of a driver that needs to modify it's device based on DT would be an I²C bus speed change. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at
Re: [RFC] Device Tree Overlays Proposal (Was Re: capebus moving omap_devices to mach-omap2)
On Mon, Nov 12, 2012 at 3:23 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: Hi Grant, Sorry for the late comments, travelling... On Nov 9, 2012, at 6:28 PM, Grant Likely wrote: On Tue, Nov 6, 2012 at 10:37 PM, Stephen Warren swar...@wwwdotorg.org wrote: On 11/05/2012 01:40 PM, Grant Likely wrote: Hey folks, As promised, here is my early draft to try and capture what device tree overlays need to do and how to get there. Comments and suggestions greatly appreciated. Interesting. This just came up internally at NVIDIA within the last couple weeks, and was discussed on the U-Boot mailing list very recently too: http://lists.denx.de/pipermail/u-boot/2012-October/thread.html#138227 (it spills into the November archive too) For these cases it is proposed to implement an overlay feature for the so that the initial device tree data can be modified by userspace at I don't know if you're maintaining this as a document and taking patches to it, but if so: Sure, why not... http://git.secretlab.ca/?p=devicetree-overlays.git;a=summary for the so split across those two lines. fixed - SHOULD reliably handle changes between different underlying overlays (ie. what happens to existing .dtb overly files if the structure of the dtb it is layered over changes. If not possible, then SHALL detect when the base tree doesn't match and refuse to apply the overlay. Perhaps use (versioned) DT bindings to represent the interface between the two .dts files? See the links to the U-Boot mailing list discussions below? Implementing versioning is conceptually a lot more complex than plain overlays since it means either the kernel or u-boot needs to start filtering the data that it's given. This can get really complex in a hurry. Mitch makes a valid point later in this thread that when it comes to manipulating the data depending on the board then the data overlay model alone doesn't handle it well. I'm not actually opposed to it, but it needs to be done in an elegant way. The DT data model already imposes more of a conceptual learning curve than I wish it did and I don't want to make that worse with a versioning model that is difficult to get ones head around. Suggestions and proposals are definitely welcome here. I didn't find versioning all that difficult TBH. Making the property access functions work sanely with versioning should cover most (if not all) kernel users. Keep non versioned property access function available to possibly users with a prefix for those that need it. - What is the model for overlays? - Can an overlay modify existing properties? - Can an overlay add new properties to existing nodes? - Can an overlay delete existing nodes/properties? This proposal is very oriented at an overlay-based approach. I'm not totally convinced that a pure overlay approach (as in how dtc does overlayed DT nodes) will be flexible enough, but would love to be persuaded. Again see below. The way I'm currently thinking about the overlay approach is as a discrete set of changes that all can be applied at once.* That certainly doesn't preclude the change being generated with a script or other tool in either firmware or userspace. For most changes it works really well. Of the scenarios that don't work well, I can think of two. The first is it moving or renaming existing nodes, and the second is if the structure of the base tree changes (say due to a firmware update). Although the second limitation is specifically with binary .dtb overlays. Recompiling the dts overlay against the new tree would work fine.** Atomicity should be handled correctly. I can't imagine how hard would be to back out a semi-applied overlay without some kind of core DT tracking support. Leaving it to the driver/user is too difficult to get right. About moving and renaming nodes, I can't think of a user-case today that needs it. Perhaps it can be handled by removal re-insertion? *with the caveat that not all types of changes are a good idea and we may disallow. For example, is changing properties in existing nodes a good idea? Yes, changing properties is something that we need. One such change is the change of the bus controller 'status' properties to enabled upon insertion of a child device node, and change back to 'on-demand' when all the child device nodes are gone. Some devices will probably have to support on the fly changes that they may not have otherwise supported. An example of a driver that needs to modify it's device based on DT would be an I²C bus speed change. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] Device Tree Overlays Proposal (Was Re: capebus moving omap_devices to mach-omap2)
On Tue, Nov 6, 2012 at 10:35 AM, Tony Lindgren wrote: > * Grant Likely [121106 03:16]: >> On Tue, Nov 6, 2012 at 10:30 AM, Pantelis Antoniou >> wrote: >> > >> > Another can of worms is the pinctrl nodes. >> >> Yes... new pinctrl data would need to trigger adding new data to >> pinctrl. I don't know if the pinctrl api supports that. > > The actual pins stay the same, just their configuration > changes. AFAIK all that is already supported using the > pinctrl framework. > > For example, considering hotplugging capes on the beaglebone: > > 1. You need to map all the sensible modes for the pins exposed >to the capes in the board specific .dts file. This will >add roughly 4 x nr_capbus_pins named modes in the .dts file >so not too bad. > > 2. Claim all the capebus pins during the capbus driver probe >and set them to some safe mode. > > 3. Try to detect the connected cape(s) over i2c. > > 4. Use pinctr_select_state to set the desired modes for >the pins used by the cape(s). > > 5. Enable capebus regulators and clocks etc. > > 6. Load the driver modules for whatever omap internal >devices the cape supports. > > You could also claim the pin for the omap internal > devices instead of claiming them in the capebus, but then > things can get messy with binding and unbinding the > drivers. So just claiming all the pins in the capebus > probably keeps things simpler. That assumes that for a particular external bus, certain pins aren't already shared with functions already on the board, for instance if an I²C bus brought out to the external bus already has a chip connected to it. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] Device Tree Overlays Proposal (Was Re: capebus moving omap_devices to mach-omap2)
On Tue, Nov 6, 2012 at 10:35 AM, Tony Lindgren t...@atomide.com wrote: * Grant Likely grant.lik...@secretlab.ca [121106 03:16]: On Tue, Nov 6, 2012 at 10:30 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: Another can of worms is the pinctrl nodes. Yes... new pinctrl data would need to trigger adding new data to pinctrl. I don't know if the pinctrl api supports that. The actual pins stay the same, just their configuration changes. AFAIK all that is already supported using the pinctrl framework. For example, considering hotplugging capes on the beaglebone: 1. You need to map all the sensible modes for the pins exposed to the capes in the board specific .dts file. This will add roughly 4 x nr_capbus_pins named modes in the .dts file so not too bad. 2. Claim all the capebus pins during the capbus driver probe and set them to some safe mode. 3. Try to detect the connected cape(s) over i2c. 4. Use pinctr_select_state to set the desired modes for the pins used by the cape(s). 5. Enable capebus regulators and clocks etc. 6. Load the driver modules for whatever omap internal devices the cape supports. You could also claim the pin for the omap internal devices instead of claiming them in the capebus, but then things can get messy with binding and unbinding the drivers. So just claiming all the pins in the capebus probably keeps things simpler. That assumes that for a particular external bus, certain pins aren't already shared with functions already on the board, for instance if an I²C bus brought out to the external bus already has a chip connected to it. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Fri, Nov 2, 2012 at 4:00 AM, Felipe Balbi wrote: > Hi, > > On Fri, Nov 02, 2012 at 02:42:51AM -0700, Russ Dill wrote: >> >> browse through various detect functions, yes, some of them key off an >> >> ID, but a lot of them just check various registers to see if certain >> >> bits are zero, or certain bits are one. A lot of I²C devices I've >> >> dealt with have no good way of probing them, especially GPIO chips >> >> (you'll notice none of the I²C GPIO expanders have detect functions) >> > >> > it doesn't mean it can't be done. >> >> Really? Please, do tell how you would write a detect function for a >> PCA9534. It has 4 registers, an input port registers, an output port >> register, a polarity inversion register, and a configuration register. > > read them and match to their reset values, perhaps ? So its ok for it to not work on warm reset? Also, I'm pretty sure [ random, 0xff, 0x00, 0xff ] describes quite a few chips. >> And don't forget, since we are probing, every detect routine for every >> I²C driver will have to run with every I²C address on every bus, >> possibly with both address formats. > > not *every* I2C address. What you say is wrong, a ->detect() method will > only run for those addresses which the device can actually assume. OK, that's still a potentially large number of addresses. >> >> On top of all this the detect routine does not tell you if the alert >> >> pin is connected to some IRQ, or in the case of a GPIO expander, what >> >> those GPIOs are connected to, etc, etc. >> > >> > so what ? All you want to do with detect is figure out if the far end is >> > who you think it is, not what it's doing. >> >> If we already knew who was there, we wouldn't need a detect routine. > > of course not :-) But the whole discussion has been about not knowing > which capes (and thus which devices) are attached to the bone. Eh? Finding out which bone is connected is pretty easy, they all have an EEPROM with identifying information. That isn't the problem that capebus is solving, capebus is solving the problem of enumerating that hardware. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Fri, Nov 2, 2012 at 1:57 AM, Felipe Balbi wrote: > Hi, > > On Thu, Nov 01, 2012 at 04:49:23PM -0700, Russ Dill wrote: >> On Thu, Nov 1, 2012 at 3:05 PM, Felipe Balbi wrote: >> > HI, >> > >> > On Thu, Nov 01, 2012 at 03:59:50PM +0200, Pantelis Antoniou wrote: >> >> Hi Alan, >> >> >> >> On Nov 1, 2012, at 3:51 PM, Alan Cox wrote: >> >> >> >> >> What they want, and what every user wants, is I plug this board in, and >> >> >> the driver make sure everything is loaded and ready. No, the end users >> >> >> don't want to see any of the implementation details of how the bitfile >> >> >> is transported; the driver can handle it. >> >> > >> >> > That doesn't necessarily make it a bus merely some kind of hotplug >> >> > enumeration of devices. That should all work properly both for devices >> >> > and busses with spi and i²c as the final bits needed for it got fixed >> >> > some time ago. >> >> > >> >> > In an ideal world you don't want to be writing custom drivers for stuff. >> >> > If your cape routes an i²c serial device to the existing system i²c >> >> > busses then you want to just create an instance of any existing driver >> >> > on >> >> > the existing i²c bus not create a whole new layer of goop. >> >> > >> >> > It does need to do the plumbing and resource management for the plumbing >> >> > but thats not the same as being a bus. >> >> > >> >> > Alan >> >> >> >> >> >> Fair enough. But there's no such thing a 'hotplug enumeration >> >> construct' in Linux yet, and a bus is the closest thing to it. It does >> >> take advantage of the nice way device code matches drivers and devices >> >> though. >> >> >> >> I'm afraid that having the I2C/SPI drivers doing the detection won't >> >> work. The capes can have arbitrary I2C/SPI devices (and even more >> >> weird components). There is no way to assure for example that the I2C >> >> device responding to address 'foo' in cape A is the same I2C device >> >> responding to the same address in cape B. >> > >> > your ->detect() method should take care of that. >> >> There isn't some magical serial number in I²C devices that a >> ->detect() method can read and the implementation of I²C is somewhat >> flexible. One devices read may be another devices write. A detect > > look at what other drivers do. You can read a revision register, you can > write a command and see if the device responds as expected, it doesn't > matter. Since a "revision" register isn't required by the I²C spec, it isn't implemented on a huge number of chips. Also, having a few dozen probe routines come though and write to random address of every single I²C device can a) take a really long time, and b) have quite a few unintended side effects. >> method that only performs reads could easily toggle a gpio that resets >> the board, rewrite and eeprom, or set the printer on fire. If you > > how ? It's just a read. Because the I²C spec is incredibly flexible. For a lot of devices, reading from a register is done by writing the register address, and then reading the contents. For devices that don't implement registers in that way (such as many eeproms), this is just a write. >> browse through various detect functions, yes, some of them key off an >> ID, but a lot of them just check various registers to see if certain >> bits are zero, or certain bits are one. A lot of I²C devices I've >> dealt with have no good way of probing them, especially GPIO chips >> (you'll notice none of the I²C GPIO expanders have detect functions) > > it doesn't mean it can't be done. Really? Please, do tell how you would write a detect function for a PCA9534. It has 4 registers, an input port registers, an output port register, a polarity inversion register, and a configuration register. And don't forget, since we are probing, every detect routine for every I²C driver will have to run with every I²C address on every bus, possibly with both address formats. >> On top of all this the detect routine does not tell you if the alert >> pin is connected to some IRQ, or in the case of a GPIO expander, what >> those GPIOs are connected to, etc, etc. > > so what ? All you want to do with detect is figure out if the far end is > who you think it is, not what it's doing. If we already knew who was there, we wouldn't need a detect routine. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Fri, Nov 2, 2012 at 1:57 AM, Felipe Balbi ba...@ti.com wrote: Hi, On Thu, Nov 01, 2012 at 04:49:23PM -0700, Russ Dill wrote: On Thu, Nov 1, 2012 at 3:05 PM, Felipe Balbi ba...@ti.com wrote: HI, On Thu, Nov 01, 2012 at 03:59:50PM +0200, Pantelis Antoniou wrote: Hi Alan, On Nov 1, 2012, at 3:51 PM, Alan Cox wrote: What they want, and what every user wants, is I plug this board in, and the driver make sure everything is loaded and ready. No, the end users don't want to see any of the implementation details of how the bitfile is transported; the driver can handle it. That doesn't necessarily make it a bus merely some kind of hotplug enumeration of devices. That should all work properly both for devices and busses with spi and i²c as the final bits needed for it got fixed some time ago. In an ideal world you don't want to be writing custom drivers for stuff. If your cape routes an i²c serial device to the existing system i²c busses then you want to just create an instance of any existing driver on the existing i²c bus not create a whole new layer of goop. It does need to do the plumbing and resource management for the plumbing but thats not the same as being a bus. Alan Fair enough. But there's no such thing a 'hotplug enumeration construct' in Linux yet, and a bus is the closest thing to it. It does take advantage of the nice way device code matches drivers and devices though. I'm afraid that having the I2C/SPI drivers doing the detection won't work. The capes can have arbitrary I2C/SPI devices (and even more weird components). There is no way to assure for example that the I2C device responding to address 'foo' in cape A is the same I2C device responding to the same address in cape B. your -detect() method should take care of that. There isn't some magical serial number in I²C devices that a -detect() method can read and the implementation of I²C is somewhat flexible. One devices read may be another devices write. A detect look at what other drivers do. You can read a revision register, you can write a command and see if the device responds as expected, it doesn't matter. Since a revision register isn't required by the I²C spec, it isn't implemented on a huge number of chips. Also, having a few dozen probe routines come though and write to random address of every single I²C device can a) take a really long time, and b) have quite a few unintended side effects. method that only performs reads could easily toggle a gpio that resets the board, rewrite and eeprom, or set the printer on fire. If you how ? It's just a read. Because the I²C spec is incredibly flexible. For a lot of devices, reading from a register is done by writing the register address, and then reading the contents. For devices that don't implement registers in that way (such as many eeproms), this is just a write. browse through various detect functions, yes, some of them key off an ID, but a lot of them just check various registers to see if certain bits are zero, or certain bits are one. A lot of I²C devices I've dealt with have no good way of probing them, especially GPIO chips (you'll notice none of the I²C GPIO expanders have detect functions) it doesn't mean it can't be done. Really? Please, do tell how you would write a detect function for a PCA9534. It has 4 registers, an input port registers, an output port register, a polarity inversion register, and a configuration register. And don't forget, since we are probing, every detect routine for every I²C driver will have to run with every I²C address on every bus, possibly with both address formats. On top of all this the detect routine does not tell you if the alert pin is connected to some IRQ, or in the case of a GPIO expander, what those GPIOs are connected to, etc, etc. so what ? All you want to do with detect is figure out if the far end is who you think it is, not what it's doing. If we already knew who was there, we wouldn't need a detect routine. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Fri, Nov 2, 2012 at 4:00 AM, Felipe Balbi ba...@ti.com wrote: Hi, On Fri, Nov 02, 2012 at 02:42:51AM -0700, Russ Dill wrote: browse through various detect functions, yes, some of them key off an ID, but a lot of them just check various registers to see if certain bits are zero, or certain bits are one. A lot of I²C devices I've dealt with have no good way of probing them, especially GPIO chips (you'll notice none of the I²C GPIO expanders have detect functions) it doesn't mean it can't be done. Really? Please, do tell how you would write a detect function for a PCA9534. It has 4 registers, an input port registers, an output port register, a polarity inversion register, and a configuration register. read them and match to their reset values, perhaps ? So its ok for it to not work on warm reset? Also, I'm pretty sure [ random, 0xff, 0x00, 0xff ] describes quite a few chips. And don't forget, since we are probing, every detect routine for every I²C driver will have to run with every I²C address on every bus, possibly with both address formats. not *every* I2C address. What you say is wrong, a -detect() method will only run for those addresses which the device can actually assume. OK, that's still a potentially large number of addresses. On top of all this the detect routine does not tell you if the alert pin is connected to some IRQ, or in the case of a GPIO expander, what those GPIOs are connected to, etc, etc. so what ? All you want to do with detect is figure out if the far end is who you think it is, not what it's doing. If we already knew who was there, we wouldn't need a detect routine. of course not :-) But the whole discussion has been about not knowing which capes (and thus which devices) are attached to the bone. Eh? Finding out which bone is connected is pretty easy, they all have an EEPROM with identifying information. That isn't the problem that capebus is solving, capebus is solving the problem of enumerating that hardware. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Thu, Nov 1, 2012 at 3:05 PM, Felipe Balbi wrote: > HI, > > On Thu, Nov 01, 2012 at 03:59:50PM +0200, Pantelis Antoniou wrote: >> Hi Alan, >> >> On Nov 1, 2012, at 3:51 PM, Alan Cox wrote: >> >> >> What they want, and what every user wants, is I plug this board in, and >> >> the driver make sure everything is loaded and ready. No, the end users >> >> don't want to see any of the implementation details of how the bitfile >> >> is transported; the driver can handle it. >> > >> > That doesn't necessarily make it a bus merely some kind of hotplug >> > enumeration of devices. That should all work properly both for devices >> > and busses with spi and i²c as the final bits needed for it got fixed >> > some time ago. >> > >> > In an ideal world you don't want to be writing custom drivers for stuff. >> > If your cape routes an i²c serial device to the existing system i²c >> > busses then you want to just create an instance of any existing driver on >> > the existing i²c bus not create a whole new layer of goop. >> > >> > It does need to do the plumbing and resource management for the plumbing >> > but thats not the same as being a bus. >> > >> > Alan >> >> >> Fair enough. But there's no such thing a 'hotplug enumeration >> construct' in Linux yet, and a bus is the closest thing to it. It does >> take advantage of the nice way device code matches drivers and devices >> though. >> >> I'm afraid that having the I2C/SPI drivers doing the detection won't >> work. The capes can have arbitrary I2C/SPI devices (and even more >> weird components). There is no way to assure for example that the I2C >> device responding to address 'foo' in cape A is the same I2C device >> responding to the same address in cape B. > > your ->detect() method should take care of that. There isn't some magical serial number in I²C devices that a ->detect() method can read and the implementation of I²C is somewhat flexible. One devices read may be another devices write. A detect method that only performs reads could easily toggle a gpio that resets the board, rewrite and eeprom, or set the printer on fire. If you browse through various detect functions, yes, some of them key off an ID, but a lot of them just check various registers to see if certain bits are zero, or certain bits are one. A lot of I²C devices I've dealt with have no good way of probing them, especially GPIO chips (you'll notice none of the I²C GPIO expanders have detect functions) On top of all this the detect routine does not tell you if the alert pin is connected to some IRQ, or in the case of a GPIO expander, what those GPIOs are connected to, etc, etc. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/3] capebus moving omap_devices to mach-omap2
On Thu, Nov 1, 2012 at 3:05 PM, Felipe Balbi ba...@ti.com wrote: HI, On Thu, Nov 01, 2012 at 03:59:50PM +0200, Pantelis Antoniou wrote: Hi Alan, On Nov 1, 2012, at 3:51 PM, Alan Cox wrote: What they want, and what every user wants, is I plug this board in, and the driver make sure everything is loaded and ready. No, the end users don't want to see any of the implementation details of how the bitfile is transported; the driver can handle it. That doesn't necessarily make it a bus merely some kind of hotplug enumeration of devices. That should all work properly both for devices and busses with spi and i²c as the final bits needed for it got fixed some time ago. In an ideal world you don't want to be writing custom drivers for stuff. If your cape routes an i²c serial device to the existing system i²c busses then you want to just create an instance of any existing driver on the existing i²c bus not create a whole new layer of goop. It does need to do the plumbing and resource management for the plumbing but thats not the same as being a bus. Alan Fair enough. But there's no such thing a 'hotplug enumeration construct' in Linux yet, and a bus is the closest thing to it. It does take advantage of the nice way device code matches drivers and devices though. I'm afraid that having the I2C/SPI drivers doing the detection won't work. The capes can have arbitrary I2C/SPI devices (and even more weird components). There is no way to assure for example that the I2C device responding to address 'foo' in cape A is the same I2C device responding to the same address in cape B. your -detect() method should take care of that. There isn't some magical serial number in I²C devices that a -detect() method can read and the implementation of I²C is somewhat flexible. One devices read may be another devices write. A detect method that only performs reads could easily toggle a gpio that resets the board, rewrite and eeprom, or set the printer on fire. If you browse through various detect functions, yes, some of them key off an ID, but a lot of them just check various registers to see if certain bits are zero, or certain bits are one. A lot of I²C devices I've dealt with have no good way of probing them, especially GPIO chips (you'll notice none of the I²C GPIO expanders have detect functions) On top of all this the detect routine does not tell you if the alert pin is connected to some IRQ, or in the case of a GPIO expander, what those GPIOs are connected to, etc, etc. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 1/7] capebus: Core capebus support
On Wed, Oct 31, 2012 at 3:07 PM, Pantelis Antoniou wrote: > > On Oct 31, 2012, at 11:55 PM, Russ Dill wrote: > >> On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou >> wrote: >>> Introducing capebus; a bus that allows small boards (capes) to connect >>> to a complex SoC using simple expansion connectors. >>> > > [snip] >>> + if (drv) { >>> + /* call the removed bus method (if added prev.) */ >>> + if (cape_dev->added) { >>> + BUG_ON(cape_dev->bus == NULL); >>> + BUG_ON(cape_dev->bus->ops == NULL); >>> + if (cape_dev->bus->ops->dev_removed) >>> + cape_dev->bus->ops->dev_removed(cape_dev); >>> + cape_dev->added = 0; >>> + } >> >> Is there any case where added will not track drv? > > > Yes, there is a corner case here. > > There is the case where while the device is created there is no matching > driver yet. Either that's the case of a not supported cape, or the > cape driver hasn't been loaded yet. > > We do need the device to be created, so that the user can browse in the > sysfs it's eeprom attributes. > > There's some further complications with runtime cape overrides, but > that's the gist of it. I'm trying to figure out how that would come about, here is where added is set to 1: + /* all is fine... */ + cape_dev->driver = drv; + cape_dev->added = 1; This is after calling drv->probe, so drv is not null. There is a brief time here where added is 0, but driver is not. + if (drv) { + /* call the removed bus method (if added prev.) */ + if (cape_dev->added) { + BUG_ON(cape_dev->bus == NULL); + BUG_ON(cape_dev->bus->ops == NULL); + if (cape_dev->bus->ops->dev_removed) + cape_dev->bus->ops->dev_removed(cape_dev); + cape_dev->added = 0; + } + if (drv->remove) { + pm_runtime_get_sync(dev); + drv->remove(cape_dev); + pm_runtime_put_noidle(dev); + } + cape_dev->driver = NULL; Is one of the remove or resume functions check added in this case? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 0/7] Capebus; a bus for SoCs using simple expansion connectors
On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou wrote: > Capebus is created to address the problem of many SoCs that can provide a > multitude of hardware interfaces but in order to keep costs down the main > boards only support a limited number of them. The rest are typically brought > out to pin connectors on to which other boards, named capes are connected and > allow those peripherals to be used. > > These capes connect to the SoC interfaces but might also contain various other > parts that may need some kind of driver to work. > > Since SoCs have limited pins and pin muxing options, not all capes can work > together so some kind of resource tracking (at least for the pins in use) is > required. > > Before capebus all of this took place in the board support file, and frankly > for boards with too many capes it was becoming unmanageable. > > Capebus provides a virtual bus, which along with a board specific controller, > cape drivers can be written using the standard Linux device model. > > The core capebus infrastructure is not depended on any specific board. > However capebus needs a board controller to provide services to the cape > devices > it controls. Services like addressing and resource reservation are provided > by the board controller. > > Capebus at the moment only support TI's Beaglebone platform. > > This RFC introduces the core concept; most supporting patches > have been posted to the relevant places. There are quite a few TODOs in the code, any chance you could summarize them in the next header email? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 1/7] capebus: Core capebus support
On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou wrote: > Introducing capebus; a bus that allows small boards (capes) to connect > to a complex SoC using simple expansion connectors. > > Up to now to support these kind of boards, one had to hack the board files, > and do all sort of gymnastics to handle all the different cases of > conflict resolution. > > Capebus provides abstractions that keep the pain to a minimum. > > This part of the series is introducing the core capebus functionality > dealing with the basic bus & driver probe functions. > > Signed-off-by: Pantelis Antoniou > --- > drivers/Kconfig | 2 + > drivers/Makefile | 3 + > drivers/capebus/Kconfig | 17 ++ > drivers/capebus/Makefile | 8 + > drivers/capebus/capebus-driver.c | 608 > +++ > drivers/capebus/capebus-probe.c | 320 + > drivers/capebus/capebus-sysfs.c | 52 > include/linux/capebus.h | 298 +++ > 8 files changed, 1308 insertions(+) > create mode 100644 drivers/capebus/Kconfig > create mode 100644 drivers/capebus/Makefile > create mode 100644 drivers/capebus/capebus-driver.c > create mode 100644 drivers/capebus/capebus-probe.c > create mode 100644 drivers/capebus/capebus-sysfs.c > create mode 100644 include/linux/capebus.h > > diff --git a/drivers/Kconfig b/drivers/Kconfig > index dbdefa3..bfbe1d1 100644 > --- a/drivers/Kconfig > +++ b/drivers/Kconfig > @@ -156,4 +156,6 @@ source "drivers/pwm/Kconfig" > > source "drivers/irqchip/Kconfig" > > +source "drivers/capebus/Kconfig" > + > endmenu > diff --git a/drivers/Makefile b/drivers/Makefile > index a16a8d0..d7a103b 100644 > --- a/drivers/Makefile > +++ b/drivers/Makefile > @@ -145,3 +145,6 @@ obj-$(CONFIG_EXTCON)+= extcon/ > obj-$(CONFIG_MEMORY) += memory/ > obj-$(CONFIG_IIO) += iio/ > obj-$(CONFIG_VME_BUS) += vme/ > + > +# Capebus > +obj-$(CONFIG_CAPEBUS) += capebus/ > diff --git a/drivers/capebus/Kconfig b/drivers/capebus/Kconfig > new file mode 100644 > index 000..cea1b68 > --- /dev/null > +++ b/drivers/capebus/Kconfig > @@ -0,0 +1,17 @@ > +# > +# Capebus core support > +# > + > +menu "CAPEBUS support" > + > +config CAPEBUS > + bool "Capebus support" > + default n > + help > + Enable to support capebus devices. > + > +source "drivers/capebus/boards/Kconfig" > + > +source "drivers/capebus/capes/Kconfig" > + > +endmenu > diff --git a/drivers/capebus/Makefile b/drivers/capebus/Makefile > new file mode 100644 > index 000..45aa303 > --- /dev/null > +++ b/drivers/capebus/Makefile > @@ -0,0 +1,8 @@ > +# > +# Makefile for CAPEBUS devices > +# > + > +obj-$(CONFIG_CAPEBUS) += capebus-probe.o \ > + capebus-driver.o capebus-sysfs.o > +obj-$(CONFIG_CAPEBUS) += boards/ > +obj-$(CONFIG_CAPEBUS) += capes/ > diff --git a/drivers/capebus/capebus-driver.c > b/drivers/capebus/capebus-driver.c > new file mode 100644 > index 000..82b1d1b > --- /dev/null > +++ b/drivers/capebus/capebus-driver.c > @@ -0,0 +1,608 @@ > +/* > + * Capebus driver infrastructure > + * > + * Copyright (C) 2012 Pantelis Antoniou > + * Copyright (C) 2012 Texas Instruments Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include > + > +/** > + * capebus_match_device - Tell if a cape device structure has a > + *matching cape device id structure > + * @drv: the cape driver to match against > + * @dev: the cape device structure to match against > + * > + * Used by a driver to check whether a cape device present in the > + * system is in its list of supported devices. Returns the matching > + * cape_device_id structure or %NULL if there is no match. > + */ > +static const struct cape_device_id *capebus_match_device( > + struct cape_driver *drv, struct cape_dev *dev) > +{ > + struct cape_bus *bus = dev->bus; > + struct cape_slot *slot = dev->slot; > + > + BUG_ON(bus == NULL); > + BUG_ON(slot
Re: [RFC 1/7] capebus: Core capebus support
On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: Introducing capebus; a bus that allows small boards (capes) to connect to a complex SoC using simple expansion connectors. Up to now to support these kind of boards, one had to hack the board files, and do all sort of gymnastics to handle all the different cases of conflict resolution. Capebus provides abstractions that keep the pain to a minimum. This part of the series is introducing the core capebus functionality dealing with the basic bus driver probe functions. Signed-off-by: Pantelis Antoniou pa...@antoniou-consulting.com --- drivers/Kconfig | 2 + drivers/Makefile | 3 + drivers/capebus/Kconfig | 17 ++ drivers/capebus/Makefile | 8 + drivers/capebus/capebus-driver.c | 608 +++ drivers/capebus/capebus-probe.c | 320 + drivers/capebus/capebus-sysfs.c | 52 include/linux/capebus.h | 298 +++ 8 files changed, 1308 insertions(+) create mode 100644 drivers/capebus/Kconfig create mode 100644 drivers/capebus/Makefile create mode 100644 drivers/capebus/capebus-driver.c create mode 100644 drivers/capebus/capebus-probe.c create mode 100644 drivers/capebus/capebus-sysfs.c create mode 100644 include/linux/capebus.h diff --git a/drivers/Kconfig b/drivers/Kconfig index dbdefa3..bfbe1d1 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -156,4 +156,6 @@ source drivers/pwm/Kconfig source drivers/irqchip/Kconfig +source drivers/capebus/Kconfig + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index a16a8d0..d7a103b 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -145,3 +145,6 @@ obj-$(CONFIG_EXTCON)+= extcon/ obj-$(CONFIG_MEMORY) += memory/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_VME_BUS) += vme/ + +# Capebus +obj-$(CONFIG_CAPEBUS) += capebus/ diff --git a/drivers/capebus/Kconfig b/drivers/capebus/Kconfig new file mode 100644 index 000..cea1b68 --- /dev/null +++ b/drivers/capebus/Kconfig @@ -0,0 +1,17 @@ +# +# Capebus core support +# + +menu CAPEBUS support + +config CAPEBUS + bool Capebus support + default n + help + Enable to support capebus devices. + +source drivers/capebus/boards/Kconfig + +source drivers/capebus/capes/Kconfig + +endmenu diff --git a/drivers/capebus/Makefile b/drivers/capebus/Makefile new file mode 100644 index 000..45aa303 --- /dev/null +++ b/drivers/capebus/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for CAPEBUS devices +# + +obj-$(CONFIG_CAPEBUS) += capebus-probe.o \ + capebus-driver.o capebus-sysfs.o +obj-$(CONFIG_CAPEBUS) += boards/ +obj-$(CONFIG_CAPEBUS) += capes/ diff --git a/drivers/capebus/capebus-driver.c b/drivers/capebus/capebus-driver.c new file mode 100644 index 000..82b1d1b --- /dev/null +++ b/drivers/capebus/capebus-driver.c @@ -0,0 +1,608 @@ +/* + * Capebus driver infrastructure + * + * Copyright (C) 2012 Pantelis Antoniou pa...@antoniou-consulting.com + * Copyright (C) 2012 Texas Instruments Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include linux/module.h +#include linux/init.h +#include linux/device.h +#include linux/mempolicy.h +#include linux/string.h +#include linux/slab.h +#include linux/cpu.h +#include linux/pm_runtime.h +#include linux/suspend.h + +#include linux/of.h +#include linux/of_device.h +#include linux/of_platform.h + +#include linux/capebus.h + +/** + * capebus_match_device - Tell if a cape device structure has a + *matching cape device id structure + * @drv: the cape driver to match against + * @dev: the cape device structure to match against + * + * Used by a driver to check whether a cape device present in the + * system is in its list of supported devices. Returns the matching + * cape_device_id structure or %NULL if there is no match. + */ +static const struct cape_device_id *capebus_match_device( + struct cape_driver *drv, struct cape_dev *dev) +{ + struct cape_bus *bus =
Re: [RFC 0/7] Capebus; a bus for SoCs using simple expansion connectors
On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: Capebus is created to address the problem of many SoCs that can provide a multitude of hardware interfaces but in order to keep costs down the main boards only support a limited number of them. The rest are typically brought out to pin connectors on to which other boards, named capes are connected and allow those peripherals to be used. These capes connect to the SoC interfaces but might also contain various other parts that may need some kind of driver to work. Since SoCs have limited pins and pin muxing options, not all capes can work together so some kind of resource tracking (at least for the pins in use) is required. Before capebus all of this took place in the board support file, and frankly for boards with too many capes it was becoming unmanageable. Capebus provides a virtual bus, which along with a board specific controller, cape drivers can be written using the standard Linux device model. The core capebus infrastructure is not depended on any specific board. However capebus needs a board controller to provide services to the cape devices it controls. Services like addressing and resource reservation are provided by the board controller. Capebus at the moment only support TI's Beaglebone platform. This RFC introduces the core concept; most supporting patches have been posted to the relevant places. There are quite a few TODOs in the code, any chance you could summarize them in the next header email? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC 1/7] capebus: Core capebus support
On Wed, Oct 31, 2012 at 3:07 PM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: On Oct 31, 2012, at 11:55 PM, Russ Dill wrote: On Wed, Oct 31, 2012 at 9:52 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: Introducing capebus; a bus that allows small boards (capes) to connect to a complex SoC using simple expansion connectors. [snip] + if (drv) { + /* call the removed bus method (if added prev.) */ + if (cape_dev-added) { + BUG_ON(cape_dev-bus == NULL); + BUG_ON(cape_dev-bus-ops == NULL); + if (cape_dev-bus-ops-dev_removed) + cape_dev-bus-ops-dev_removed(cape_dev); + cape_dev-added = 0; + } Is there any case where added will not track drv? Yes, there is a corner case here. There is the case where while the device is created there is no matching driver yet. Either that's the case of a not supported cape, or the cape driver hasn't been loaded yet. We do need the device to be created, so that the user can browse in the sysfs it's eeprom attributes. There's some further complications with runtime cape overrides, but that's the gist of it. I'm trying to figure out how that would come about, here is where added is set to 1: + /* all is fine... */ + cape_dev-driver = drv; + cape_dev-added = 1; This is after calling drv-probe, so drv is not null. There is a brief time here where added is 0, but driver is not. + if (drv) { + /* call the removed bus method (if added prev.) */ + if (cape_dev-added) { + BUG_ON(cape_dev-bus == NULL); + BUG_ON(cape_dev-bus-ops == NULL); + if (cape_dev-bus-ops-dev_removed) + cape_dev-bus-ops-dev_removed(cape_dev); + cape_dev-added = 0; + } + if (drv-remove) { + pm_runtime_get_sync(dev); + drv-remove(cape_dev); + pm_runtime_put_noidle(dev); + } + cape_dev-driver = NULL; Is one of the remove or resume functions check added in this case? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ti_tscadc: Match mfd sub devices to regmap interface
On Wed, Oct 31, 2012 at 8:55 AM, Pantelis Antoniou wrote: > The MFD parent device now uses a regmap, instead of direct > memory access. Use the same method in the sub devices to avoid > nasty surprises. > > Also rework the channel initialization of tiadc a bit. > > Signed-off-by: Pantelis Antoniou > --- > drivers/iio/adc/ti_am335x_adc.c | 27 +++ > drivers/input/touchscreen/ti_am335x_tsc.c | 16 +--- > drivers/mfd/ti_am335x_tscadc.c| 7 +-- > 3 files changed, 37 insertions(+), 13 deletions(-) > > diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c > index d48fd79..5f325c1 100644 > --- a/drivers/iio/adc/ti_am335x_adc.c > +++ b/drivers/iio/adc/ti_am335x_adc.c > @@ -23,7 +23,9 @@ > #include > #include > #include > +#include > > +#include > #include > #include > > @@ -36,13 +38,17 @@ struct tiadc_device { > > static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) > { > - return readl(adc->mfd_tscadc->tscadc_base + reg); > + unsigned int val; > + > + val = (unsigned int)-1; > + regmap_read(adc->mfd_tscadc->regmap_tscadc, reg, ); > + return val; > } Would it be cleaner to instead do: static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) { unsigned int val; return regmap_read(adc->mfd_tscadc->regmap_tscadc, reg, ) ? : val; } or int ret; ret = regmap_read(adc->mfd_tscadc->regmap_tscadc, reg, ); return ret < 0 ret ? : val; > static void tiadc_writel(struct tiadc_device *adc, unsigned int reg, > unsigned int val) > { > - writel(val, adc->mfd_tscadc->tscadc_base + reg); > + regmap_write(adc->mfd_tscadc->regmap_tscadc, reg, val); > } > > static void tiadc_step_config(struct tiadc_device *adc_dev) > @@ -75,22 +81,24 @@ static void tiadc_step_config(struct tiadc_device > *adc_dev) > tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); > } > > -static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) > +static int tiadc_channel_init(struct iio_dev *indio_dev, > + struct tiadc_device *adc_dev) > { > struct iio_chan_spec *chan_array; > struct iio_chan_spec *chan; > char *s; > int i, len, size, ret; > + int channels = adc_dev->channels; > > - size = indio_dev->num_channels * (sizeof(struct iio_chan_spec) + 6); > + size = channels * (sizeof(struct iio_chan_spec) + 6); > chan_array = kzalloc(size, GFP_KERNEL); > if (chan_array == NULL) > return -ENOMEM; > > /* buffer space is after the array */ > - s = (char *)(chan_array + indio_dev->num_channels); > + s = (char *)(chan_array + channels); > chan = chan_array; > - for (i = 0; i < indio_dev->num_channels; i++, chan++, s += len + 1) { > + for (i = 0; i < channels; i++, chan++, s += len + 1) { > > len = sprintf(s, "AIN%d", i); > > @@ -105,8 +113,9 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, > int channels) > } > > indio_dev->channels = chan_array; > + indio_dev->num_channels = channels; > > - size = (indio_dev->num_channels + 1) * sizeof(struct iio_map); > + size = (channels + 1) * sizeof(struct iio_map); > adc_dev->map = kzalloc(size, GFP_KERNEL); > if (adc_dev->map == NULL) { > kfree(chan_array); > @@ -203,7 +212,7 @@ static int __devinit tiadc_probe(struct platform_device > *pdev) > > tiadc_step_config(adc_dev); > > - err = tiadc_channel_init(indio_dev, adc_dev->channels); > + err = tiadc_channel_init(indio_dev, adc_dev); > if (err < 0) > goto err_free_device; > > @@ -213,6 +222,8 @@ static int __devinit tiadc_probe(struct platform_device > *pdev) > > platform_set_drvdata(pdev, indio_dev); > > + dev_info(>dev, "Initialized\n"); > + > return 0; > > err_free_channels: > diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c > b/drivers/input/touchscreen/ti_am335x_tsc.c > index 7a26810..d09e1a7 100644 > --- a/drivers/input/touchscreen/ti_am335x_tsc.c > +++ b/drivers/input/touchscreen/ti_am335x_tsc.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include > > @@ -64,13 +65,17 @@ struct titsc { > > static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) > { > - return readl(ts->mfd_tscadc->tscadc_base + reg); > + unsigned int val; > + > + val = (unsigned int)-1; > + regmap_read(ts->mfd_tscadc->regmap_tscadc, reg, ); > + return val; > } > > static void titsc_writel(struct titsc *tsc, unsigned int reg, > unsigned int val) > { > - writel(val, tsc->mfd_tscadc->tscadc_base + reg); > + regmap_write(tsc->mfd_tscadc->regmap_tscadc, reg, val); > } > > /* > @@ -455,10
Re: [PATCH] ti_tscadc: Match mfd sub devices to regmap interface
On Wed, Oct 31, 2012 at 8:55 AM, Pantelis Antoniou pa...@antoniou-consulting.com wrote: The MFD parent device now uses a regmap, instead of direct memory access. Use the same method in the sub devices to avoid nasty surprises. Also rework the channel initialization of tiadc a bit. Signed-off-by: Pantelis Antoniou pa...@antoniou-consulting.com --- drivers/iio/adc/ti_am335x_adc.c | 27 +++ drivers/input/touchscreen/ti_am335x_tsc.c | 16 +--- drivers/mfd/ti_am335x_tscadc.c| 7 +-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index d48fd79..5f325c1 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c @@ -23,7 +23,9 @@ #include linux/iio/iio.h #include linux/iio/machine.h #include linux/iio/driver.h +#include linux/regmap.h +#include linux/io.h #include linux/mfd/ti_am335x_tscadc.h #include linux/platform_data/ti_am335x_adc.h @@ -36,13 +38,17 @@ struct tiadc_device { static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) { - return readl(adc-mfd_tscadc-tscadc_base + reg); + unsigned int val; + + val = (unsigned int)-1; + regmap_read(adc-mfd_tscadc-regmap_tscadc, reg, val); + return val; } Would it be cleaner to instead do: static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) { unsigned int val; return regmap_read(adc-mfd_tscadc-regmap_tscadc, reg, val) ? : val; } or int ret; ret = regmap_read(adc-mfd_tscadc-regmap_tscadc, reg, val); return ret 0 ret ? : val; static void tiadc_writel(struct tiadc_device *adc, unsigned int reg, unsigned int val) { - writel(val, adc-mfd_tscadc-tscadc_base + reg); + regmap_write(adc-mfd_tscadc-regmap_tscadc, reg, val); } static void tiadc_step_config(struct tiadc_device *adc_dev) @@ -75,22 +81,24 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); } -static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) +static int tiadc_channel_init(struct iio_dev *indio_dev, + struct tiadc_device *adc_dev) { struct iio_chan_spec *chan_array; struct iio_chan_spec *chan; char *s; int i, len, size, ret; + int channels = adc_dev-channels; - size = indio_dev-num_channels * (sizeof(struct iio_chan_spec) + 6); + size = channels * (sizeof(struct iio_chan_spec) + 6); chan_array = kzalloc(size, GFP_KERNEL); if (chan_array == NULL) return -ENOMEM; /* buffer space is after the array */ - s = (char *)(chan_array + indio_dev-num_channels); + s = (char *)(chan_array + channels); chan = chan_array; - for (i = 0; i indio_dev-num_channels; i++, chan++, s += len + 1) { + for (i = 0; i channels; i++, chan++, s += len + 1) { len = sprintf(s, AIN%d, i); @@ -105,8 +113,9 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) } indio_dev-channels = chan_array; + indio_dev-num_channels = channels; - size = (indio_dev-num_channels + 1) * sizeof(struct iio_map); + size = (channels + 1) * sizeof(struct iio_map); adc_dev-map = kzalloc(size, GFP_KERNEL); if (adc_dev-map == NULL) { kfree(chan_array); @@ -203,7 +212,7 @@ static int __devinit tiadc_probe(struct platform_device *pdev) tiadc_step_config(adc_dev); - err = tiadc_channel_init(indio_dev, adc_dev-channels); + err = tiadc_channel_init(indio_dev, adc_dev); if (err 0) goto err_free_device; @@ -213,6 +222,8 @@ static int __devinit tiadc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); + dev_info(pdev-dev, Initialized\n); + return 0; err_free_channels: diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 7a26810..d09e1a7 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -26,6 +26,7 @@ #include linux/io.h #include linux/input/ti_am335x_tsc.h #include linux/delay.h +#include linux/regmap.h #include linux/mfd/ti_am335x_tscadc.h @@ -64,13 +65,17 @@ struct titsc { static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) { - return readl(ts-mfd_tscadc-tscadc_base + reg); + unsigned int val; + + val = (unsigned int)-1; + regmap_read(ts-mfd_tscadc-regmap_tscadc, reg, val); + return val; } static void titsc_writel(struct titsc *tsc, unsigned int reg, unsigned int val) { -
Re: [RFC PATCH v3 00/16] DMA Engine support for AM33XX
On Thu, Oct 18, 2012 at 6:26 AM, Matt Porter wrote: > Changes since v2: > - Rebased on 3.7-rc1 > - Fixed bug in DT/pdata parsing first found by Gururaja > that turned out to be masked by some toolchains > - Dropped unused mach-omap2/devices.c hsmmc patch > - Added AM33XX crossbar DMA event mux support > - Added am335x-evm support > > Changes since v1: > - Rebased on top of mainline from 12250d8 > - Dropped the feature removal schedule patch > - Implemented dma_request_slave_channel_compat() and > converted the mmc and spi drivers to use it > - Dropped unneeded #address-cells and #size-cells from > EDMA DT support > - Moved private EDMA header to linux/platform_data/ and > removed some unneeded definitions > - Fixed parsing of optional properties > > TODO: > - Add dmaengine support for per-channel caps so the > hack to set the maximum segments can be replaced with > a query to the dmaengine driver > > This series adds DMA Engine support for AM33xx, which uses > an EDMA DMAC. The EDMA DMAC has been previously supported by only > a private API implementation (much like the situation with OMAP > DMA) found on the DaVinci family of SoCs. This pretty far along and looks great. Reviewed-by: russ.d...@ti.com > The series applies on top of 3.7-rc1 and the following patches: > > - GPMC fails to reserve memory fix: > http://www.spinics.net/lists/linux-omap/msg79675.html > - TPS65910 regulator fix: > https://patchwork.kernel.org/patch/1593651/ > - dmaengine DT support from Vinod's dmaengine_dt branch in > git://git.infradead.org/users/vkoul/slave-dma.git since > 027478851791df751176398be02a3b1c5f6aa824 > > The approach taken is similar to how OMAP DMA is being converted to > DMA Engine support. With the functional EDMA private API already > existing in mach-davinci/dma.c, we first move that to an ARM common > area so it can be shared. Adding DT and runtime PM support to the > private EDMA API implementation allows it to run on AM33xx. AM33xx > *only* boots using DT so we leverage Jon's generic DT DMA helpers to > register EDMA DMAC with the of_dma framework and then add support > for calling the dma_request_slave_channel() API to both the mmc > and spi drivers. > > With this series both BeagleBone and the AM335x EVM have working > MMC and SPI support. > > This is tested on BeagleBone with a SPI framebuffer driver and MMC > rootfs. A trivial gpio DMA event misc driver was used to test the > crossbar DMA event support. It is also tested on the AM335x EVM > with the onboard SPI flash and MMC rootfs. The branch at > https://github.com/ohporter/linux/tree/edma-dmaengine-v3 has the > complete series, dependencies, and some test drivers/defconfigs. > > Regression testing was done on AM180x-EVM (which also makes use > of the EDMA dmaengine driver and the EDMA private API) using SD, > SPI flash, and the onboard audio supported by the ASoC Davinci > driver. > > After this series, the plan is to convert the last in-tree user > of the private EDMA API (davinci-pcm/mcasp) and then eliminate > the private EDMA API by folding its functionality into > drivers/dma/edma.c. > > Matt Porter (16): > dmaengine: edma: fix slave config dependency on direction > ARM: davinci: move private EDMA API to arm/common > ARM: edma: remove unused transfer controller handlers > ARM: edma: add DT and runtime PM support for AM33XX > ARM: edma: add AM33XX crossbar event support > dmaengine: edma: enable build for AM33XX > dmaengine: edma: Add TI EDMA device tree binding > ARM: dts: add AM33XX EDMA support > dmaengine: add dma_request_slave_channel_compat() > mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() > mmc: omap_hsmmc: limit max_segs with the EDMA DMAC > mmc: omap_hsmmc: add generic DMA request support to the DT binding > ARM: dts: add AM33XX MMC support > spi: omap2-mcspi: convert to dma_request_slave_channel_compat() > spi: omap2-mcspi: add generic DMA request support to the DT binding > ARM: dts: add AM33XX SPI support > > Documentation/devicetree/bindings/dma/ti-edma.txt | 51 + > .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 25 +- > Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- > arch/arm/Kconfig |1 + > arch/arm/boot/dts/am335x-bone.dts | 23 + > arch/arm/boot/dts/am335x-evm.dts | 15 + > arch/arm/boot/dts/am33xx.dtsi | 101 ++ > arch/arm/common/Kconfig|3 + > arch/arm/common/Makefile |1 + > arch/arm/common/edma.c | 1841 > > arch/arm/mach-davinci/Makefile |2 +- > arch/arm/mach-davinci/board-da830-evm.c|
Re: [RFC PATCH v3 00/16] DMA Engine support for AM33XX
On Thu, Oct 18, 2012 at 6:26 AM, Matt Porter mpor...@ti.com wrote: Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties TODO: - Add dmaengine support for per-channel caps so the hack to set the maximum segments can be replaced with a query to the dmaengine driver This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. This pretty far along and looks great. Reviewed-by: russ.d...@ti.com The series applies on top of 3.7-rc1 and the following patches: - GPMC fails to reserve memory fix: http://www.spinics.net/lists/linux-omap/msg79675.html - TPS65910 regulator fix: https://patchwork.kernel.org/patch/1593651/ - dmaengine DT support from Vinod's dmaengine_dt branch in git://git.infradead.org/users/vkoul/slave-dma.git since 027478851791df751176398be02a3b1c5f6aa824 The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working MMC and SPI support. This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-v3 has the complete series, dependencies, and some test drivers/defconfigs. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. After this series, the plan is to convert the last in-tree user of the private EDMA API (davinci-pcm/mcasp) and then eliminate the private EDMA API by folding its functionality into drivers/dma/edma.c. Matt Porter (16): dmaengine: edma: fix slave config dependency on direction ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add DT and runtime PM support for AM33XX ARM: edma: add AM33XX crossbar event support dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() mmc: omap_hsmmc: limit max_segs with the EDMA DMAC mmc: omap_hsmmc: add generic DMA request support to the DT binding ARM: dts: add AM33XX MMC support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI support Documentation/devicetree/bindings/dma/ti-edma.txt | 51 + .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 25 +- Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig |1 + arch/arm/boot/dts/am335x-bone.dts | 23 + arch/arm/boot/dts/am335x-evm.dts | 15 + arch/arm/boot/dts/am33xx.dtsi | 101 ++ arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/common/edma.c | 1841 arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-da830-evm.c|4 +- arch/arm/mach-davinci/board-da850-evm.c|8 +-
[PATCH] Fix 2.6.24-rc7 regression in asix.c
51bf2976 caused a regression in the asix usbnet driver. usb_control_msg returns the number of bytes read on success, not 0. Tested with NETGEAR FA120. Signed-off-by: Russ Dill <[EMAIL PROTECTED]> --- drivers/net/usb/asix.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1249f44..569028b 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -202,10 +202,10 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, buf, size, USB_CTRL_GET_TIMEOUT); - if (err >= 0 && err < size) - err = -EINVAL; - if (!err) + if (err == size) memcpy(data, buf, size); + else if (err >= 0) + err = -EINVAL; kfree(buf); out: -- 1.5.3.7 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Fix 2.6.24-rc7 regression in asix.c
51bf2976 caused a regression in the asix usbnet driver. usb_control_msg returns the number of bytes read on success, not 0. Tested with NETGEAR FA120. Signed-off-by: Russ Dill [EMAIL PROTECTED] --- drivers/net/usb/asix.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 1249f44..569028b 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -202,10 +202,10 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, buf, size, USB_CTRL_GET_TIMEOUT); - if (err = 0 err size) - err = -EINVAL; - if (!err) + if (err == size) memcpy(data, buf, size); + else if (err = 0) + err = -EINVAL; kfree(buf); out: -- 1.5.3.7 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Why does reading from /dev/urandom deplete entropy so much?
Marc Haber zugschlus.de> writes: > > While debugging Exim4's GnuTLS interface, I recently found out that > reading from /dev/urandom depletes entropy as much as reading from > /dev/random would. This has somehow surprised me since I have always > believed that /dev/urandom has lower quality entropy than /dev/random, > but lots of it. > > This also means that I can "sabotage" applications reading from > /dev/random just by continuously reading from /dev/urandom, even not > meaning to do any harm. An application either needs to be cryptographically secure, or it doesn't. If it doesn't, then just use /dev/urandom to seed a PRNG. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Why does reading from /dev/urandom deplete entropy so much?
Marc Haber mh+linux-kernel at zugschlus.de writes: While debugging Exim4's GnuTLS interface, I recently found out that reading from /dev/urandom depletes entropy as much as reading from /dev/random would. This has somehow surprised me since I have always believed that /dev/urandom has lower quality entropy than /dev/random, but lots of it. This also means that I can sabotage applications reading from /dev/random just by continuously reading from /dev/urandom, even not meaning to do any harm. An application either needs to be cryptographically secure, or it doesn't. If it doesn't, then just use /dev/urandom to seed a PRNG. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Better document profile=
On 10/25/07, Andrew Morton <[EMAIL PROTECTED]> wrote: > On Tue, 16 Oct 2007 22:16:47 -0700 > "Russ Dill" <[EMAIL PROTECTED]> wrote: > > > Be more explicit on what the step/bucket size accomplishes. > > > > Signed-off-by: Russ Dill <[EMAIL PROTECTED]> > > --- > > Documentation/kernel-parameters.txt |5 - > > 1 files changed, 4 insertions(+), 1 deletions(-) > > > > diff --git a/Documentation/kernel-parameters.txt > > b/Documentation/kernel-parameters.txt > > index eb24799..3c6fd27 100644 > > --- a/Documentation/kernel-parameters.txt > > +++ b/Documentation/kernel-parameters.txt > > @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is > > defined in the file > > Your email client is wordwrapping the patches. Sorry, I had sent an updated email a couple minutes after this one without the wrapping. > > Format: [schedule,] > > Param: "schedule" - profile schedule points. > > Param: - step/bucket size as a power of 2 for > > - statistical time based profiling. > > + statistical time based profiling. A value of > > + 2 will provide a granularity of 4 bytes, a > > + value of 3 will provide a granularity of 8 > > + bytes and so on. > > Param: "sleep" - profile D-state sleeping (millisecs) > > Actually the prof_shift isn't in units of bytes: it is in units of > sizeof(unsigned long). I thought we just went through this? extern char _text[], _stext[], _etext[]; [...] prof_len = (_etext - _stext) >> prof_shift; prof_buffer = alloc_bootmem(prof_len*sizeof(atomic_t)); 1MB kernel, 32 bit, prof_shift = 2, makes for 262144 profiling slots, a granularity of 4 bytes 1MB kernel, 64 bit, prof_shift = 2, makes for 262144 profiling slots, a granularity of 4 bytes The only difference between the two being the sizeof(atomic_t), so that a 32 bit kernel would allocate a 1MB buffer, and a 64 bit kernel would allocate a 2MB buffer. I'm having nightmares about megawords again... > So on a 64-bit kernel, prof_shift=2 will give a granularity of 8<<2 bytes > and on a 32-bit kernel, prof_shift=3 will give a granularity of 4<<3 bytes. now you are confusing me even more... by 8<<2 and 4<<3 do you mean 32 bytes? Linus says the following in 0.98: # uncomment this if you want kernel profiling: the profile_shift is the # granularity of the profiling (5 = 32-byte granularity) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Better document profile=
On 10/25/07, Andrew Morton [EMAIL PROTECTED] wrote: On Tue, 16 Oct 2007 22:16:47 -0700 Russ Dill [EMAIL PROTECTED] wrote: Be more explicit on what the step/bucket size accomplishes. Signed-off-by: Russ Dill [EMAIL PROTECTED] --- Documentation/kernel-parameters.txt |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eb24799..3c6fd27 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is defined in the file Your email client is wordwrapping the patches. Sorry, I had sent an updated email a couple minutes after this one without the wrapping. Format: [schedule,]number Param: schedule - profile schedule points. Param: number - step/bucket size as a power of 2 for - statistical time based profiling. + statistical time based profiling. A value of + 2 will provide a granularity of 4 bytes, a + value of 3 will provide a granularity of 8 + bytes and so on. Param: sleep - profile D-state sleeping (millisecs) Actually the prof_shift isn't in units of bytes: it is in units of sizeof(unsigned long). I thought we just went through this? extern char _text[], _stext[], _etext[]; [...] prof_len = (_etext - _stext) prof_shift; prof_buffer = alloc_bootmem(prof_len*sizeof(atomic_t)); 1MB kernel, 32 bit, prof_shift = 2, makes for 262144 profiling slots, a granularity of 4 bytes 1MB kernel, 64 bit, prof_shift = 2, makes for 262144 profiling slots, a granularity of 4 bytes The only difference between the two being the sizeof(atomic_t), so that a 32 bit kernel would allocate a 1MB buffer, and a 64 bit kernel would allocate a 2MB buffer. I'm having nightmares about megawords again... So on a 64-bit kernel, prof_shift=2 will give a granularity of 82 bytes and on a 32-bit kernel, prof_shift=3 will give a granularity of 43 bytes. now you are confusing me even more... by 82 and 43 do you mean 32 bytes? Linus says the following in 0.98: # uncomment this if you want kernel profiling: the profile_shift is the # granularity of the profiling (5 = 32-byte granularity) - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH fixed] Better document profile=
Be more explicit on what the step/bucket size accomplishes. Signed-off-by: Russ Dill <[EMAIL PROTECTED]> --- Documentation/kernel-parameters.txt |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eb24799..3c6fd27 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is defined in the file Format: [schedule,] Param: "schedule" - profile schedule points. Param: - step/bucket size as a power of 2 for - statistical time based profiling. + statistical time based profiling. A value of + 2 will provide a granularity of 4 bytes, a + value of 3 will provide a granularity of 8 + bytes and so on. Param: "sleep" - profile D-state sleeping (millisecs) processor.max_cstate= [HW,ACPI] -- 1.5.2.5 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Better document profile=
Be more explicit on what the step/bucket size accomplishes. Signed-off-by: Russ Dill <[EMAIL PROTECTED]> --- Documentation/kernel-parameters.txt |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eb24799..3c6fd27 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is defined in the file Format: [schedule,] Param: "schedule" - profile schedule points. Param: - step/bucket size as a power of 2 for - statistical time based profiling. + statistical time based profiling. A value of + 2 will provide a granularity of 4 bytes, a + value of 3 will provide a granularity of 8 + bytes and so on. Param: "sleep" - profile D-state sleeping (millisecs) processor.max_cstate= [HW,ACPI] -- 1.5.2.5 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Better document profile=
Be more explicit on what the step/bucket size accomplishes. Signed-off-by: Russ Dill [EMAIL PROTECTED] --- Documentation/kernel-parameters.txt |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eb24799..3c6fd27 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is defined in the file Format: [schedule,]number Param: schedule - profile schedule points. Param: number - step/bucket size as a power of 2 for - statistical time based profiling. + statistical time based profiling. A value of + 2 will provide a granularity of 4 bytes, a + value of 3 will provide a granularity of 8 + bytes and so on. Param: sleep - profile D-state sleeping (millisecs) processor.max_cstate= [HW,ACPI] -- 1.5.2.5 - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH fixed] Better document profile=
Be more explicit on what the step/bucket size accomplishes. Signed-off-by: Russ Dill [EMAIL PROTECTED] --- Documentation/kernel-parameters.txt |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index eb24799..3c6fd27 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1427,7 +1427,10 @@ and is between 256 and 4096 characters. It is defined in the file Format: [schedule,]number Param: schedule - profile schedule points. Param: number - step/bucket size as a power of 2 for - statistical time based profiling. + statistical time based profiling. A value of + 2 will provide a granularity of 4 bytes, a + value of 3 will provide a granularity of 8 + bytes and so on. Param: sleep - profile D-state sleeping (millisecs) processor.max_cstate= [HW,ACPI] -- 1.5.2.5 - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [OT] Argument with an OS professor over profile=3
On 10/10/07, David Newall <[EMAIL PROTECTED]> wrote: > Russ Dill wrote: > > I've been having a back and forth going for a while with my TA and OS > > professor on the meaning of profile=3 and have been unable to convince > > either of them. The basic question is if profile=3 is passed to kernel > > with an 8MB text section, how big is the allocated profile buffer. His > > answer is 1MB > > > > if (prof_shift) { > > unsigned int size; > > /* only text is profiled */ > > prof_len = (unsigned *) &_etext - (unsigned *) &_stext; > > > You stipulated 8MB text, but this calculates in unsigned ints, so > prof_len = 2M. Please have a look at my followup, I accidentally sent out code that I had used to produce an answer as my prof thought it works. The actual code casts to (unsigned long). Sigh, I've shot myself in the foot... Anyway, the book (and the class covers 2.4.1) and the associated code has since moved from init/main.c. Here's how the 2.4.1ish code looks: http://tldp.org/HOWTO/Linux-i386-Boot-Code-HOWTO/init_main.html - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [OT] Argument with an OS professor over profile=3
/* only text is profiled */ > prof_len = (unsigned *) &_etext - (unsigned *) &_stext; Crap, sorry, accidentally sent a version I had laying around demonstrating how one *would* get the answer he expects. The correct line is of course: prof_len = (unsigned long) &_etext - (unsigned long) &_stext; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[OT] Argument with an OS professor over profile=3
I've been having a back and forth going for a while with my TA and OS professor on the meaning of profile=3 and have been unable to convince either of them. The basic question is if profile=3 is passed to kernel with an 8MB text section, how big is the allocated profile buffer. His answer is 1MB if (prof_shift) { unsigned int size; /* only text is profiled */ prof_len = (unsigned *) &_etext - (unsigned *) &_stext; prof_len >>= prof_shift; size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1; prof_buffer = (unsigned int *) alloc_bootmem(size); } I've booted linux with profile=3 and pointed to the dmesg output. I've copied the code out of init/main.c into a test program and run it. I've even pointed to the comment in the Makefile for linux-0.98. He seems to think that there is pointer arithmetic taking place. To make matters worse, our textbook "Linux Core Kernel Commentary, 2nd Edition", also has an incorrect answer. It states "A prof_shift value of 2, for example, allocates an amount of memory equal to 25 percent of the kernel's code size to profile the kernel." And of course, he's been giving the exam for 4 years and no one else complained. Anyway, a reply from whoever sent this message back in 1992: http://groups.google.com/group/comp.os.linux/browse_thread/thread/d84462f394d3a206/dfee60779481ccec?lnk=st==4#dfee60779481ccec > I wrote a kernel profiling utility for this, and sent the patches > (small) and a user-level program to print out results (even smaller) to > the kernel mailing-list. If anybody sees this slow-down problem, and > tries out the profiling code, I'd be interested to have some sample > output. > > If you aren't on the kernel list, I can make the patches available on > the net. would be nice. I heard he had arguments with his OS prof's back in the day. (even neater if someone had the email that was sent to whatever that kernel list was, just for my general curiosity), but emails from others would be nice too :) A few secondary questions that aren't nearly as important. Is IRQ used an abbreviation for interrupt, or does it have a separate meaning to kernel developers? Rate the following responses on a scale from 1-10: Why does the source code use 14 calls to BUILD_16_IRQS each of which makes 16 calls to BI (which expands to BUILD_IRQ) instead of 224 calls to BUILD_IRQ? Reduce amount of source code and redundancy 224 calls would be ugly and difficult to maintain. Plus, kernel developers are lazv, they don't want to have to copy 224 times. Thanks, I work full time and attend graduate school full time, I've already spent far too much time arguing with my prof and TA. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[OT] Argument with an OS professor over profile=3
I've been having a back and forth going for a while with my TA and OS professor on the meaning of profile=3 and have been unable to convince either of them. The basic question is if profile=3 is passed to kernel with an 8MB text section, how big is the allocated profile buffer. His answer is 1MB if (prof_shift) { unsigned int size; /* only text is profiled */ prof_len = (unsigned *) _etext - (unsigned *) _stext; prof_len = prof_shift; size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1; prof_buffer = (unsigned int *) alloc_bootmem(size); } I've booted linux with profile=3 and pointed to the dmesg output. I've copied the code out of init/main.c into a test program and run it. I've even pointed to the comment in the Makefile for linux-0.98. He seems to think that there is pointer arithmetic taking place. To make matters worse, our textbook Linux Core Kernel Commentary, 2nd Edition, also has an incorrect answer. It states A prof_shift value of 2, for example, allocates an amount of memory equal to 25 percent of the kernel's code size to profile the kernel. And of course, he's been giving the exam for 4 years and no one else complained. Anyway, a reply from whoever sent this message back in 1992: http://groups.google.com/group/comp.os.linux/browse_thread/thread/d84462f394d3a206/dfee60779481ccec?lnk=stq=rnum=4#dfee60779481ccec I wrote a kernel profiling utility for this, and sent the patches (small) and a user-level program to print out results (even smaller) to the kernel mailing-list. If anybody sees this slow-down problem, and tries out the profiling code, I'd be interested to have some sample output. If you aren't on the kernel list, I can make the patches available on the net. would be nice. I heard he had arguments with his OS prof's back in the day. (even neater if someone had the email that was sent to whatever that kernel list was, just for my general curiosity), but emails from others would be nice too :) A few secondary questions that aren't nearly as important. Is IRQ used an abbreviation for interrupt, or does it have a separate meaning to kernel developers? Rate the following responses on a scale from 1-10: Why does the source code use 14 calls to BUILD_16_IRQS each of which makes 16 calls to BI (which expands to BUILD_IRQ) instead of 224 calls to BUILD_IRQ? Reduce amount of source code and redundancy 224 calls would be ugly and difficult to maintain. Plus, kernel developers are lazv, they don't want to have to copypaste 224 times. Thanks, I work full time and attend graduate school full time, I've already spent far too much time arguing with my prof and TA. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/