All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Biedl <linux-kernel.bfrz@manchmal.in-ulm.de>
To: linux-parisc@vger.kernel.org
Subject: Testing the lws_compare_and_swap_2 syscall
Date: Tue, 24 Oct 2017 22:03:42 +0200	[thread overview]
Message-ID: <1508874207@msgid.manchmal.in-ulm.de> (raw)

Hello,

looking into John's recent fix for lws_compare_and_swap_2 on 32bit
systems I got the feeling things still aren't right yet. To defeat
or prove that, also since I'd like to learn more about this ... I wrote
a small program the uses that syscall, and things break galore.

Could you please check the code below[1] for obvious usage errors? Note
the entire cmpxchg2 function was copied from gcc, and the disassembly
output provided by objdump looks correct as far as I can tell.

The program takes four numerical parameters that correspond to the
four parameters of the syscall.

To start with, using the invalid value 4 as size parameter does not
return ENOSYS as I'd expect but crashes my system[2], using both 32 and
64 bit kernel, no root privileges required. This should never happen.

Regards,
    Christoph

[1]
======================================================================
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

/* borrowed from __kernel_cmpxchg2 in libgcc/config/pa/linux-atomic.c in the gcc sources */
static inline long
cmpxchg2 (void *mem, const void *oldval, const void *newval,
                   int val_size)
{
  register unsigned long lws_mem asm("r26") = (unsigned long) (mem);
  register unsigned long lws_old asm("r25") = (unsigned long) oldval;
  register unsigned long lws_new asm("r24") = (unsigned long) newval;
  register int lws_size asm("r23") = val_size;
  register long lws_ret   asm("r28");
  register long lws_errno asm("r21");
  asm volatile (        "ble    0xb0(%%sr2, %%r0)       \n\t"
                        "ldi    %6, %%r20               \n\t"
        : "=r" (lws_ret), "=r" (lws_errno), "+r" (lws_mem),
          "+r" (lws_old), "+r" (lws_new), "+r" (lws_size)
        : "i" (2)
        : "r1", "r20", "r22", "r29", "r31", "fr4", "memory"
  );

  /* If the kernel LWS call is successful, lws_ret contains 0.  */
  if (__builtin_expect (lws_ret == 0, 1))
    return 0;

  if (__builtin_expect (lws_errno == -EFAULT || lws_errno == -ENOSYS, 0))
    __builtin_trap ();

  /* If the kernel LWS call fails with no error, return -EBUSY */
  if (__builtin_expect (!lws_errno, 0))
    return -EBUSY;

  return lws_errno;
}



int main (int argc, char **argv) {

    if (argc != 5) {
        printf ("usage <mem> <old> <new> <size>\n");
        exit (1);
    }

    uint64_t a = atoi (argv[1]);
    uint64_t b = atoi (argv[2]);
    uint64_t c = atoi (argv[3]);
    unsigned long size = atoi (argv[4]);

    printf ("a = 0x%016llx, b = 0x%016llx, c = 0x%016llx\n",
        a,
        b,
        c
    );

    unsigned long r = cmpxchg2 (&a, &b, &c, size);

    printf ("a = 0x%016llx\n", a);
    printf ("r = 0x%lx\n", r);

    return 0;
}
======================================================================


[2]
| Backtrace:
|
| Kernel Fault: Code=26 (Data memory access rights trap) regs=000000007ca8f738 (Addr=0000000000000002)
| CPU: 0 PID: 1289 Comm: a.out Not tainted 4.12.0-2-parisc64-smp #1 Debian 4.12.13-1
| task: 000000007ca8eec0 task.stack: 000000007cb68000
|
|      YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
| PSW: 00001000000001101111111100001111 Not tainted
| r00-03  000000ff0806ff0f 0000000040cf2000 0000000000010987 00000000f93963c0
| r04-07  00000000f853fc70 00000000ffffffff 00000000ffffffff 00000000ffffffff
| r08-11  00000000fffffffe 00000000ffffffff 00000000fffffffd 00000000000ed000
| r12-15  00000000ffffffff 0000000000911d28 0000000000000000 0000000000117be8
| r16-19  00000000009ce448 0000000000000000 0000000000000001 00000000f9396328
| r20-23  0000000000000002 00000000000004d4 00000000f844a08c 0000000000000004
| r24-27  00000000f9396330 00000000f9396328 00000000f9396320 0000000000011100
| r28-31  0000000040cf2528 0000000000000010 00000000f9396400 00000000000106e7
| sr00-03  00000000003a7800 0000000000000000 0000000000000000 00000000003a7800
| sr04-07  00000000003a7800 00000000003a7800 00000000003a7800 00000000003a7800
|
| IASQ: 0000000000000000 0000000000000000 IAOQ: 0000000000000578 000000000000057c
|  IIR: 0e8095dc    ISR: 0000000000000000  IOR: 0000000000000002
|  CPU:        0   CR30: 000000007cb68000 CR31: 0000000011111111
|  ORIG_R28: 0000000000000000
|  IAOQ[0]: 0x578
|  IAOQ[1]: 0x57c
|  RP(r2): 0x10987
| Backtrace:
|
| Kernel panic - not syncing: Kernel Fault
| ---[ end Kernel panic - not syncing: Kernel Fault

             reply	other threads:[~2017-10-24 20:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-24 20:03 Christoph Biedl [this message]
2017-10-25  1:48 ` Testing the lws_compare_and_swap_2 syscall John David Anglin
2017-10-26  0:22   ` Christoph Biedl
2017-10-26 14:06     ` John David Anglin
2017-11-06 21:27     ` Helge Deller
2017-11-06 22:45       ` John David Anglin
2017-11-07 21:31         ` John David Anglin
2017-11-07 21:46       ` Christoph Biedl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1508874207@msgid.manchmal.in-ulm.de \
    --to=linux-kernel.bfrz@manchmal.in-ulm.de \
    --cc=linux-parisc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.