Messages in this thread Patch in this message | | | Subject | [RFC][PATCH 2/3] Process events biarch bug: Process events timestamp bug | From | Matt Helsley <> | Date | Tue, 27 Jun 2006 04:48:46 -0700 |
| |
The event sent by Process Events from a 64-bit kernel is not compatible with what a 32-bit userspace program would expect to recieve because the timespec struct (used to send a timestamp) is not the same. This means that fields stored after the timestamp are offset and programs that don't take this into account break under these circumstances.
This is a problem on ppc64, s390, x86-64.. any "biarch" system where it's possible for a 64-bit kernel to run 32-bit userspace programs.
This patch adds a comment highlighting the problem and a Documentation file showing a userspace workaround.
Signed-off-by: Matt Helsley <matthltc@us.ibm.com> --- Documentation/connector/process_events.txt | 75 +++++++++++++++++++++++++++++ drivers/connector/Kconfig | 3 + include/linux/cn_proc.h | 7 ++ 3 files changed, 85 insertions(+)
Index: linux-2.6.17-mm3-biarch/include/linux/cn_proc.h =================================================================== --- linux-2.6.17-mm3-biarch.orig/include/linux/cn_proc.h +++ linux-2.6.17-mm3-biarch/include/linux/cn_proc.h @@ -55,11 +55,18 @@ struct proc_event { /* "next" should be 0x00000400 */ /* "last" is the last process event: exit */ PROC_EVENT_EXIT = 0x80000000 } what; __u32 cpu; + + /* + * UGH! timespec is biarch incompatible. See + * Documentation/connector/process_events.txt if you're going to listen + * for process events in userspace. + */ struct timespec timestamp; + union process_event_data { /* must be last field of proc_event struct */ struct { __u32 err; } ack; Index: linux-2.6.17-mm3-biarch/Documentation/connector/process_events.txt =================================================================== --- /dev/null +++ linux-2.6.17-mm3-biarch/Documentation/connector/process_events.txt @@ -0,0 +1,75 @@ +NOTES: + +To safely use process events on biarch systems it's necessary to account for +the difference in size of the events returned by 64-bit kernels to 32-bit +applications. This size difference is caused by use of a struct timespec for +the timestamp field. + +There are multiple ways of doing this. However, few of them account for the +fact that the size of the process event structure may change in the future. + +#include "linux/cn_proc.h" + +{ + ... + struct process_event *ev; + union process_event_data *evdata; + struct timespec ts; + + ev = cn_msg->data; + if ((cn_msg->len - sizeof(struct process_event)) == sizeof(__u64)) { + __u64 *v; + + /* kernel is sending 64-bit timestamps to 32-bit userspace */ + + v = (*__u64)&ev->timestamp; + ts.tv_sec = *v; + v++; + ts.tv_nsec = *v; + v++; + evdata = (union process_event_data*)v; + } else { + evdata = &ev->event_data; + ts = ev->timestamp; + } + + switch(ev->what) { + case PROCESS_EVENT_EXIT: + ... evdata->exit.exit_code ... + break; + } +} + +Alternately, you can compare the size of the message length to the known +size of the two structure variations and thus determine which structure to +use to access the data: + +struct pev32 { + enum what what; + __u32 cpu; + __u32 timestamp[2]; + union process_event_data event_data; +}; + +struct pev64 { + enum what what; + __u32 cpu; + __u64 timestamp[2]; + union process_event_data event_data; +}; + +... +if (cn_msg->len == sizeof(struct pev64)) { + ... +} else if (cn_msg->len == sizeof(struct pev32)) { + ... +} + +Both approaches assume that the process events structure will never change +size. + +To limit the number of times you need to test which format is being sent use +the acknowledgement message returned by the kernel after sending +PROC_CN_MCAST_LISTEN. Use any of the techniques described above on the +acknowledgement message and then set function pointers, flags, etc. to avoid +the test in the future. Index: linux-2.6.17-mm3-biarch/drivers/connector/Kconfig =================================================================== --- linux-2.6.17-mm3-biarch.orig/drivers/connector/Kconfig +++ linux-2.6.17-mm3-biarch/drivers/connector/Kconfig @@ -16,6 +16,9 @@ config PROC_EVENTS depends on CONNECTOR help Provide a connector that reports process events to userspace. Send events such as fork, exec, id change (uid, gid, suid, etc), and exit. + See Documentation/connector/process_events.txt if you're going to + listen for process events in userspace. + endmenu --
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |