* rtcansend 32-bit
@ 2021-11-02 18:57 C Smith
2021-11-02 19:11 ` Jan Kiszka
0 siblings, 1 reply; 13+ messages in thread
From: C Smith @ 2021-11-02 18:57 UTC (permalink / raw)
To: Xenomai List
I ran into a problem wherein my real-time Xenomai 32-bit app
fails on the socket operations of the 64-bit CAN driver.
My real-time userspace app is Cobalt x86, compiled -m32.
When I try the Xenomai rtcansend.c sample app compiled 32-bit, I get the
same error :
[root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 --verbose
--identifier=0x123 0xde 0xad
send: Message too long
Looking at rtcansend.c. The call to sendto is failing and returns 'Message
too long' here:
ret = sendto(s, (void *)&frame, sizeof(can_frame_t), 0,
(struct sockaddr *)&to_addr, sizeof(to_addr));
Here is how I configured Xenomai for 32-bit when I built it:
./configure --host=i686-linux CFLAGS="-m32 -D_FILE_OFFSET_BITS=64"
LDFLAGS=-m32 host_alias=i686-linux
But note that if I compile both Xenomai and rtcansend.c 64-bit, everything
works fine.
So how can 32-bit Xeno apps use the 64-bit CAN driver ?
thanks,
-C Smith
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-02 18:57 rtcansend 32-bit C Smith
@ 2021-11-02 19:11 ` Jan Kiszka
2021-11-02 22:57 ` C Smith
0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2021-11-02 19:11 UTC (permalink / raw)
To: C Smith, Xenomai List
On 02.11.21 19:57, C Smith via Xenomai wrote:
> I ran into a problem wherein my real-time Xenomai 32-bit app
> fails on the socket operations of the 64-bit CAN driver.
> My real-time userspace app is Cobalt x86, compiled -m32.
>
> When I try the Xenomai rtcansend.c sample app compiled 32-bit, I get the
> same error :
>
> [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 --verbose
> --identifier=0x123 0xde 0xad
> send: Message too long
>
> Looking at rtcansend.c. The call to sendto is failing and returns 'Message
> too long' here:
> ret = sendto(s, (void *)&frame, sizeof(can_frame_t), 0,
> (struct sockaddr *)&to_addr, sizeof(to_addr));
>
> Here is how I configured Xenomai for 32-bit when I built it:
> ./configure --host=i686-linux CFLAGS="-m32 -D_FILE_OFFSET_BITS=64"
> LDFLAGS=-m32 host_alias=i686-linux
>
> But note that if I compile both Xenomai and rtcansend.c 64-bit, everything
> works fine.
>
> So how can 32-bit Xeno apps use the 64-bit CAN driver ?
>
We possibly have compat ABI issue here: The Xenomai core can handle
32-bit calls of sendto (sendmsg internally) into 64-bit kernel, but
maybe there is something beyond that interpreted by the CAN driver that
is not aware of 32 vs. 64 bit userland.
I suspect sizeof(can_frame_t) varies, though I don't see why yet. Could
you debug that, instrument kernel/drivers/can/rtcan_raw.c as well as the
userspace code?
The other reason for EMSGSIZE would be msg_iovlen != 1, but that would
mean we have an issue in the generic compat sendmsg code, and that is
less likely.
Jan
--
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-02 19:11 ` Jan Kiszka
@ 2021-11-02 22:57 ` C Smith
2021-11-03 6:59 ` Jan Kiszka
0 siblings, 1 reply; 13+ messages in thread
From: C Smith @ 2021-11-02 22:57 UTC (permalink / raw)
To: Xenomai List
I added some printf/printk to rtcansend.c as well as rtcan_raw.c:
rtcan_raw.c:
/* Check size of buffer */
if (iov->iov_len != sizeof(can_frame_t)) {
printk("rtcan_raw.c, 850: sizeof(can_frame_t): %ld\n",
sizeof(can_frame_t));
printk("rtcan_raw.c, 852: iov->iov_len: %ld\n",
iov->iov_len);
return -EMSGSIZE;
}
when running rtcansend (32-bit compile, which fails with EMSGSIZE):
[root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
sizeof(can_frame_t): 16
send: Message too long
[root@pc can]# dmesg
[11275.197125] rtcan_raw.c, 850: sizeof(can_frame_t): 16
[11275.197133] rtcan_raw.c, 852: iov->iov_len: 34494267600
when running rtcansend (64-bit compile, sends out can msg OK):
[root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
sizeof(can_frame_t): 16
[root@pc can]# dmesg
[12476.571032] rtcan_raw.c, 850: sizeof(can_frame_t): 16
[12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
It looks like the struct user_msghdr *msg passed into rtcan_raw_sendmsg()
is corrupt.
I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
-C Smith
On Tue, Nov 2, 2021 at 12:11 PM Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 02.11.21 19:57, C Smith via Xenomai wrote:
> > I ran into a problem wherein my real-time Xenomai 32-bit app
> > fails on the socket operations of the 64-bit CAN driver.
> > My real-time userspace app is Cobalt x86, compiled -m32.
> >
> > When I try the Xenomai rtcansend.c sample app compiled 32-bit, I get the
> > same error :
> >
> > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 --verbose
> > --identifier=0x123 0xde 0xad
> > send: Message too long
> >
> > Looking at rtcansend.c. The call to sendto is failing and returns
> 'Message
> > too long' here:
> > ret = sendto(s, (void *)&frame, sizeof(can_frame_t), 0,
> > (struct sockaddr *)&to_addr, sizeof(to_addr));
> >
> > Here is how I configured Xenomai for 32-bit when I built it:
> > ./configure --host=i686-linux CFLAGS="-m32 -D_FILE_OFFSET_BITS=64"
> > LDFLAGS=-m32 host_alias=i686-linux
> >
> > But note that if I compile both Xenomai and rtcansend.c 64-bit,
> everything
> > works fine.
> >
> > So how can 32-bit Xeno apps use the 64-bit CAN driver ?
> >
>
> We possibly have compat ABI issue here: The Xenomai core can handle
> 32-bit calls of sendto (sendmsg internally) into 64-bit kernel, but
> maybe there is something beyond that interpreted by the CAN driver that
> is not aware of 32 vs. 64 bit userland.
>
> I suspect sizeof(can_frame_t) varies, though I don't see why yet. Could
> you debug that, instrument kernel/drivers/can/rtcan_raw.c as well as the
> userspace code?
>
> The other reason for EMSGSIZE would be msg_iovlen != 1, but that would
> mean we have an issue in the generic compat sendmsg code, and that is
> less likely.
>
> Jan
>
> --
> Siemens AG, T RDA IOT
> Corporate Competence Center Embedded Linux
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-02 22:57 ` C Smith
@ 2021-11-03 6:59 ` Jan Kiszka
2021-11-03 10:46 ` Jan Kiszka
0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2021-11-03 6:59 UTC (permalink / raw)
To: C Smith, Xenomai List
On 02.11.21 23:57, C Smith via Xenomai wrote:
> I added some printf/printk to rtcansend.c as well as rtcan_raw.c:
>
> rtcan_raw.c:
> /* Check size of buffer */
> if (iov->iov_len != sizeof(can_frame_t)) {
> printk("rtcan_raw.c, 850: sizeof(can_frame_t): %ld\n",
> sizeof(can_frame_t));
> printk("rtcan_raw.c, 852: iov->iov_len: %ld\n",
> iov->iov_len);
> return -EMSGSIZE;
> }
>
> when running rtcansend (32-bit compile, which fails with EMSGSIZE):
> [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
> sizeof(can_frame_t): 16
> send: Message too long
>
> [root@pc can]# dmesg
> [11275.197125] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> [11275.197133] rtcan_raw.c, 852: iov->iov_len: 34494267600
>
> when running rtcansend (64-bit compile, sends out can msg OK):
> [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
> sizeof(can_frame_t): 16
>
> [root@pc can]# dmesg
> [12476.571032] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
>
> It looks like the struct user_msghdr *msg passed into rtcan_raw_sendmsg()
> is corrupt.
> I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
> -C Smith
OK, my guess was wrong. Let me see where we corrupt this.
Brings https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21 into
memory...
Jan
--
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-03 6:59 ` Jan Kiszka
@ 2021-11-03 10:46 ` Jan Kiszka
2021-11-03 11:09 ` Bezdeka, Florian
0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2021-11-03 10:46 UTC (permalink / raw)
To: C Smith, Xenomai List
On 03.11.21 07:59, Jan Kiszka wrote:
> On 02.11.21 23:57, C Smith via Xenomai wrote:
>> I added some printf/printk to rtcansend.c as well as rtcan_raw.c:
>>
>> rtcan_raw.c:
>> /* Check size of buffer */
>> if (iov->iov_len != sizeof(can_frame_t)) {
>> printk("rtcan_raw.c, 850: sizeof(can_frame_t): %ld\n",
>> sizeof(can_frame_t));
>> printk("rtcan_raw.c, 852: iov->iov_len: %ld\n",
>> iov->iov_len);
>> return -EMSGSIZE;
>> }
>>
>> when running rtcansend (32-bit compile, which fails with EMSGSIZE):
>> [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
>> sizeof(can_frame_t): 16
>> send: Message too long
>>
>> [root@pc can]# dmesg
>> [11275.197125] rtcan_raw.c, 850: sizeof(can_frame_t): 16
>> [11275.197133] rtcan_raw.c, 852: iov->iov_len: 34494267600
>>
>> when running rtcansend (64-bit compile, sends out can msg OK):
>> [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
>> sizeof(can_frame_t): 16
>>
>> [root@pc can]# dmesg
>> [12476.571032] rtcan_raw.c, 850: sizeof(can_frame_t): 16
>> [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
>>
>> It looks like the struct user_msghdr *msg passed into rtcan_raw_sendmsg()
>> is corrupt.
>> I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
>> -C Smith
>
> OK, my guess was wrong. Let me see where we corrupt this.
>
> Brings https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21 into
> memory...
>
Found it: We are lacking use of rtdm_get_iovec in rtcan - in contrast to
RTnet (see e.g. rt_packet_sendmsg). Would you feel like looking into
such a change?
Jan
--
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-03 10:46 ` Jan Kiszka
@ 2021-11-03 11:09 ` Bezdeka, Florian
2021-11-04 6:49 ` C Smith
0 siblings, 1 reply; 13+ messages in thread
From: Bezdeka, Florian @ 2021-11-03 11:09 UTC (permalink / raw)
To: xenomai, jan.kiszka, csmithquestions
On Wed, 2021-11-03 at 11:46 +0100, Jan Kiszka via Xenomai wrote:
> On 03.11.21 07:59, Jan Kiszka wrote:
> > On 02.11.21 23:57, C Smith via Xenomai wrote:
> > > I added some printf/printk to rtcansend.c as well as rtcan_raw.c:
> > >
> > > rtcan_raw.c:
> > > /* Check size of buffer */
> > > if (iov->iov_len != sizeof(can_frame_t)) {
> > > printk("rtcan_raw.c, 850: sizeof(can_frame_t): %ld\n",
> > > sizeof(can_frame_t));
> > > printk("rtcan_raw.c, 852: iov->iov_len: %ld\n",
> > > iov->iov_len);
> > > return -EMSGSIZE;
> > > }
> > >
> > > when running rtcansend (32-bit compile, which fails with EMSGSIZE):
> > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
> > > sizeof(can_frame_t): 16
> > > send: Message too long
> > >
> > > [root@pc can]# dmesg
> > > [11275.197125] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> > > [11275.197133] rtcan_raw.c, 852: iov->iov_len: 34494267600
> > >
> > > when running rtcansend (64-bit compile, sends out can msg OK):
> > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde 0xad
> > > sizeof(can_frame_t): 16
> > >
> > > [root@pc can]# dmesg
> > > [12476.571032] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> > > [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
> > >
> > > It looks like the struct user_msghdr *msg passed into rtcan_raw_sendmsg()
> > > is corrupt.
> > > I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
> > > -C Smith
> >
> > OK, my guess was wrong. Let me see where we corrupt this.
> >
> > Brings https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21 into
> > memory...
> >
>
> Found it: We are lacking use of rtdm_get_iovec in rtcan - in contrast to
> RTnet (see e.g. rt_packet_sendmsg). Would you feel like looking into
> such a change?
Just a note: rtcan_raw_sendmsg() and rtcan_raw_recvmsg() are both
affected. Both should be using rtdm_get_iovec().
>
> Jan
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-03 11:09 ` Bezdeka, Florian
@ 2021-11-04 6:49 ` C Smith
2021-11-04 8:05 ` Bezdeka, Florian
0 siblings, 1 reply; 13+ messages in thread
From: C Smith @ 2021-11-04 6:49 UTC (permalink / raw)
To: Bezdeka, Florian; +Cc: xenomai, jan.kiszka
I was able to make the CAN transmit work successfully from my 32 bit
compile of rtcansend.c, by adding rtdm_get_iovec() to the code. I'll submit
a patch once both transmit and receive are working, but I'm still having
trouble receiving data in the rtcanrecv app. I added rtdm_get_iovec() to
rtcan_raw_recvmsg() so that may ultimately work but the driver is already
giving up during the bind. I get this error:
[root@pc can]# /usr/xenomai/bin/rtcanrecv rtcan0 -v
interface rtcan0
s=3, ifr_name=rtcan0
bind: Invalid argument
Cleaning up...
Here's the ioctl with extra printk()s, which executes during the bind:
int rtcan_raw_ioctl(struct rtdm_fd *fd,unsigned int request, void *arg)
{
int ret = 0;
switch (request) {
COMPAT_CASE(_RTIOC_BIND): {
struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
struct sockaddr_can *sockaddr, sockaddr_buf;
if (rtdm_fd_is_user(fd)) {
/* Copy argument structure from userspace */
printk("rtcan_raw.c, 421: rtcan_raw_ioctl\n");
if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
sizeof(struct _rtdm_setsockaddr_args)))
return -EFAULT;
setaddr = &setaddr_buf;
printk("rtcan_raw.c, 427: rtcan_raw_ioctl\n");
printk("rtcan_raw.c, 428: setaddr->addrlen: %d\n", setaddr->addrlen);
/* Check size */
if (setaddr->addrlen != sizeof(struct sockaddr_can))
return -EINVAL;
The resultant print statements in dmesg :
[27177.480980] rtcan_raw.c, 421: rtcan_raw_ioctl
[27177.480987] rtcan_raw.c, 427: rtcan_raw_ioctl
[27177.480994] rtcan_raw.c, 428: setaddr->addrlen: -6084360
Do you have any idea why addrlen is corrupt ?
Thanks, -C Smith
On Wed, Nov 3, 2021 at 4:09 AM Bezdeka, Florian <florian.bezdeka@siemens.com>
wrote:
> On Wed, 2021-11-03 at 11:46 +0100, Jan Kiszka via Xenomai wrote:
> > On 03.11.21 07:59, Jan Kiszka wrote:
> > > On 02.11.21 23:57, C Smith via Xenomai wrote:
> > > > I added some printf/printk to rtcansend.c as well as rtcan_raw.c:
> > > >
> > > > rtcan_raw.c:
> > > > /* Check size of buffer */
> > > > if (iov->iov_len != sizeof(can_frame_t)) {
> > > > printk("rtcan_raw.c, 850: sizeof(can_frame_t): %ld\n",
> > > > sizeof(can_frame_t));
> > > > printk("rtcan_raw.c, 852: iov->iov_len: %ld\n",
> > > > iov->iov_len);
> > > > return -EMSGSIZE;
> > > > }
> > > >
> > > > when running rtcansend (32-bit compile, which fails with EMSGSIZE):
> > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde
> 0xad
> > > > sizeof(can_frame_t): 16
> > > > send: Message too long
> > > >
> > > > [root@pc can]# dmesg
> > > > [11275.197125] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> > > > [11275.197133] rtcan_raw.c, 852: iov->iov_len: 34494267600
> > > >
> > > > when running rtcansend (64-bit compile, sends out can msg OK):
> > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s 0xde
> 0xad
> > > > sizeof(can_frame_t): 16
> > > >
> > > > [root@pc can]# dmesg
> > > > [12476.571032] rtcan_raw.c, 850: sizeof(can_frame_t): 16
> > > > [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
> > > >
> > > > It looks like the struct user_msghdr *msg passed into
> rtcan_raw_sendmsg()
> > > > is corrupt.
> > > > I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
> > > > -C Smith
> > >
> > > OK, my guess was wrong. Let me see where we corrupt this.
> > >
> > > Brings https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21
> into
> > > memory...
> > >
> >
> > Found it: We are lacking use of rtdm_get_iovec in rtcan - in contrast to
> > RTnet (see e.g. rt_packet_sendmsg). Would you feel like looking into
> > such a change?
>
> Just a note: rtcan_raw_sendmsg() and rtcan_raw_recvmsg() are both
> affected. Both should be using rtdm_get_iovec().
>
> >
> > Jan
> >
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-04 6:49 ` C Smith
@ 2021-11-04 8:05 ` Bezdeka, Florian
2021-11-05 7:09 ` C Smith
0 siblings, 1 reply; 13+ messages in thread
From: Bezdeka, Florian @ 2021-11-04 8:05 UTC (permalink / raw)
To: csmithquestions; +Cc: xenomai, jan.kiszka
On Wed, 2021-11-03 at 23:49 -0700, C Smith wrote:
> I was able to make the CAN transmit work successfully from my 32 bit
> compile of rtcansend.c, by adding rtdm_get_iovec() to the code. I'll
> submit a patch once both transmit and receive are working, but I'm
> still having trouble receiving data in the rtcanrecv app. I added
> rtdm_get_iovec() to rtcan_raw_recvmsg() so that may ultimately work
> but the driver is already giving up during the bind. I get this
> error:
>
> [root@pc can]# /usr/xenomai/bin/rtcanrecv rtcan0 -v
> interface rtcan0
> s=3, ifr_name=rtcan0
> bind: Invalid argument
> Cleaning up...
>
> Here's the ioctl with extra printk()s, which executes during the
> bind:
>
> int rtcan_raw_ioctl(struct rtdm_fd *fd,unsigned int request, void
> *arg)
> {
> int ret = 0;
>
> switch (request) {
> COMPAT_CASE(_RTIOC_BIND): {
> struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> struct sockaddr_can *sockaddr, sockaddr_buf;
>
> if (rtdm_fd_is_user(fd)) {
> /* Copy argument structure from userspace */
> printk("rtcan_raw.c, 421: rtcan_raw_ioctl\n");
>
> if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
> sizeof(struct _rtdm_setsockaddr_args)))
> return -EFAULT;
That should be the source of your problem. It looks like rtcan never
had a compat interface. (Jan should confirm first...)
You have a 64 bit kernel, so the pointer width (in struct
_rtdm_setsockaddr_args) is considered to be 8 bytes but userspace only
provided 4.
The copy operation still succeeds, but reading from this struct is now
broken because of wrong offsets.
Reading struct _rtdm_setsockaddr_args has be wrapped into a helper
similar to rtdm_get_iovec().
>
> setaddr = &setaddr_buf;
> printk("rtcan_raw.c, 427: rtcan_raw_ioctl\n");
> printk("rtcan_raw.c, 428: setaddr->addrlen: %d\n", setaddr-
> >addrlen);
>
> /* Check size */
> if (setaddr->addrlen != sizeof(struct sockaddr_can))
> return -EINVAL;
>
> The resultant print statements in dmesg :
> [27177.480980] rtcan_raw.c, 421: rtcan_raw_ioctl
> [27177.480987] rtcan_raw.c, 427: rtcan_raw_ioctl
> [27177.480994] rtcan_raw.c, 428: setaddr->addrlen: -6084360
>
> Do you have any idea why addrlen is corrupt ?
> Thanks, -C Smith
>
> On Wed, Nov 3, 2021 at 4:09 AM Bezdeka, Florian
> <florian.bezdeka@siemens.com> wrote:
> > On Wed, 2021-11-03 at 11:46 +0100, Jan Kiszka via Xenomai wrote:
> > > On 03.11.21 07:59, Jan Kiszka wrote:
> > > > On 02.11.21 23:57, C Smith via Xenomai wrote:
> > > > > I added some printf/printk to rtcansend.c as well as
> > rtcan_raw.c:
> > > > >
> > > > > rtcan_raw.c:
> > > > > /* Check size of buffer */
> > > > > if (iov->iov_len != sizeof(can_frame_t)) {
> > > > > printk("rtcan_raw.c, 850: sizeof(can_frame_t):
> > %ld\n",
> > > > > sizeof(can_frame_t));
> > > > > printk("rtcan_raw.c, 852: iov->iov_len:
> > > > > %ld\n",
> > > > > iov->iov_len);
> > > > > return -EMSGSIZE;
> > > > > }
> > > > >
> > > > > when running rtcansend (32-bit compile, which fails with
> > EMSGSIZE):
> > > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s
> > 0xde 0xad
> > > > > sizeof(can_frame_t): 16
> > > > > send: Message too long
> > > > >
> > > > > [root@pc can]# dmesg
> > > > > [11275.197125] rtcan_raw.c, 850:
> > > > > sizeof(can_frame_t):
> > 16
> > > > > [11275.197133] rtcan_raw.c, 852: iov->iov_len:
> > 34494267600
> > > > >
> > > > > when running rtcansend (64-bit compile, sends out can msg
> > > > > OK):
> > > > > [root@pc can]# /usr/xenomai/bin/rtcansend rtcan0 -s
> > 0xde 0xad
> > > > > sizeof(can_frame_t): 16
> > > > >
> > > > > [root@pc can]# dmesg
> > > > > [12476.571032] rtcan_raw.c, 850:
> > > > > sizeof(can_frame_t):
> > 16
> > > > > [12476.571040] rtcan_raw.c, 852: iov->iov_len: 16
> > > > >
> > > > > It looks like the struct user_msghdr *msg passed into
> > rtcan_raw_sendmsg()
> > > > > is corrupt.
> > > > > I'm using Xenomai 3.1, with kernel 4.19.989 x86_64
> > > > > -C Smith
> > > >
> > > > OK, my guess was wrong. Let me see where we corrupt this.
> > > >
> > > > Brings
> > https://gitlab.com/Xenomai/xenomai-hacker-space/-/issues/21 into
> > > > memory...
> > > >
> > >
> > > Found it: We are lacking use of rtdm_get_iovec in rtcan - in
> > contrast to
> > > RTnet (see e.g. rt_packet_sendmsg). Would you feel like looking
> > into
> > > such a change?
> >
> > Just a note: rtcan_raw_sendmsg() and rtcan_raw_recvmsg() are both
> > affected. Both should be using rtdm_get_iovec().
> >
> > >
> > > Jan
> > >
> >
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-04 8:05 ` Bezdeka, Florian
@ 2021-11-05 7:09 ` C Smith
2021-11-05 8:14 ` Jan Kiszka
0 siblings, 1 reply; 13+ messages in thread
From: C Smith @ 2021-11-05 7:09 UTC (permalink / raw)
To: Bezdeka, Florian; +Cc: xenomai, jan.kiszka
Please review and accept this patch, which allows 32 bit apps to send and
receive CAN. It is tested successfully with 32bit and 64bit compiles of
utils/can/rtcansend.c / and rtcanrecv.c. The compat interface is now
implemented, rtdm_get_iovec() is used and the get_sockaddr() methodology
from the xddp sockets code was emulated to get the CAN receive to work.
Signed-off-by: C Smith <csmithquestions@gmail.com>
---
kernel/drivers/can/rtcan_internal.h | 3 +
kernel/drivers/can/rtcan_raw.c | 111
++++++++++++++++++++++++------------
2 files changed, 76 insertions(+), 38 deletions(-)
diff --git a/kernel/drivers/can/rtcan_internal.h
b/kernel/drivers/can/rtcan_internal.h
index b290005..03febef 100644
--- a/kernel/drivers/can/rtcan_internal.h
+++ b/kernel/drivers/can/rtcan_internal.h
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <rtdm/driver.h>
+#include <rtdm/compat.h>
#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
#define RTCAN_ASSERT(expr, func) \
@@ -58,4 +59,6 @@
#define rtcandev_err(dev, fmt, args...) \
printk(KERN_ERR "%s: " fmt, (dev)->name, ##args)
+#define COMPAT_CASE(__op) case __op __COMPAT_CASE(__op ## _COMPAT)
+
#endif /* __RTCAN_INTERNAL_H_ */
diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
index 693b927..6e8ebe6 100644
--- a/kernel/drivers/can/rtcan_raw.c
+++ b/kernel/drivers/can/rtcan_raw.c
@@ -215,6 +215,58 @@ EXPORT_SYMBOL_GPL(rtcan_loopback);
#endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */
+int rtcan_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_can **saddrp,
+ const void *arg)
+{
+ struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
+ int ret = 0;
+
+ if (!rtdm_fd_is_user(fd)) {
+ setaddr = (struct _rtdm_setsockaddr_args *)arg;
+ *saddrp = (struct sockaddr_can *)setaddr->addr;
+ }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+ if (rtdm_fd_is_compat(fd)) {
+ struct compat_rtdm_setsockaddr_args csetaddr_buff;
+
+ /* Copy argument structure from userspace */
+ ret = rtdm_safe_copy_from_user(fd, &csetaddr_buff,
+ arg, sizeof(csetaddr_buff));
+ if (ret)
+ return ret;
+
+ /* Check size */
+ if (csetaddr_buff.addrlen != sizeof(**saddrp))
+ return -EINVAL;
+
+ return rtdm_safe_copy_from_user(fd, *saddrp,
+ compat_ptr(csetaddr_buff.addr),
+ sizeof(struct sockaddr_can));
+ *saddrp = NULL;
+ return 0;
+ }
+#endif
+
+ if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
+ sizeof(struct _rtdm_setsockaddr_args)))
+ return -EFAULT;
+
+ setaddr = &setaddr_buf;
+
+ /* Check size */
+ if (setaddr->addrlen != sizeof(struct sockaddr_can))
+ return -EINVAL;
+
+ return rtdm_safe_copy_from_user(fd, *saddrp,
+ setaddr->addr,
+ sizeof(struct sockaddr_can));
+
+ *saddrp = NULL;
+ return 0;
+}
+
+
int rtcan_raw_socket(struct rtdm_fd *fd, int protocol)
{
/* Only protocol CAN_RAW is supported */
@@ -408,46 +460,21 @@ static int rtcan_raw_setsockopt(struct rtdm_fd *fd,
int rtcan_raw_ioctl(struct rtdm_fd *fd,
unsigned int request, void *arg)
{
+ struct sockaddr_can saddr, *saddrp = &saddr;
int ret = 0;
switch (request) {
- case _RTIOC_BIND: {
- struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
- struct sockaddr_can *sockaddr, sockaddr_buf;
-
- if (rtdm_fd_is_user(fd)) {
- /* Copy argument structure from userspace */
- if (!rtdm_read_user_ok(fd, arg,
- sizeof(struct _rtdm_setsockaddr_args)) ||
- rtdm_copy_from_user(fd, &setaddr_buf, arg,
- sizeof(struct _rtdm_setsockaddr_args)))
- return -EFAULT;
- setaddr = &setaddr_buf;
+ COMPAT_CASE(_RTIOC_BIND):
+ ret = rtcan_get_sockaddr(fd, &saddrp, arg);
+ if (ret)
+ return ret;
+ if (saddrp == NULL)
+ return -EFAULT;
+ ret = rtcan_raw_bind(fd, saddrp);
+ break;
- /* Check size */
- if (setaddr->addrlen != sizeof(struct sockaddr_can))
- return -EINVAL;
-
- /* Copy argument structure from userspace */
- if (!rtdm_read_user_ok(fd, arg,
- sizeof(struct sockaddr_can)) ||
- rtdm_copy_from_user(fd, &sockaddr_buf, setaddr->addr,
- sizeof(struct sockaddr_can)))
- return -EFAULT;
- sockaddr = &sockaddr_buf;
- } else {
- setaddr = (struct _rtdm_setsockaddr_args *)arg;
- sockaddr = (struct sockaddr_can *)setaddr->addr;
- }
-
- /* Now, all required data are in kernel space */
- ret = rtcan_raw_bind(fd, sockaddr);
-
- break;
- }
-
- case _RTIOC_SETSOCKOPT: {
+ COMPAT_CASE(_RTIOC_SETSOCKOPT): {
struct _rtdm_setsockopt_args *setopt;
struct _rtdm_setsockopt_args setopt_buf;
@@ -532,7 +559,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
struct sockaddr_can scan;
nanosecs_rel_t timeout;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
struct iovec iov_buf;
can_frame_t frame;
nanosecs_abs_t timestamp = 0;
@@ -584,6 +611,10 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
iov = &iov_buf;
}
+ ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
+ if (ret)
+ return ret;
+
/* Check size of buffer */
if (iov->iov_len < sizeof(can_frame_t))
return -EMSGSIZE;
@@ -768,7 +799,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
struct sockaddr_can scan_buf;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
struct iovec iov_buf;
can_frame_t *frame;
can_frame_t frame_buf;
@@ -841,8 +872,12 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
iov = &iov_buf;
}
+ ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
+ if (ret)
+ return ret;
+
/* Check size of buffer */
- if (iov->iov_len != sizeof(can_frame_t))
+ if (iov->iov_len != sizeof(can_frame_t))
return -EMSGSIZE;
frame = (can_frame_t *)iov->iov_base;
--
2.1.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-05 7:09 ` C Smith
@ 2021-11-05 8:14 ` Jan Kiszka
2021-11-05 8:25 ` Bezdeka, Florian
0 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2021-11-05 8:14 UTC (permalink / raw)
To: C Smith, Bezdeka, Florian; +Cc: xenomai
On 05.11.21 08:09, C Smith wrote:
> Please review and accept this patch, which allows 32 bit apps to send
> and receive CAN. It is tested successfully with 32bit and 64bit compiles
> of utils/can/rtcansend.c / and rtcanrecv.c. The compat interface is now
> implemented, rtdm_get_iovec() is used and the get_sockaddr() methodology
> from the xddp sockets code was emulated to get the CAN receive to work.
Please write a commit message in a way that it motivates the change. Any
introductory words can go into a cover letter or...
>
> Signed-off-by: C Smith <csmithquestions@gmail.com
> <mailto:csmithquestions@gmail.com>>
> ---
...after this separator.
> kernel/drivers/can/rtcan_internal.h | 3 +
> kernel/drivers/can/rtcan_raw.c | 111
> ++++++++++++++++++++++++------------
> 2 files changed, 76 insertions(+), 38 deletions(-)
>
Not sure what the baseline was or if something was mangled, but the
patch does not apply on top of master/next.
> diff --git a/kernel/drivers/can/rtcan_internal.h
> b/kernel/drivers/can/rtcan_internal.h
> index b290005..03febef 100644
> --- a/kernel/drivers/can/rtcan_internal.h
> +++ b/kernel/drivers/can/rtcan_internal.h
> @@ -28,6 +28,7 @@
>
> #include <linux/module.h>
> #include <rtdm/driver.h>
> +#include <rtdm/compat.h>
>
> #ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
> #define RTCAN_ASSERT(expr, func) \
> @@ -58,4 +59,6 @@
> #define rtcandev_err(dev, fmt, args...) \
> printk(KERN_ERR "%s: " fmt, (dev)->name, ##args)
>
> +#define COMPAT_CASE(__op) case __op __COMPAT_CASE(__op ## _COMPAT)
> +
Why redefing this? It's part of rtdm/compat.h already, isn't it?
> #endif /* __RTCAN_INTERNAL_H_ */
> diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
> index 693b927..6e8ebe6 100644
> --- a/kernel/drivers/can/rtcan_raw.c
> +++ b/kernel/drivers/can/rtcan_raw.c
> @@ -215,6 +215,58 @@ EXPORT_SYMBOL_GPL(rtcan_loopback);
> #endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */
>
>
> +int rtcan_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_can **saddrp,
> + const void *arg)
> +{
> + struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> + int ret = 0;
> +
> + if (!rtdm_fd_is_user(fd)) {
> + setaddr = (struct _rtdm_setsockaddr_args *)arg;
> + *saddrp = (struct sockaddr_can *)setaddr->addr;
> + }
> +
> +#ifdef CONFIG_XENO_ARCH_SYS3264
> + if (rtdm_fd_is_compat(fd)) {
> + struct compat_rtdm_setsockaddr_args csetaddr_buff;
> +
> + /* Copy argument structure from userspace */
> + ret = rtdm_safe_copy_from_user(fd, &csetaddr_buff,
> + arg, sizeof(csetaddr_buff));
> + if (ret)
> + return ret;
> +
> + /* Check size */
> + if (csetaddr_buff.addrlen != sizeof(**saddrp))
Below you use sizeof(sockaddr_can). For consistency reasons, both tests
should use the same pattern.
> + return -EINVAL;
> +
> + return rtdm_safe_copy_from_user(fd, *saddrp,
> + compat_ptr(csetaddr_buff.addr),
> + sizeof(struct sockaddr_can));
> + *saddrp = NULL;
> + return 0;
> + }
> +#endif
> +
> + if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
> + sizeof(struct _rtdm_setsockaddr_args)))
> + return -EFAULT;
> +
> + setaddr = &setaddr_buf;
> +
> + /* Check size */
> + if (setaddr->addrlen != sizeof(struct sockaddr_can))
> + return -EINVAL;
> +
> + return rtdm_safe_copy_from_user(fd, *saddrp,
> + setaddr->addr,
> + sizeof(struct sockaddr_can));
> +
> + *saddrp = NULL;
> + return 0;
> +}
> +
> +
> int rtcan_raw_socket(struct rtdm_fd *fd, int protocol)
> {
> /* Only protocol CAN_RAW is supported */
> @@ -408,46 +460,21 @@ static int rtcan_raw_setsockopt(struct rtdm_fd *fd,
> int rtcan_raw_ioctl(struct rtdm_fd *fd,
> unsigned int request, void *arg)
> {
> + struct sockaddr_can saddr, *saddrp = &saddr;
> int ret = 0;
>
> switch (request) {
> - case _RTIOC_BIND: {
> - struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> - struct sockaddr_can *sockaddr, sockaddr_buf;
> -
> - if (rtdm_fd_is_user(fd)) {
> - /* Copy argument structure from userspace */
> - if (!rtdm_read_user_ok(fd, arg,
> - sizeof(struct _rtdm_setsockaddr_args)) ||
> - rtdm_copy_from_user(fd, &setaddr_buf, arg,
> - sizeof(struct _rtdm_setsockaddr_args)))
> - return -EFAULT;
>
> - setaddr = &setaddr_buf;
> + COMPAT_CASE(_RTIOC_BIND):
> + ret = rtcan_get_sockaddr(fd, &saddrp, arg);
> + if (ret)
> + return ret;
> + if (saddrp == NULL)
> + return -EFAULT;
> + ret = rtcan_raw_bind(fd, saddrp);
> + break;
Seeing this weird indention (even when ignoring the legacy original
indention of the target file before the change), I suspect the patch was
mangled by your email client.
>
> - /* Check size */
> - if (setaddr->addrlen != sizeof(struct sockaddr_can))
> - return -EINVAL;
> -
> - /* Copy argument structure from userspace */
> - if (!rtdm_read_user_ok(fd, arg,
> - sizeof(struct sockaddr_can)) ||
> - rtdm_copy_from_user(fd, &sockaddr_buf, setaddr->addr,
> - sizeof(struct sockaddr_can)))
> - return -EFAULT;
> - sockaddr = &sockaddr_buf;
> - } else {
> - setaddr = (struct _rtdm_setsockaddr_args *)arg;
> - sockaddr = (struct sockaddr_can *)setaddr->addr;
> - }
> -
> - /* Now, all required data are in kernel space */
> - ret = rtcan_raw_bind(fd, sockaddr);
> -
> - break;
> - }
> -
> - case _RTIOC_SETSOCKOPT: {
> + COMPAT_CASE(_RTIOC_SETSOCKOPT): {
> struct _rtdm_setsockopt_args *setopt;
> struct _rtdm_setsockopt_args setopt_buf;
>
> @@ -532,7 +559,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> struct sockaddr_can scan;
> nanosecs_rel_t timeout;
> - struct iovec *iov = (struct iovec *)msg->msg_iov;
> + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> struct iovec iov_buf;
> can_frame_t frame;
> nanosecs_abs_t timestamp = 0;
> @@ -584,6 +611,10 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> iov = &iov_buf;
> }
>
> + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> + if (ret)
> + return ret;
> +
> /* Check size of buffer */
> if (iov->iov_len < sizeof(can_frame_t))
> return -EMSGSIZE;
> @@ -768,7 +799,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
> struct sockaddr_can scan_buf;
> - struct iovec *iov = (struct iovec *)msg->msg_iov;
> + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> struct iovec iov_buf;
> can_frame_t *frame;
> can_frame_t frame_buf;
> @@ -841,8 +872,12 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> iov = &iov_buf;
> }
>
> + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> + if (ret)
> + return ret;
> +
> /* Check size of buffer */
> - if (iov->iov_len != sizeof(can_frame_t))
> + if (iov->iov_len != sizeof(can_frame_t))
> return -EMSGSIZE;
>
> frame = (can_frame_t *)iov->iov_base;
> --
> 2.1.0
Thanks,
Jan
--
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-05 8:14 ` Jan Kiszka
@ 2021-11-05 8:25 ` Bezdeka, Florian
2021-11-05 18:14 ` C Smith
0 siblings, 1 reply; 13+ messages in thread
From: Bezdeka, Florian @ 2021-11-05 8:25 UTC (permalink / raw)
To: jan.kiszka, csmithquestions; +Cc: xenomai
On Fri, 2021-11-05 at 09:14 +0100, Jan Kiszka wrote:
> On 05.11.21 08:09, C Smith wrote:
> > Please review and accept this patch, which allows 32 bit apps to send
> > and receive CAN. It is tested successfully with 32bit and 64bit compiles
> > of utils/can/rtcansend.c / and rtcanrecv.c. The compat interface is now
> > implemented, rtdm_get_iovec() is used and the get_sockaddr() methodology
> > from the xddp sockets code was emulated to get the CAN receive to work.
>
> Please write a commit message in a way that it motivates the change. Any
> introductory words can go into a cover letter or...
>
> >
> > Signed-off-by: C Smith <csmithquestions@gmail.com
> > <mailto:csmithquestions@gmail.com>>
> > ---
>
> ...after this separator.
>
> > kernel/drivers/can/rtcan_internal.h | 3 +
> > kernel/drivers/can/rtcan_raw.c | 111
> > ++++++++++++++++++++++++------------
> > 2 files changed, 76 insertions(+), 38 deletions(-)
> >
>
> Not sure what the baseline was or if something was mangled, but the
> patch does not apply on top of master/next.
>
> > diff --git a/kernel/drivers/can/rtcan_internal.h
> > b/kernel/drivers/can/rtcan_internal.h
> > index b290005..03febef 100644
> > --- a/kernel/drivers/can/rtcan_internal.h
> > +++ b/kernel/drivers/can/rtcan_internal.h
> > @@ -28,6 +28,7 @@
> >
> > #include <linux/module.h>
> > #include <rtdm/driver.h>
> > +#include <rtdm/compat.h>
> >
> > #ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
> > #define RTCAN_ASSERT(expr, func) \
> > @@ -58,4 +59,6 @@
> > #define rtcandev_err(dev, fmt, args...) \
> > printk(KERN_ERR "%s: " fmt, (dev)->name, ##args)
> >
> > +#define COMPAT_CASE(__op) case __op __COMPAT_CASE(__op ## _COMPAT)
> > +
>
> Why redefing this? It's part of rtdm/compat.h already, isn't it?
>
> > #endif /* __RTCAN_INTERNAL_H_ */
> > diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
> > index 693b927..6e8ebe6 100644
> > --- a/kernel/drivers/can/rtcan_raw.c
> > +++ b/kernel/drivers/can/rtcan_raw.c
> > @@ -215,6 +215,58 @@ EXPORT_SYMBOL_GPL(rtcan_loopback);
> > #endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */
> >
> >
> > +int rtcan_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_can **saddrp,
> > + const void *arg)
> > +{
> > + struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> > + int ret = 0;
> > +
> > + if (!rtdm_fd_is_user(fd)) {
> > + setaddr = (struct _rtdm_setsockaddr_args *)arg;
> > + *saddrp = (struct sockaddr_can *)setaddr->addr;
> > + }
> > +
> > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > + if (rtdm_fd_is_compat(fd)) {
> > + struct compat_rtdm_setsockaddr_args csetaddr_buff;
> > +
> > + /* Copy argument structure from userspace */
> > + ret = rtdm_safe_copy_from_user(fd, &csetaddr_buff,
> > + arg, sizeof(csetaddr_buff));
> > + if (ret)
> > + return ret;
> > +
> > + /* Check size */
> > + if (csetaddr_buff.addrlen != sizeof(**saddrp))
>
> Below you use sizeof(sockaddr_can). For consistency reasons, both tests
> should use the same pattern.
>
> > + return -EINVAL;
> > +
> > + return rtdm_safe_copy_from_user(fd, *saddrp,
> > + compat_ptr(csetaddr_buff.addr),
> > + sizeof(struct sockaddr_can));
> > + *saddrp = NULL;
> > + return 0;
Dead code. The last two lines will never be executed.
> > + }
> > +#endif
> > +
> > + if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
> > + sizeof(struct _rtdm_setsockaddr_args)))
> > + return -EFAULT;
> > +
> > + setaddr = &setaddr_buf;
> > +
> > + /* Check size */
> > + if (setaddr->addrlen != sizeof(struct sockaddr_can))
> > + return -EINVAL;
> > +
> > + return rtdm_safe_copy_from_user(fd, *saddrp,
> > + setaddr->addr,
> > + sizeof(struct sockaddr_can));
> > +
> > + *saddrp = NULL;
> > + return 0;
Dead code.
> > +}
> > +
> > +
> > int rtcan_raw_socket(struct rtdm_fd *fd, int protocol)
> > {
> > /* Only protocol CAN_RAW is supported */
> > @@ -408,46 +460,21 @@ static int rtcan_raw_setsockopt(struct rtdm_fd *fd,
> > int rtcan_raw_ioctl(struct rtdm_fd *fd,
> > unsigned int request, void *arg)
> > {
> > + struct sockaddr_can saddr, *saddrp = &saddr;
> > int ret = 0;
> >
> > switch (request) {
> > - case _RTIOC_BIND: {
> > - struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> > - struct sockaddr_can *sockaddr, sockaddr_buf;
> > -
> > - if (rtdm_fd_is_user(fd)) {
> > - /* Copy argument structure from userspace */
> > - if (!rtdm_read_user_ok(fd, arg,
> > - sizeof(struct _rtdm_setsockaddr_args)) ||
> > - rtdm_copy_from_user(fd, &setaddr_buf, arg,
> > - sizeof(struct _rtdm_setsockaddr_args)))
> > - return -EFAULT;
> >
> > - setaddr = &setaddr_buf;
> > + COMPAT_CASE(_RTIOC_BIND):
> > + ret = rtcan_get_sockaddr(fd, &saddrp, arg);
> > + if (ret)
> > + return ret;
> > + if (saddrp == NULL)
> > + return -EFAULT;
> > + ret = rtcan_raw_bind(fd, saddrp);
> > + break;
>
> Seeing this weird indention (even when ignoring the legacy original
> indention of the target file before the change), I suspect the patch was
> mangled by your email client.
>
> >
> > - /* Check size */
> > - if (setaddr->addrlen != sizeof(struct sockaddr_can))
> > - return -EINVAL;
> > -
> > - /* Copy argument structure from userspace */
> > - if (!rtdm_read_user_ok(fd, arg,
> > - sizeof(struct sockaddr_can)) ||
> > - rtdm_copy_from_user(fd, &sockaddr_buf, setaddr->addr,
> > - sizeof(struct sockaddr_can)))
> > - return -EFAULT;
> > - sockaddr = &sockaddr_buf;
> > - } else {
> > - setaddr = (struct _rtdm_setsockaddr_args *)arg;
> > - sockaddr = (struct sockaddr_can *)setaddr->addr;
> > - }
> > -
> > - /* Now, all required data are in kernel space */
> > - ret = rtcan_raw_bind(fd, sockaddr);
> > -
> > - break;
> > - }
> > -
> > - case _RTIOC_SETSOCKOPT: {
> > + COMPAT_CASE(_RTIOC_SETSOCKOPT): {
> > struct _rtdm_setsockopt_args *setopt;
> > struct _rtdm_setsockopt_args setopt_buf;
> >
> > @@ -532,7 +559,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> > struct sockaddr_can scan;
> > nanosecs_rel_t timeout;
> > - struct iovec *iov = (struct iovec *)msg->msg_iov;
> > + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> > struct iovec iov_buf;
> > can_frame_t frame;
> > nanosecs_abs_t timestamp = 0;
> > @@ -584,6 +611,10 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > iov = &iov_buf;
> > }
> >
> > + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> > + if (ret)
> > + return ret;
> > +
> > /* Check size of buffer */
> > if (iov->iov_len < sizeof(can_frame_t))
> > return -EMSGSIZE;
> > @@ -768,7 +799,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> > struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> > struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
> > struct sockaddr_can scan_buf;
> > - struct iovec *iov = (struct iovec *)msg->msg_iov;
> > + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> > struct iovec iov_buf;
> > can_frame_t *frame;
> > can_frame_t frame_buf;
> > @@ -841,8 +872,12 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> > iov = &iov_buf;
> > }
> >
> > + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> > + if (ret)
> > + return ret;
> > +
> > /* Check size of buffer */
> > - if (iov->iov_len != sizeof(can_frame_t))
> > + if (iov->iov_len != sizeof(can_frame_t))
> > return -EMSGSIZE;
> >
> > frame = (can_frame_t *)iov->iov_base;
> > --
> > 2.1.0
>
> Thanks,
> Jan
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-05 8:25 ` Bezdeka, Florian
@ 2021-11-05 18:14 ` C Smith
2021-11-05 18:21 ` Jan Kiszka
0 siblings, 1 reply; 13+ messages in thread
From: C Smith @ 2021-11-05 18:14 UTC (permalink / raw)
To: xenomai, Bezdeka, Florian, jan.kiszka
Here's an updated patch addressing mentioned issues.
I've noticed ipc/internal.h re-defines COMPAT_CASE(__op) as well.
I don't know what gmail is doing to the inline text (this should be
plain text) so I've also attached a .gz version of the patch.
Subject: [PATCH] 32-bit userspace app support for rtcan
Signed-off-by: C Smith <csmithquestions@gmail.com>
---
kernel/drivers/can/rtcan_internal.h | 1 +
kernel/drivers/can/rtcan_raw.c | 102 +++++++++++++++++++++++-------------
2 files changed, 67 insertions(+), 36 deletions(-)
diff --git a/kernel/drivers/can/rtcan_internal.h
b/kernel/drivers/can/rtcan_internal.h
index b290005..d1f9d31 100644
--- a/kernel/drivers/can/rtcan_internal.h
+++ b/kernel/drivers/can/rtcan_internal.h
@@ -28,6 +28,7 @@
#include <linux/module.h>
#include <rtdm/driver.h>
+#include <rtdm/compat.h>
#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
#define RTCAN_ASSERT(expr, func) \
diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
index 693b927..88a179f 100644
--- a/kernel/drivers/can/rtcan_raw.c
+++ b/kernel/drivers/can/rtcan_raw.c
@@ -215,6 +215,53 @@ EXPORT_SYMBOL_GPL(rtcan_loopback);
#endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */
+int rtcan_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_can **saddrp,
+ const void *arg)
+{
+ struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
+ int ret = 0;
+
+ if (!rtdm_fd_is_user(fd)) {
+ setaddr = (struct _rtdm_setsockaddr_args *)arg;
+ *saddrp = (struct sockaddr_can *)setaddr->addr;
+ }
+
+#ifdef CONFIG_XENO_ARCH_SYS3264
+ if (rtdm_fd_is_compat(fd)) {
+ struct compat_rtdm_setsockaddr_args csetaddr_buff;
+
+ /* Copy argument structure from userspace */
+ ret = rtdm_safe_copy_from_user(fd, &csetaddr_buff,
+ arg, sizeof(csetaddr_buff));
+ if (ret)
+ return ret;
+
+ /* Check size */
+ if (csetaddr_buff.addrlen != sizeof(struct sockaddr_can))
+ return -EINVAL;
+
+ return rtdm_safe_copy_from_user(fd, *saddrp,
+ compat_ptr(csetaddr_buff.addr),
+ sizeof(struct sockaddr_can));
+ }
+#endif
+
+ if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
+ sizeof(struct _rtdm_setsockaddr_args)))
+ return -EFAULT;
+
+ setaddr = &setaddr_buf;
+
+ /* Check size */
+ if (setaddr->addrlen != sizeof(struct sockaddr_can))
+ return -EINVAL;
+
+ return rtdm_safe_copy_from_user(fd, *saddrp,
+ setaddr->addr,
+ sizeof(struct sockaddr_can));
+}
+
+
int rtcan_raw_socket(struct rtdm_fd *fd, int protocol)
{
/* Only protocol CAN_RAW is supported */
@@ -408,46 +455,21 @@ static int rtcan_raw_setsockopt(struct rtdm_fd *fd,
int rtcan_raw_ioctl(struct rtdm_fd *fd,
unsigned int request, void *arg)
{
+ struct sockaddr_can saddr, *saddrp = &saddr;
int ret = 0;
switch (request) {
- case _RTIOC_BIND: {
- struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
- struct sockaddr_can *sockaddr, sockaddr_buf;
-
- if (rtdm_fd_is_user(fd)) {
- /* Copy argument structure from userspace */
- if (!rtdm_read_user_ok(fd, arg,
- sizeof(struct _rtdm_setsockaddr_args)) ||
- rtdm_copy_from_user(fd, &setaddr_buf, arg,
- sizeof(struct _rtdm_setsockaddr_args)))
- return -EFAULT;
-
- setaddr = &setaddr_buf;
-
- /* Check size */
- if (setaddr->addrlen != sizeof(struct sockaddr_can))
- return -EINVAL;
-
- /* Copy argument structure from userspace */
- if (!rtdm_read_user_ok(fd, arg,
- sizeof(struct sockaddr_can)) ||
- rtdm_copy_from_user(fd, &sockaddr_buf, setaddr->addr,
- sizeof(struct sockaddr_can)))
- return -EFAULT;
- sockaddr = &sockaddr_buf;
- } else {
- setaddr = (struct _rtdm_setsockaddr_args *)arg;
- sockaddr = (struct sockaddr_can *)setaddr->addr;
- }
-
- /* Now, all required data are in kernel space */
- ret = rtcan_raw_bind(fd, sockaddr);
+ COMPAT_CASE(_RTIOC_BIND):
+ ret = rtcan_get_sockaddr(fd, &saddrp, arg);
+ if (ret)
+ return ret;
+ if (saddrp == NULL)
+ return -EFAULT;
+ ret = rtcan_raw_bind(fd, saddrp);
break;
- }
- case _RTIOC_SETSOCKOPT: {
+ COMPAT_CASE(_RTIOC_SETSOCKOPT): {
struct _rtdm_setsockopt_args *setopt;
struct _rtdm_setsockopt_args setopt_buf;
@@ -532,7 +554,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
struct sockaddr_can scan;
nanosecs_rel_t timeout;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
struct iovec iov_buf;
can_frame_t frame;
nanosecs_abs_t timestamp = 0;
@@ -584,6 +606,10 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
iov = &iov_buf;
}
+ ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
+ if (ret)
+ return ret;
+
/* Check size of buffer */
if (iov->iov_len < sizeof(can_frame_t))
return -EMSGSIZE;
@@ -768,7 +794,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
struct rtcan_socket *sock = rtdm_fd_to_private(fd);
struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
struct sockaddr_can scan_buf;
- struct iovec *iov = (struct iovec *)msg->msg_iov;
+ struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
struct iovec iov_buf;
can_frame_t *frame;
can_frame_t frame_buf;
@@ -841,6 +867,10 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
iov = &iov_buf;
}
+ ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
+ if (ret)
+ return ret;
+
/* Check size of buffer */
if (iov->iov_len != sizeof(can_frame_t))
return -EMSGSIZE;
--
2.1.0
On Fri, Nov 5, 2021 at 1:25 AM Bezdeka, Florian
<florian.bezdeka@siemens.com> wrote:
>
> On Fri, 2021-11-05 at 09:14 +0100, Jan Kiszka wrote:
> > On 05.11.21 08:09, C Smith wrote:
> > > Please review and accept this patch, which allows 32 bit apps to send
> > > and receive CAN. It is tested successfully with 32bit and 64bit compiles
> > > of utils/can/rtcansend.c / and rtcanrecv.c. The compat interface is now
> > > implemented, rtdm_get_iovec() is used and the get_sockaddr() methodology
> > > from the xddp sockets code was emulated to get the CAN receive to work.
> >
> > Please write a commit message in a way that it motivates the change. Any
> > introductory words can go into a cover letter or...
> >
> > >
> > > Signed-off-by: C Smith <csmithquestions@gmail.com
> > > <mailto:csmithquestions@gmail.com>>
> > > ---
> >
> > ...after this separator.
> >
> > > kernel/drivers/can/rtcan_internal.h | 3 +
> > > kernel/drivers/can/rtcan_raw.c | 111
> > > ++++++++++++++++++++++++------------
> > > 2 files changed, 76 insertions(+), 38 deletions(-)
> > >
> >
> > Not sure what the baseline was or if something was mangled, but the
> > patch does not apply on top of master/next.
> >
> > > diff --git a/kernel/drivers/can/rtcan_internal.h
> > > b/kernel/drivers/can/rtcan_internal.h
> > > index b290005..03febef 100644
> > > --- a/kernel/drivers/can/rtcan_internal.h
> > > +++ b/kernel/drivers/can/rtcan_internal.h
> > > @@ -28,6 +28,7 @@
> > >
> > > #include <linux/module.h>
> > > #include <rtdm/driver.h>
> > > +#include <rtdm/compat.h>
> > >
> > > #ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
> > > #define RTCAN_ASSERT(expr, func) \
> > > @@ -58,4 +59,6 @@
> > > #define rtcandev_err(dev, fmt, args...) \
> > > printk(KERN_ERR "%s: " fmt, (dev)->name, ##args)
> > >
> > > +#define COMPAT_CASE(__op) case __op __COMPAT_CASE(__op ## _COMPAT)
> > > +
> >
> > Why redefing this? It's part of rtdm/compat.h already, isn't it?
> >
> > > #endif /* __RTCAN_INTERNAL_H_ */
> > > diff --git a/kernel/drivers/can/rtcan_raw.c b/kernel/drivers/can/rtcan_raw.c
> > > index 693b927..6e8ebe6 100644
> > > --- a/kernel/drivers/can/rtcan_raw.c
> > > +++ b/kernel/drivers/can/rtcan_raw.c
> > > @@ -215,6 +215,58 @@ EXPORT_SYMBOL_GPL(rtcan_loopback);
> > > #endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */
> > >
> > >
> > > +int rtcan_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_can **saddrp,
> > > + const void *arg)
> > > +{
> > > + struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> > > + int ret = 0;
> > > +
> > > + if (!rtdm_fd_is_user(fd)) {
> > > + setaddr = (struct _rtdm_setsockaddr_args *)arg;
> > > + *saddrp = (struct sockaddr_can *)setaddr->addr;
> > > + }
> > > +
> > > +#ifdef CONFIG_XENO_ARCH_SYS3264
> > > + if (rtdm_fd_is_compat(fd)) {
> > > + struct compat_rtdm_setsockaddr_args csetaddr_buff;
> > > +
> > > + /* Copy argument structure from userspace */
> > > + ret = rtdm_safe_copy_from_user(fd, &csetaddr_buff,
> > > + arg, sizeof(csetaddr_buff));
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /* Check size */
> > > + if (csetaddr_buff.addrlen != sizeof(**saddrp))
> >
> > Below you use sizeof(sockaddr_can). For consistency reasons, both tests
> > should use the same pattern.
> >
> > > + return -EINVAL;
> > > +
> > > + return rtdm_safe_copy_from_user(fd, *saddrp,
> > > + compat_ptr(csetaddr_buff.addr),
> > > + sizeof(struct sockaddr_can));
> > > + *saddrp = NULL;
> > > + return 0;
>
> Dead code. The last two lines will never be executed.
>
> > > + }
> > > +#endif
> > > +
> > > + if (rtdm_safe_copy_from_user(fd, &setaddr_buf, arg,
> > > + sizeof(struct _rtdm_setsockaddr_args)))
> > > + return -EFAULT;
> > > +
> > > + setaddr = &setaddr_buf;
> > > +
> > > + /* Check size */
> > > + if (setaddr->addrlen != sizeof(struct sockaddr_can))
> > > + return -EINVAL;
> > > +
> > > + return rtdm_safe_copy_from_user(fd, *saddrp,
> > > + setaddr->addr,
> > > + sizeof(struct sockaddr_can));
> > > +
> > > + *saddrp = NULL;
> > > + return 0;
>
> Dead code.
>
> > > +}
> > > +
> > > +
> > > int rtcan_raw_socket(struct rtdm_fd *fd, int protocol)
> > > {
> > > /* Only protocol CAN_RAW is supported */
> > > @@ -408,46 +460,21 @@ static int rtcan_raw_setsockopt(struct rtdm_fd *fd,
> > > int rtcan_raw_ioctl(struct rtdm_fd *fd,
> > > unsigned int request, void *arg)
> > > {
> > > + struct sockaddr_can saddr, *saddrp = &saddr;
> > > int ret = 0;
> > >
> > > switch (request) {
> > > - case _RTIOC_BIND: {
> > > - struct _rtdm_setsockaddr_args *setaddr, setaddr_buf;
> > > - struct sockaddr_can *sockaddr, sockaddr_buf;
> > > -
> > > - if (rtdm_fd_is_user(fd)) {
> > > - /* Copy argument structure from userspace */
> > > - if (!rtdm_read_user_ok(fd, arg,
> > > - sizeof(struct _rtdm_setsockaddr_args)) ||
> > > - rtdm_copy_from_user(fd, &setaddr_buf, arg,
> > > - sizeof(struct _rtdm_setsockaddr_args)))
> > > - return -EFAULT;
> > >
> > > - setaddr = &setaddr_buf;
> > > + COMPAT_CASE(_RTIOC_BIND):
> > > + ret = rtcan_get_sockaddr(fd, &saddrp, arg);
> > > + if (ret)
> > > + return ret;
> > > + if (saddrp == NULL)
> > > + return -EFAULT;
> > > + ret = rtcan_raw_bind(fd, saddrp);
> > > + break;
> >
> > Seeing this weird indention (even when ignoring the legacy original
> > indention of the target file before the change), I suspect the patch was
> > mangled by your email client.
> >
> > >
> > > - /* Check size */
> > > - if (setaddr->addrlen != sizeof(struct sockaddr_can))
> > > - return -EINVAL;
> > > -
> > > - /* Copy argument structure from userspace */
> > > - if (!rtdm_read_user_ok(fd, arg,
> > > - sizeof(struct sockaddr_can)) ||
> > > - rtdm_copy_from_user(fd, &sockaddr_buf, setaddr->addr,
> > > - sizeof(struct sockaddr_can)))
> > > - return -EFAULT;
> > > - sockaddr = &sockaddr_buf;
> > > - } else {
> > > - setaddr = (struct _rtdm_setsockaddr_args *)arg;
> > > - sockaddr = (struct sockaddr_can *)setaddr->addr;
> > > - }
> > > -
> > > - /* Now, all required data are in kernel space */
> > > - ret = rtcan_raw_bind(fd, sockaddr);
> > > -
> > > - break;
> > > - }
> > > -
> > > - case _RTIOC_SETSOCKOPT: {
> > > + COMPAT_CASE(_RTIOC_SETSOCKOPT): {
> > > struct _rtdm_setsockopt_args *setopt;
> > > struct _rtdm_setsockopt_args setopt_buf;
> > >
> > > @@ -532,7 +559,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > > struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> > > struct sockaddr_can scan;
> > > nanosecs_rel_t timeout;
> > > - struct iovec *iov = (struct iovec *)msg->msg_iov;
> > > + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> > > struct iovec iov_buf;
> > > can_frame_t frame;
> > > nanosecs_abs_t timestamp = 0;
> > > @@ -584,6 +611,10 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_fd *fd,
> > > iov = &iov_buf;
> > > }
> > >
> > > + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> > > + if (ret)
> > > + return ret;
> > > +
> > > /* Check size of buffer */
> > > if (iov->iov_len < sizeof(can_frame_t))
> > > return -EMSGSIZE;
> > > @@ -768,7 +799,7 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> > > struct rtcan_socket *sock = rtdm_fd_to_private(fd);
> > > struct sockaddr_can *scan = (struct sockaddr_can *)msg->msg_name;
> > > struct sockaddr_can scan_buf;
> > > - struct iovec *iov = (struct iovec *)msg->msg_iov;
> > > + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov;
> > > struct iovec iov_buf;
> > > can_frame_t *frame;
> > > can_frame_t frame_buf;
> > > @@ -841,8 +872,12 @@ ssize_t rtcan_raw_sendmsg(struct rtdm_fd *fd,
> > > iov = &iov_buf;
> > > }
> > >
> > > + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast);
> > > + if (ret)
> > > + return ret;
> > > +
> > > /* Check size of buffer */
> > > - if (iov->iov_len != sizeof(can_frame_t))
> > > + if (iov->iov_len != sizeof(can_frame_t))
> > > return -EMSGSIZE;
> > >
> > > frame = (can_frame_t *)iov->iov_base;
> > > --
> > > 2.1.0
> >
> > Thanks,
> > Jan
> >
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rtcan.patch.gz
Type: application/gzip
Size: 1730 bytes
Desc: not available
URL: <http://xenomai.org/pipermail/xenomai/attachments/20211105/f172ba0f/attachment.bin>
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: rtcansend 32-bit
2021-11-05 18:14 ` C Smith
@ 2021-11-05 18:21 ` Jan Kiszka
0 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-11-05 18:21 UTC (permalink / raw)
To: C Smith, xenomai, Bezdeka, Florian
On 05.11.21 19:14, C Smith wrote:
> Here's an updated patch addressing mentioned issues.
> I've noticed ipc/internal.h re-defines COMPAT_CASE(__op) as well.
>
> I don't know what gmail is doing to the inline text (this should be
> plain text) so I've also attached a .gz version of the patch.
>
Please use git send-email against gmail's SMTP server. The attached .gz
version is also incomplete.
Buildroot has a nicely detailed description how to get that ball rolling
(just replace addresses):
https://buildroot.org/downloads/manual/manual.html#submitting-patches
Jan
--
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-11-05 18:21 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-02 18:57 rtcansend 32-bit C Smith
2021-11-02 19:11 ` Jan Kiszka
2021-11-02 22:57 ` C Smith
2021-11-03 6:59 ` Jan Kiszka
2021-11-03 10:46 ` Jan Kiszka
2021-11-03 11:09 ` Bezdeka, Florian
2021-11-04 6:49 ` C Smith
2021-11-04 8:05 ` Bezdeka, Florian
2021-11-05 7:09 ` C Smith
2021-11-05 8:14 ` Jan Kiszka
2021-11-05 8:25 ` Bezdeka, Florian
2021-11-05 18:14 ` C Smith
2021-11-05 18:21 ` Jan Kiszka
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.