[PATCH 5/8] macintosh/adb-iop: Resolve static checker warnings

2020-05-30 Thread Finn Thain
drivers/macintosh/adb-iop.c:215:28: warning: Using plain integer as NULL pointer
drivers/macintosh/adb-iop.c:170:5: warning: symbol 'adb_iop_probe' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:177:5: warning: symbol 'adb_iop_init' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:184:5: warning: symbol 'adb_iop_send_request' was 
not declared. Should it be static?
drivers/macintosh/adb-iop.c:230:5: warning: symbol 'adb_iop_autopoll' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:236:6: warning: symbol 'adb_iop_poll' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:241:5: warning: symbol 'adb_iop_reset_bus' was not 
declared. Should it be static?

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 7ecc41bc7358..a2b28e09f2ce 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -166,21 +166,21 @@ static void adb_iop_start(void)
 adb_iop_complete);
 }
 
-int adb_iop_probe(void)
+static int adb_iop_probe(void)
 {
if (!iop_ism_present)
return -ENODEV;
return 0;
 }
 
-int adb_iop_init(void)
+static int adb_iop_init(void)
 {
pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n");
iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
return 0;
 }
 
-int adb_iop_send_request(struct adb_request *req, int sync)
+static int adb_iop_send_request(struct adb_request *req, int sync)
 {
int err;
 
@@ -211,7 +211,7 @@ static int adb_iop_write(struct adb_request *req)
 
local_irq_save(flags);
 
-   if (current_req != 0) {
+   if (current_req) {
last_req->next = req;
last_req = req;
} else {
@@ -227,18 +227,18 @@ static int adb_iop_write(struct adb_request *req)
return 0;
 }
 
-int adb_iop_autopoll(int devs)
+static int adb_iop_autopoll(int devs)
 {
/* TODO: how do we enable/disable autopoll? */
return 0;
 }
 
-void adb_iop_poll(void)
+static void adb_iop_poll(void)
 {
iop_ism_irq_poll(ADB_IOP);
 }
 
-int adb_iop_reset_bus(void)
+static int adb_iop_reset_bus(void)
 {
struct adb_request req;
 
-- 
2.26.2



[PATCH 7/8] macintosh/adb-iop: Implement sending -> idle state transition

2020-05-30 Thread Finn Thain
On leaving the 'sending' state, proceed to the 'idle' state if no reply is
expected. Drop redundant test for adb_iop_state == sending && current_req.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index f22792c95d4f..8594e4f9a830 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -77,15 +77,14 @@ static void adb_iop_done(void)
 
 static void adb_iop_complete(struct iop_msg *msg)
 {
-   struct adb_request *req;
unsigned long flags;
 
local_irq_save(flags);
 
-   req = current_req;
-   if ((adb_iop_state == sending) && req && req->reply_expected) {
+   if (current_req->reply_expected)
adb_iop_state = awaiting_reply;
-   }
+   else
+   adb_iop_done();
 
local_irq_restore(flags);
 }
-- 
2.26.2



[PATCH 4/8] macintosh/adb-iop: Access current_req and adb_iop_state when inside lock

2020-05-30 Thread Finn Thain
Drop the redundant local_irq_save/restore() from adb_iop_start() because
the caller has to do it anyway. This is the pattern used in via-macii.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index c3089dacf2e2..7ecc41bc7358 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -137,7 +137,6 @@ static void adb_iop_listen(struct iop_msg *msg)
 
 static void adb_iop_start(void)
 {
-   unsigned long flags;
struct adb_request *req;
struct adb_iopmsg amsg;
 
@@ -146,8 +145,6 @@ static void adb_iop_start(void)
if (!req)
return;
 
-   local_irq_save(flags);
-
/* The IOP takes MacII-style packets, so strip the initial
 * ADB_PACKET byte.
 */
@@ -161,7 +158,6 @@ static void adb_iop_start(void)
 
req->sent = 1;
adb_iop_state = sending;
-   local_irq_restore(flags);
 
/* Now send it. The IOP manager will call adb_iop_complete
 * when the message has been sent.
@@ -208,13 +204,13 @@ static int adb_iop_write(struct adb_request *req)
return -EINVAL;
}
 
-   local_irq_save(flags);
-
req->next = NULL;
req->sent = 0;
req->complete = 0;
req->reply_len = 0;
 
+   local_irq_save(flags);
+
if (current_req != 0) {
last_req->next = req;
last_req = req;
@@ -223,10 +219,11 @@ static int adb_iop_write(struct adb_request *req)
last_req = req;
}
 
-   local_irq_restore(flags);
-
if (adb_iop_state == idle)
adb_iop_start();
+
+   local_irq_restore(flags);
+
return 0;
 }
 
-- 
2.26.2



[PATCH 3/8] macintosh/adb-iop: Adopt bus reset algorithm from via-macii driver

2020-05-30 Thread Finn Thain
This algorithm is slightly shorter and avoids the surprising
adb_iop_start() call in adb_iop_poll().

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index ca3b411b0742..c3089dacf2e2 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -238,24 +238,19 @@ int adb_iop_autopoll(int devs)
 
 void adb_iop_poll(void)
 {
-   if (adb_iop_state == idle)
-   adb_iop_start();
iop_ism_irq_poll(ADB_IOP);
 }
 
 int adb_iop_reset_bus(void)
 {
-   struct adb_request req = {
-   .reply_expected = 0,
-   .nbytes = 2,
-   .data = { ADB_PACKET, 0 },
-   };
-
-   adb_iop_write(&req);
-   while (!req.complete) {
-   adb_iop_poll();
-   schedule();
-   }
+   struct adb_request req;
+
+   /* Command = 0, Address = ignored */
+   adb_request(&req, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
+   adb_iop_send_request(&req, 1);
+
+   /* Don't want any more requests during the Global Reset low time. */
+   mdelay(3);
 
return 0;
 }
-- 
2.26.2



[PATCH 2/8] macintosh/adb-iop: Correct comment text

2020-05-30 Thread Finn Thain
This patch improves comment style and corrects some misunderstandings
in the text.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index ce28ff40fb9c..ca3b411b0742 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -101,11 +101,10 @@ static void adb_iop_listen(struct iop_msg *msg)
 
req = current_req;
 
-   /* Handle a timeout. Timeout packets seem to occur even after */
-   /* we've gotten a valid reply to a TALK, so I'm assuming that */
-   /* a "timeout" is actually more like an "end-of-data" signal. */
-   /* We need to send back a timeout packet to the IOP to shut   */
-   /* it up, plus complete the current request, if any.  */
+   /* Handle a timeout. Timeout packets seem to occur even after
+* we've gotten a valid reply to a TALK, presumably because of
+* autopolling.
+*/
 
if (amsg->flags & ADB_IOP_TIMEOUT) {
msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
@@ -115,9 +114,6 @@ static void adb_iop_listen(struct iop_msg *msg)
adb_iop_end_req(req, idle);
}
} else {
-   /* TODO: is it possible for more than one chunk of data  */
-   /*   to arrive before the timeout? If so we need to */
-   /*   use reply_ptr here like the other drivers do.  */
if ((adb_iop_state == awaiting_reply) &&
(amsg->flags & ADB_IOP_EXPLICIT)) {
req->reply_len = amsg->count + 1;
@@ -152,23 +148,24 @@ static void adb_iop_start(void)
 
local_irq_save(flags);
 
-   /* The IOP takes MacII-style packets, so */
-   /* strip the initial ADB_PACKET byte.*/
-
+   /* The IOP takes MacII-style packets, so strip the initial
+* ADB_PACKET byte.
+*/
amsg.flags = ADB_IOP_EXPLICIT;
amsg.count = req->nbytes - 2;
 
-   /* amsg.data immediately follows amsg.cmd, effectively making */
-   /* amsg.cmd a pointer to the beginning of a full ADB packet.  */
+   /* amsg.data immediately follows amsg.cmd, effectively making
+* &amsg.cmd a pointer to the beginning of a full ADB packet.
+*/
memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1);
 
req->sent = 1;
adb_iop_state = sending;
local_irq_restore(flags);
 
-   /* Now send it. The IOP manager will call adb_iop_complete */
-   /* when the packet has been sent.  */
-
+   /* Now send it. The IOP manager will call adb_iop_complete
+* when the message has been sent.
+*/
iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *)&amsg,
 adb_iop_complete);
 }
-- 
2.26.2



[PATCH 1/8] macintosh/adb-iop: Remove dead and redundant code

2020-05-30 Thread Finn Thain
Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 29 -
 1 file changed, 29 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index fca31640e3ef..ce28ff40fb9c 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -18,24 +18,16 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
 
-/*#define DEBUG_ADB_IOP*/
-
 static struct adb_request *current_req;
 static struct adb_request *last_req;
-#if 0
-static unsigned char reply_buff[16];
-static unsigned char *reply_ptr;
-#endif
 
 static enum adb_iop_state {
idle,
@@ -104,22 +96,11 @@ static void adb_iop_listen(struct iop_msg *msg)
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
struct adb_request *req;
unsigned long flags;
-#ifdef DEBUG_ADB_IOP
-   int i;
-#endif
 
local_irq_save(flags);
 
req = current_req;
 
-#ifdef DEBUG_ADB_IOP
-   printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req,
-  (uint)amsg->count + 2, (uint)amsg->flags, (uint)amsg->cmd);
-   for (i = 0; i < amsg->count; i++)
-   printk(" %02X", (uint)amsg->data[i]);
-   printk("\n");
-#endif
-
/* Handle a timeout. Timeout packets seem to occur even after */
/* we've gotten a valid reply to a TALK, so I'm assuming that */
/* a "timeout" is actually more like an "end-of-data" signal. */
@@ -163,9 +144,6 @@ static void adb_iop_start(void)
unsigned long flags;
struct adb_request *req;
struct adb_iopmsg amsg;
-#ifdef DEBUG_ADB_IOP
-   int i;
-#endif
 
/* get the packet to send */
req = current_req;
@@ -174,13 +152,6 @@ static void adb_iop_start(void)
 
local_irq_save(flags);
 
-#ifdef DEBUG_ADB_IOP
-   printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes);
-   for (i = 0; i < req->nbytes; i++)
-   printk(" %02X", (uint)req->data[i]);
-   printk("\n");
-#endif
-
/* The IOP takes MacII-style packets, so */
/* strip the initial ADB_PACKET byte.*/
 
-- 
2.26.2



[PATCH 0/8] Mac ADB IOP driver fixes

2020-05-30 Thread Finn Thain
The adb-iop driver was never finished. Some deficiencies have become
apparent over the years. For example,

 - Mouse and/or keyboard may stop working if used together

 - SRQ autopoll list cannot be changed

 - Some bugs were found by inspection

This patch series contains fixes for the known bugs in the driver, plus
a few clean-ups.


Finn Thain (8):
  macintosh/adb-iop: Remove dead and redundant code
  macintosh/adb-iop: Correct comment text
  macintosh/adb-iop: Adopt bus reset algorithm from via-macii driver
  macintosh/adb-iop: Access current_req and adb_iop_state when inside
lock
  macintosh/adb-iop: Resolve static checker warnings
  macintosh/adb-iop: Implement idle -> sending state transition
  macintosh/adb-iop: Implement sending -> idle state transition
  macintosh/adb-iop: Implement SRQ autopolling

 arch/m68k/include/asm/adb_iop.h |   1 +
 drivers/macintosh/adb-iop.c | 186 +++-
 2 files changed, 86 insertions(+), 101 deletions(-)

-- 
2.26.2



[PATCH 6/8] macintosh/adb-iop: Implement idle -> sending state transition

2020-05-30 Thread Finn Thain
In the present algorithm, the 'idle' state transition does not take
place until there's a bus timeout. Once idle, the driver does not
automatically proceed with the next request.

Change the algorithm so that queued ADB requests will be sent as soon as
the driver becomes idle. This is to take place after the current IOP
message is completed.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 43 +
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index a2b28e09f2ce..f22792c95d4f 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -54,13 +54,19 @@ struct adb_driver adb_iop_driver = {
.reset_bus= adb_iop_reset_bus
 };
 
-static void adb_iop_end_req(struct adb_request *req, int state)
+static void adb_iop_done(void)
 {
+   struct adb_request *req = current_req;
+
+   adb_iop_state = idle;
+
req->complete = 1;
current_req = req->next;
if (req->done)
(*req->done)(req);
-   adb_iop_state = state;
+
+   if (adb_iop_state == idle)
+   adb_iop_start();
 }
 
 /*
@@ -94,37 +100,36 @@ static void adb_iop_complete(struct iop_msg *msg)
 static void adb_iop_listen(struct iop_msg *msg)
 {
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
-   struct adb_request *req;
unsigned long flags;
+   bool req_done = false;
 
local_irq_save(flags);
 
-   req = current_req;
-
/* Handle a timeout. Timeout packets seem to occur even after
 * we've gotten a valid reply to a TALK, presumably because of
 * autopolling.
 */
 
-   if (amsg->flags & ADB_IOP_TIMEOUT) {
-   msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
-   msg->reply[1] = 0;
-   msg->reply[2] = 0;
-   if (req && (adb_iop_state != idle)) {
-   adb_iop_end_req(req, idle);
-   }
-   } else {
-   if ((adb_iop_state == awaiting_reply) &&
-   (amsg->flags & ADB_IOP_EXPLICIT)) {
+   if (amsg->flags & ADB_IOP_EXPLICIT) {
+   if (adb_iop_state == awaiting_reply) {
+   struct adb_request *req = current_req;
+
req->reply_len = amsg->count + 1;
memcpy(req->reply, &amsg->cmd, req->reply_len);
-   } else {
-   adb_input(&amsg->cmd, amsg->count + 1,
- amsg->flags & ADB_IOP_AUTOPOLL);
+
+   req_done = true;
}
-   memcpy(msg->reply, msg->message, IOP_MSG_LEN);
+   } else if (!(amsg->flags & ADB_IOP_TIMEOUT)) {
+   adb_input(&amsg->cmd, amsg->count + 1,
+ amsg->flags & ADB_IOP_AUTOPOLL);
}
+
+   msg->reply[0] = ADB_IOP_AUTOPOLL;
iop_complete_message(msg);
+
+   if (req_done)
+   adb_iop_done();
+
local_irq_restore(flags);
 }
 
-- 
2.26.2



[PATCH 8/8] macintosh/adb-iop: Implement SRQ autopolling

2020-05-30 Thread Finn Thain
The adb_driver.autopoll method is needed during ADB bus scan and device
address assignment. Implement this method so that the IOP's list of
device addresses can be updated. When the list is empty, disable SRQ
autopolling.

Cc: Joshua Thompson 
Cc: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/m68k/include/asm/adb_iop.h |  1 +
 drivers/macintosh/adb-iop.c | 32 ++--
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/m68k/include/asm/adb_iop.h b/arch/m68k/include/asm/adb_iop.h
index 195d7fb1268c..6aecd020e2fc 100644
--- a/arch/m68k/include/asm/adb_iop.h
+++ b/arch/m68k/include/asm/adb_iop.h
@@ -29,6 +29,7 @@
 
 #define ADB_IOP_EXPLICIT   0x80/* nonzero if explicit command */
 #define ADB_IOP_AUTOPOLL   0x40/* auto/SRQ polling enabled*/
+#define ADB_IOP_SET_AUTOPOLL   0x20/* set autopoll device list*/
 #define ADB_IOP_SRQ0x04/* SRQ detected*/
 #define ADB_IOP_TIMEOUT0x02/* nonzero if timeout  
*/
 
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 8594e4f9a830..f3d1a460fbce 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -7,10 +7,6 @@
  * 1999-07-01 (jmt) - First implementation for new driver architecture.
  *
  * 1999-07-31 (jmt) - First working version.
- *
- * TODO:
- *
- * o Implement SRQ handling.
  */
 
 #include 
@@ -28,6 +24,7 @@
 
 static struct adb_request *current_req;
 static struct adb_request *last_req;
+static unsigned int autopoll_devs;
 
 static enum adb_iop_state {
idle,
@@ -123,7 +120,7 @@ static void adb_iop_listen(struct iop_msg *msg)
  amsg->flags & ADB_IOP_AUTOPOLL);
}
 
-   msg->reply[0] = ADB_IOP_AUTOPOLL;
+   msg->reply[0] = autopoll_devs ? ADB_IOP_AUTOPOLL : 0;
iop_complete_message(msg);
 
if (req_done)
@@ -231,9 +228,32 @@ static int adb_iop_write(struct adb_request *req)
return 0;
 }
 
+static void adb_iop_set_ap_complete(struct iop_msg *msg)
+{
+   struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
+
+   autopoll_devs = (amsg->data[1] << 8) | amsg->data[0];
+}
+
 static int adb_iop_autopoll(int devs)
 {
-   /* TODO: how do we enable/disable autopoll? */
+   struct adb_iopmsg amsg;
+   unsigned long flags;
+   unsigned int mask = (unsigned int)devs & 0xFFFE;
+
+   local_irq_save(flags);
+
+   amsg.flags = ADB_IOP_SET_AUTOPOLL | (mask ? ADB_IOP_AUTOPOLL : 0);
+   amsg.count = 2;
+   amsg.cmd = 0;
+   amsg.data[0] = mask & 0xFF;
+   amsg.data[1] = (mask >> 8) & 0xFF;
+
+   iop_send_message(ADB_IOP, ADB_CHAN, NULL, sizeof(amsg), (__u8 *)&amsg,
+adb_iop_set_ap_complete);
+
+   local_irq_restore(flags);
+
return 0;
 }
 
-- 
2.26.2



Re: [musl] ppc64le and 32-bit LE userland compatibility

2020-05-30 Thread Will Springer
On Friday, May 29, 2020 12:24:27 PM PDT Rich Felker wrote:
> The argument passing for pread/pwrite is historically a mess and
> differs between archs. musl has a dedicated macro that archs can
> define to override it. But it looks like it should match regardless of
> BE vs LE, and musl already defines it for powerpc with the default
> definition, adding a zero arg to start on an even arg-slot index,
> which is an odd register (since ppc32 args start with an odd one, r3).
> 
> > [6]:
> > https://gist.github.com/Skirmisher/02891c1a8cafa0ff18b2460933ef4f3c
> I don't think this is correct, but I'm confused about where it's
> getting messed up because it looks like it should already be right.

Hmm, interesting. Will have to go back to it I guess...

> > This was enough to fix up the `file` bug. I'm no seasoned kernel
> > hacker, though, and there is still concern over the right way to
> > approach this, whether it should live in the kernel or libc, etc.
> > Frankly, I don't know the ABI structure enough to understand why the
> > register padding has to be different in this case, or what
> > lower-level component is responsible for it.. For comparison, I had a
> > look at the mips tree, since it's bi-endian and has a similar 32/64
> > situation. There is a macro conditional upon endianness that is
> > responsible for munging long longs; it uses __MIPSEB__ and __MIPSEL__
> > instead of an if/else on the generic __LITTLE_ENDIAN__. Not sure what
> > to make of that. (It also simply swaps registers for LE, unlike what
> > I did for ppc.)
> Indeed the problem is probably that you need to swap registers for LE,
> not remove the padding slot. Did you check what happens if you pass a
> value larger than 32 bits?
> 
> If so, the right way to fix this on the kernel side would be to
> construct the value as a union rather than by bitwise ops so it's
> endian-agnostic:
> 
>   (union { u32 parts[2]; u64 val; }){{ arg1, arg2 }}.val
> 
> But the kernel folks might prefer endian ifdefs for some odd reason...

You are right, this does seem odd considering what the other archs do. 
It's quite possible I made a silly mistake, of course...

I haven't tested with values outside the 32-bit range yet; again, this is 
new territory for me, so I haven't exactly done exhaustive tests on 
everything. I'll give it a closer look.

> > Also worth noting is the one other outstanding bug, where the
> > time-related syscalls in the 32-bit vDSO seem to return garbage. It
> > doesn't look like an endian bug to me, and it doesn't affect standard
> > syscalls (which is why if you run `date` on musl it prints the
> > correct time, unlike on glibc). The vDSO time functions are
> > implemented in ppc asm (arch/powerpc/kernel/vdso32/ gettimeofday.S),
> > and I've never touched the stuff, so if anyone has a clue I'm all
> > ears.
> Not sure about this. Worst-case, just leave it disabled until someone
> finds a fix.

Apparently these asm implementations are being replaced by the generic C 
ones [1], so it may be this fixes itself on its own.

Thanks,
Will [she/her]

[1]: https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=173231








[PATCH v1 4/4] KVM: PPC: Book3S HV: migrate hot plugged memory

2020-05-30 Thread Ram Pai
From: Laurent Dufour 

When a memory slot is hot plugged to a SVM, GFNs associated with that
memory slot automatically default to secure GFN. Hence migrate the
PFNs associated with these GFNs to device-PFNs.

uv_migrate_mem_slot() is called to achieve that. It will not call
UV_PAGE_IN since this request is ignored by the Ultravisor.
NOTE: Ultravisor does not trust any page content provided by
the Hypervisor, ones the VM turns secure.

Cc: Paul Mackerras 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Bharata B Rao 
Cc: Aneesh Kumar K.V 
Cc: Sukadev Bhattiprolu 
Cc: Laurent Dufour 
Cc: Thiago Jung Bauermann 
Cc: David Gibson 
Cc: Claudio Carvalho 
Cc: kvm-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ram Pai 
(fixed merge conflicts. Modified the commit message)
Signed-off-by: Laurent Dufour 
---
 arch/powerpc/include/asm/kvm_book3s_uvmem.h |  4 
 arch/powerpc/kvm/book3s_hv.c| 11 +++
 arch/powerpc/kvm/book3s_hv_uvmem.c  |  3 +--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s_uvmem.h 
b/arch/powerpc/include/asm/kvm_book3s_uvmem.h
index f0c5708..2ec2e5afb 100644
--- a/arch/powerpc/include/asm/kvm_book3s_uvmem.h
+++ b/arch/powerpc/include/asm/kvm_book3s_uvmem.h
@@ -23,6 +23,7 @@ unsigned long kvmppc_h_svm_page_out(struct kvm *kvm,
 void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
 struct kvm *kvm, bool skip_page_out,
 bool purge_gfn);
+int uv_migrate_mem_slot(struct kvm *kvm, const struct kvm_memory_slot 
*memslot);
 #else
 static inline int kvmppc_uvmem_init(void)
 {
@@ -78,5 +79,8 @@ static inline int kvmppc_send_page_to_uv(struct kvm *kvm, 
unsigned long gfn)
 kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
struct kvm *kvm, bool skip_page_out,
bool purge_gfn) { }
+
+static int uv_migrate_mem_slot(struct kvm *kvm,
+   const struct kvm_memory_slot *memslot);
 #endif /* CONFIG_PPC_UV */
 #endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 4c62bfe..604d062 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -4516,13 +4516,16 @@ static void kvmppc_core_commit_memory_region_hv(struct 
kvm *kvm,
case KVM_MR_CREATE:
if (kvmppc_uvmem_slot_init(kvm, new))
return;
-   uv_register_mem_slot(kvm->arch.lpid,
-new->base_gfn << PAGE_SHIFT,
-new->npages * PAGE_SIZE,
-0, new->id);
+   if (uv_register_mem_slot(kvm->arch.lpid,
+new->base_gfn << PAGE_SHIFT,
+new->npages * PAGE_SIZE,
+0, new->id))
+   return;
+   uv_migrate_mem_slot(kvm, new);
break;
case KVM_MR_DELETE:
uv_unregister_mem_slot(kvm->arch.lpid, old->id);
+   kvmppc_uvmem_drop_pages(old, kvm, true, true);
kvmppc_uvmem_slot_free(kvm, old);
break;
default:
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 36dda1d..1fa5f2a 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -377,8 +377,7 @@ static int kvmppc_svm_migrate_page(struct vm_area_struct 
*vma,
return ret;
 }
 
-static int uv_migrate_mem_slot(struct kvm *kvm,
-   const struct kvm_memory_slot *memslot)
+int uv_migrate_mem_slot(struct kvm *kvm, const struct kvm_memory_slot *memslot)
 {
unsigned long gfn = memslot->base_gfn;
unsigned long end;
-- 
1.8.3.1



[PATCH v1 3/4] KVM: PPC: Book3S HV: migrate remaining normal-GFNs to secure-GFNs in H_SVM_INIT_DONE

2020-05-30 Thread Ram Pai
H_SVM_INIT_DONE incorrectly assumes that the Ultravisor has explicitly
called H_SVM_PAGE_IN for all secure pages. These GFNs continue to be
normal GFNs associated with normal PFNs; when infact, these GFNs should
have been secure GFNs associated with device PFNs.

Move all the PFN associated with the SVM's GFNs to device PFNs, in
H_SVM_INIT_DONE. Skip the GFNs that are already Paged-in or Shared
through H_SVM_PAGE_IN.

Cc: Paul Mackerras 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Bharata B Rao 
Cc: Aneesh Kumar K.V 
Cc: Sukadev Bhattiprolu 
Cc: Laurent Dufour 
Cc: Thiago Jung Bauermann 
Cc: David Gibson 
Cc: Claudio Carvalho 
Cc: kvm-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ram Pai 
---
 Documentation/powerpc/ultravisor.rst |   2 +
 arch/powerpc/kvm/book3s_hv_uvmem.c   | 219 ---
 2 files changed, 154 insertions(+), 67 deletions(-)

diff --git a/Documentation/powerpc/ultravisor.rst 
b/Documentation/powerpc/ultravisor.rst
index 363736d..3bc8957 100644
--- a/Documentation/powerpc/ultravisor.rst
+++ b/Documentation/powerpc/ultravisor.rst
@@ -933,6 +933,8 @@ Return values
* H_UNSUPPORTED if called from the wrong context (e.g.
from an SVM or before an H_SVM_INIT_START
hypercall).
+   * H_STATE   if the hypervisor could not successfully
+transition the VM to Secure VM.
 
 Description
 ~~~
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 2ef1e03..36dda1d 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -318,14 +318,149 @@ unsigned long kvmppc_h_svm_init_start(struct kvm *kvm)
return ret;
 }
 
+static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm);
+
+/*
+ * Alloc a PFN from private device memory pool. If @pagein is true,
+ * copy page from normal memory to secure memory using UV_PAGE_IN uvcall.
+ */
+static int kvmppc_svm_migrate_page(struct vm_area_struct *vma,
+   unsigned long start,
+   unsigned long end, unsigned long gpa, struct kvm *kvm,
+   unsigned long page_shift,
+   bool pagein)
+{
+   unsigned long src_pfn, dst_pfn = 0;
+   struct migrate_vma mig;
+   struct page *dpage;
+   struct page *spage;
+   unsigned long pfn;
+   int ret = 0;
+
+   memset(&mig, 0, sizeof(mig));
+   mig.vma = vma;
+   mig.start = start;
+   mig.end = end;
+   mig.src = &src_pfn;
+   mig.dst = &dst_pfn;
+
+   ret = migrate_vma_setup(&mig);
+   if (ret)
+   return ret;
+
+   if (!(*mig.src & MIGRATE_PFN_MIGRATE)) {
+   ret = -1;
+   goto out_finalize;
+   }
+
+   dpage = kvmppc_uvmem_get_page(gpa, kvm);
+   if (!dpage) {
+   ret = -1;
+   goto out_finalize;
+   }
+
+   if (pagein) {
+   pfn = *mig.src >> MIGRATE_PFN_SHIFT;
+   spage = migrate_pfn_to_page(*mig.src);
+   if (spage) {
+   ret = uv_page_in(kvm->arch.lpid, pfn << page_shift,
+   gpa, 0, page_shift);
+   if (ret)
+   goto out_finalize;
+   }
+   }
+
+   *mig.dst = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
+   migrate_vma_pages(&mig);
+out_finalize:
+   migrate_vma_finalize(&mig);
+   return ret;
+}
+
+static int uv_migrate_mem_slot(struct kvm *kvm,
+   const struct kvm_memory_slot *memslot)
+{
+   unsigned long gfn = memslot->base_gfn;
+   unsigned long end;
+   bool downgrade = false;
+   struct vm_area_struct *vma;
+   int i, ret = 0;
+   unsigned long start = gfn_to_hva(kvm, gfn);
+
+   if (kvm_is_error_hva(start))
+   return H_STATE;
+
+   end = start + (memslot->npages << PAGE_SHIFT);
+
+   down_write(&kvm->mm->mmap_sem);
+
+   mutex_lock(&kvm->arch.uvmem_lock);
+   vma = find_vma_intersection(kvm->mm, start, end);
+   if (!vma || vma->vm_start > start || vma->vm_end < end) {
+   ret = H_STATE;
+   goto out_unlock;
+   }
+
+   ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
+ MADV_UNMERGEABLE, &vma->vm_flags);
+   downgrade_write(&kvm->mm->mmap_sem);
+   downgrade = true;
+   if (ret) {
+   ret = H_STATE;
+   goto out_unlock;
+   }
+
+   for (i = 0; i < memslot->npages; i++, ++gfn) {
+   /* skip paged-in pages and shared pages */
+   if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL) ||
+   kvmppc_gfn_is_uvmem_shared(gfn, kvm))
+   continue;
+
+   start = gfn_to_hva(kvm, gfn);
+   end = start + (1UL << PAGE_SHIFT);
+ 

[PATCH v1 2/4] KVM: PPC: Book3S HV: track shared GFNs of secure VMs

2020-05-30 Thread Ram Pai
During the life of SVM, its GFNs can transition from secure to shared
state and vice-versa. Since the kernel does not track GFNs that are
shared, it is not possible to disambiguate a shared GFN from a GFN whose
PFN has not yet been migrated to a device-PFN.

The ability to identify a shared GFN is needed to skip migrating its PFN
to device PFN. This functionality is leveraged in a subsequent patch.

Add the ability to identify the state of a GFN.

Cc: Paul Mackerras 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Bharata B Rao 
Cc: Aneesh Kumar K.V 
Cc: Sukadev Bhattiprolu 
Cc: Laurent Dufour 
Cc: Thiago Jung Bauermann 
Cc: David Gibson 
Cc: Claudio Carvalho 
Cc: kvm-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Reviewed-by: Thiago Jung Bauermann 
Signed-off-by: Ram Pai 
---
 arch/powerpc/include/asm/kvm_book3s_uvmem.h |   6 +-
 arch/powerpc/kvm/book3s_64_mmu_radix.c  |   2 +-
 arch/powerpc/kvm/book3s_hv.c|   2 +-
 arch/powerpc/kvm/book3s_hv_uvmem.c  | 115 ++--
 4 files changed, 113 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s_uvmem.h 
b/arch/powerpc/include/asm/kvm_book3s_uvmem.h
index 5a9834e..f0c5708 100644
--- a/arch/powerpc/include/asm/kvm_book3s_uvmem.h
+++ b/arch/powerpc/include/asm/kvm_book3s_uvmem.h
@@ -21,7 +21,8 @@ unsigned long kvmppc_h_svm_page_out(struct kvm *kvm,
 int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn);
 unsigned long kvmppc_h_svm_init_abort(struct kvm *kvm);
 void kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
-struct kvm *kvm, bool skip_page_out);
+struct kvm *kvm, bool skip_page_out,
+bool purge_gfn);
 #else
 static inline int kvmppc_uvmem_init(void)
 {
@@ -75,6 +76,7 @@ static inline int kvmppc_send_page_to_uv(struct kvm *kvm, 
unsigned long gfn)
 
 static inline void
 kvmppc_uvmem_drop_pages(const struct kvm_memory_slot *free,
-   struct kvm *kvm, bool skip_page_out) { }
+   struct kvm *kvm, bool skip_page_out,
+   bool purge_gfn) { }
 #endif /* CONFIG_PPC_UV */
 #endif /* __ASM_KVM_BOOK3S_UVMEM_H__ */
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c 
b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index 803940d..3448459 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -1100,7 +1100,7 @@ void kvmppc_radix_flush_memslot(struct kvm *kvm,
unsigned int shift;
 
if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_START)
-   kvmppc_uvmem_drop_pages(memslot, kvm, true);
+   kvmppc_uvmem_drop_pages(memslot, kvm, true, false);
 
if (kvm->arch.secure_guest & KVMPPC_SECURE_INIT_DONE)
return;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 103d13e..4c62bfe 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -5467,7 +5467,7 @@ static int kvmhv_svm_off(struct kvm *kvm)
continue;
 
kvm_for_each_memslot(memslot, slots) {
-   kvmppc_uvmem_drop_pages(memslot, kvm, true);
+   kvmppc_uvmem_drop_pages(memslot, kvm, true, true);
uv_unregister_mem_slot(kvm->arch.lpid, memslot->id);
}
}
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index ea4a1f1..2ef1e03 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -99,14 +99,56 @@
 static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock);
 
 #define KVMPPC_UVMEM_PFN   (1UL << 63)
+#define KVMPPC_UVMEM_SHARED(1UL << 62)
+#define KVMPPC_UVMEM_FLAG_MASK (KVMPPC_UVMEM_PFN | KVMPPC_UVMEM_SHARED)
+#define KVMPPC_UVMEM_PFN_MASK  (~KVMPPC_UVMEM_FLAG_MASK)
 
 struct kvmppc_uvmem_slot {
struct list_head list;
unsigned long nr_pfns;
unsigned long base_pfn;
+   /*
+* pfns array has an entry for each GFN of the memory slot.
+*
+* The GFN can be in one of the following states.
+*
+* (a) Secure - The GFN is secure. Only Ultravisor can access it.
+* (b) Shared - The GFN is shared. Both Hypervisor and Ultravisor
+*  can access it.
+* (c) Normal - The GFN is a normal.  Only Hypervisor can access it.
+*
+* Secure GFN is associated with a devicePFN. Its pfn[] has
+* KVMPPC_UVMEM_PFN flag set, and has the value of the device PFN
+* KVMPPC_UVMEM_SHARED flag unset, and has the value of the device PFN
+*
+* Shared GFN is associated with a memoryPFN. Its pfn[] has
+* KVMPPC_UVMEM_SHARED flag set. But its KVMPPC_UVMEM_PFN is not set,
+* and there is no PFN value stored.
+*
+* Normal GFN is not associated with memoryPFN. Its pfn[] has
+* KVMPPC_UVMEM_SHARED and 

[PATCH v1 1/4] KVM: PPC: Book3S HV: Fix function definition in book3s_hv_uvmem.c

2020-05-30 Thread Ram Pai
Without this fix, GIT gets confused. It generates incorrect
function context for code changes.  Weird, but true.

Cc: Paul Mackerras 
Cc: Benjamin Herrenschmidt 
Cc: Michael Ellerman 
Cc: Bharata B Rao 
Cc: Aneesh Kumar K.V 
Cc: Sukadev Bhattiprolu 
Cc: Laurent Dufour 
Cc: Thiago Jung Bauermann 
Cc: David Gibson 
Cc: Claudio Carvalho 
Cc: kvm-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ram Pai 
---
 arch/powerpc/kvm/book3s_hv_uvmem.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 79b1202..ea4a1f1 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -368,8 +368,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
  * Alloc a PFN from private device memory pool and copy page from normal
  * memory to secure memory using UV_PAGE_IN uvcall.
  */
-static int
-kvmppc_svm_page_in(struct vm_area_struct *vma, unsigned long start,
+static int kvmppc_svm_page_in(struct vm_area_struct *vma, unsigned long start,
   unsigned long end, unsigned long gpa, struct kvm *kvm,
   unsigned long page_shift, bool *downgrade)
 {
@@ -436,8 +435,8 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
  * In the former case, uses dev_pagemap_ops.migrate_to_ram handler
  * to unmap the device page from QEMU's page tables.
  */
-static unsigned long
-kvmppc_share_page(struct kvm *kvm, unsigned long gpa, unsigned long page_shift)
+static unsigned long kvmppc_share_page(struct kvm *kvm, unsigned long gpa,
+   unsigned long page_shift)
 {
 
int ret = H_PARAMETER;
@@ -486,9 +485,9 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
  * H_PAGE_IN_SHARED flag makes the page shared which means that the same
  * memory in is visible from both UV and HV.
  */
-unsigned long
-kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gpa,
-unsigned long flags, unsigned long page_shift)
+unsigned long kvmppc_h_svm_page_in(struct kvm *kvm, unsigned long gpa,
+   unsigned long flags,
+   unsigned long page_shift)
 {
bool downgrade = false;
unsigned long start, end;
@@ -545,10 +544,10 @@ static struct page *kvmppc_uvmem_get_page(unsigned long 
gpa, struct kvm *kvm)
  * Provision a new page on HV side and copy over the contents
  * from secure memory using UV_PAGE_OUT uvcall.
  */
-static int
-kvmppc_svm_page_out(struct vm_area_struct *vma, unsigned long start,
-   unsigned long end, unsigned long page_shift,
-   struct kvm *kvm, unsigned long gpa)
+static int kvmppc_svm_page_out(struct vm_area_struct *vma,
+   unsigned long start,
+   unsigned long end, unsigned long page_shift,
+   struct kvm *kvm, unsigned long gpa)
 {
unsigned long src_pfn, dst_pfn = 0;
struct migrate_vma mig;
-- 
1.8.3.1



[PATCH v1 0/4] Migrate non-migrated pages of a SVM.

2020-05-30 Thread Ram Pai
This patch series migrates the non-migrate pages of a SVM.
This is required when the UV calls H_SVM_INIT_DONE, and
when a memory-slot is hotplugged to a Secure VM.

Laurent Dufour (1):
  KVM: PPC: Book3S HV: migrate hot plugged memory

Ram Pai (3):
  KVM: PPC: Book3S HV: Fix function definition in book3s_hv_uvmem.c
  KVM: PPC: Book3S HV: track shared GFNs of secure VMs
  KVM: PPC: Book3S HV: migrate remaining normal-GFNs to secure-GFNs in
H_SVM_INIT_DONE

 Documentation/powerpc/ultravisor.rst|   2 +
 arch/powerpc/include/asm/kvm_book3s_uvmem.h |  10 +-
 arch/powerpc/kvm/book3s_64_mmu_radix.c  |   2 +-
 arch/powerpc/kvm/book3s_hv.c|  13 +-
 arch/powerpc/kvm/book3s_hv_uvmem.c  | 348 +---
 5 files changed, 284 insertions(+), 91 deletions(-)

-- 
1.8.3.1



Re: ppc64le and 32-bit LE userland compatibility

2020-05-30 Thread Will Springer
On Saturday, May 30, 2020 12:22:12 PM PDT Segher Boessenkool wrote:
> The original sysv PowerPC supplement
> http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
> supports LE as well, and most powerpcle ports use that.  But, the
> big-endian Linux ABI differs in quite a few places, and it of course
> makes a lot better sense if powerpcle-linux follows that.

Right, I should have clarified I was talking about Linux ABIs 
specifically.

> What patches did you need?  I regularly build >30 cross compilers (on
> both BE and LE hosts; I haven't used 32-bit hosts for a long time, but
> in the past those worked fine as well).  I also cross-built
> powerpcle-linux-gcc quite a few times (from powerpc64le, from powerpc64,
> from various x86).

There was just an assumption that LE == powerpc64le in libgo, spotted by 
q66 (daniel@ on the CC). I just pushed the patch to [1].

> Almost no project that used 32-bit PowerPC in LE mode has sent patches
> to the upstreams.

Right, but I have heard concerns from at least one person familiar with 
the ppc kernel about breaking existing users of this arch-endianness 
combo, if any. It seems likely that none of those use upstream, though ^^;

> The ABI says long longs are passed in the same order in registers as it
> would be in memory; so the high part and the low part are swapped
> between BE and LE.  Which registers make up a pair is exactly the same
> between the two.  (You can verify this with an existing powerpcle-*
> compiler, too; I did, and we implement it correctly as far as I can
> see).

I'll give it a closer look. This is my first time poking at this sort of 
thing in depth, so excuse my unfamiliarity!

> A huge factor in having good GCC support for powerpcle-linux (or
> anything else) is someone needs to regularly test it, and share test
> results with us (via gcc-testresults@).  Hint hint hint :-)
> 
> That way we know it is in good shape, know when we are regressing it,
> know there is interest in it.

Once I have more of a bootstrapped userland than a barely-functional 
cross chroot, I'll get back to you on that :)
 
> gl;hf,
> 
> 
> Segher

Thanks,
Will [she/her]

[1]: 
https://github.com/Skirmisher/void-packages/blob/master/srcpkgs/gcc/patches/libgo-ppcle.patch






Re: ppc64le and 32-bit LE userland compatibility

2020-05-30 Thread Will Springer
On Saturday, May 30, 2020 8:37:43 AM PDT Christophe Leroy wrote:
> There is a series at
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=173231 to
> switch powerpc to the Generic C VDSO.
> 
> Can you try and see whether it fixes your issue ?
> 
> Christophe

Sure thing, I spotted that after making the initial post. Will report back 
with results.

Will [she/her]






Re: [GIT PULL] Please pull powerpc/linux.git powerpc-5.7-6 tag

2020-05-30 Thread pr-tracker-bot
The pull request you sent on Sun, 31 May 2020 00:05:02 +1000:

> https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
> tags/powerpc-5.7-6

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/ffeb595d84811dde16a28b33d8a7cf26d51d51b3

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker


Re: ppc64le and 32-bit LE userland compatibility

2020-05-30 Thread Segher Boessenkool
Hi!

On Fri, May 29, 2020 at 07:03:48PM +, Will Springer wrote:
> Hey all, a couple of us over in #talos-workstation on freenode have been
> working on an effort to bring up a Linux PowerPC userland that runs in 32-bit
> little-endian mode, aka ppcle. As far as we can tell, no ABI has ever been
> designated for this

https://www.polyomino.org.uk/publications/2011/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf

> (unless you count the patchset from a decade ago [1]), so

The original sysv PowerPC supplement
http://refspecs.linux-foundation.org/elf/elfspec_ppc.pdf
supports LE as well, and most powerpcle ports use that.  But, the
big-endian Linux ABI differs in quite a few places, and it of course
makes a lot better sense if powerpcle-linux follows that.

> it's pretty much uncharted territory as far as Linux is concerned. We want to
> sync up with libc and the relevant kernel folks to establish the best path
> forward.
> 
> The practical application that drove these early developments (as you might
> expect) is x86 emulation. The box86 project [2] implements a translation layer
> for ia32 library calls to native architecture ones; this way, emulation
> overhead is significantly reduced by relying on native libraries where
> possible (libc, libGL, etc.) instead of emulating an entire x86 userspace.
> box86 is primarily targeted at ARM, but it can be adapted to other
> architectures—so long as they match ia32's 32-bit, little-endian nature. Hence
> the need for a ppcle userland; modern POWER brought ppc64le as a supported
> configuration, but without a 32-bit equivalent there is no option for a 32/64
> multilib environment, as seen with ppc/ppc64 and arm/aarch64.
> 
> Surprisingly, beyond minor patching of gcc to get crosscompile going,

What patches did you need?  I regularly build >30 cross compilers (on
both BE and LE hosts; I haven't used 32-bit hosts for a long time, but
in the past those worked fine as well).  I also cross-built
powerpcle-linux-gcc quite a few times (from powerpc64le, from powerpc64,
from various x86).

> bootstrapping the initial userland was not much of a problem. The work has
> been done on top of the Void Linux PowerPC project [3], and much of that is
> now present in its source package tree [4].
> 
> The first issue with running the userland came from the ppc32 signal handler 
> forcing BE in the MSR, causing any 32LE process receiving a signal (such as a 
> shell receiving SIGCHLD) to terminate with SIGILL. This was trivially 
> patched, 

Heh :-)

> along with enabling the 32-bit vDSO on ppc64le kernels [5]. (Given that this 
> behavior has been in place since 2006, I don't think anyone has been using 
> the 
> kernel in this state to run ppcle userlands.)

Almost no project that used 32-bit PowerPC in LE mode has sent patches
to the upstreams.

> The next problem concerns the ABI more directly. The failure mode was `file`
> surfacing EINVAL from pread64 when invoked on an ELF; pread64 was passed a
> garbage value for `pos`, which didn't appear to be caused by anything in 
> `file`. Initially it seemed as though the 32-bit components of the arg were
> getting swapped, and we made hacky fixes to glibc and musl to put them in the
> "right order"; however, we weren't sure if that was the correct approach, or
> if there were knock-on effects we didn't know about. So we found the relevant
> compat code path in the kernel, at arch/powerpc/kernel/sys_ppc32.c, where
> there exists this comment:
> 
> > /*
> >  * long long munging:
> >  * The 32 bit ABI passes long longs in an odd even register pair.
> >  */
> 
> It seems that the opposite is true in LE mode, and something is expecting long
> longs to start on an even register. I realized this after I tried swapping hi/
> lo `u32`s here and didn't see an improvement. I whipped up a patch [6] that
> switches which syscalls use padding arguments depending on endianness, while
> hopefully remaining tidy enough to be unobtrusive. (I took some liberties with
> variable names/types so that the macro could be consistent.)

The ABI says long longs are passed in the same order in registers as it
would be in memory; so the high part and the low part are swapped between
BE and LE.  Which registers make up a pair is exactly the same between
the two.  (You can verify this with an existing powerpcle-* compiler, too;
I did, and we implement it correctly as far as I can see).

> This was enough to fix up the `file` bug. I'm no seasoned kernel hacker,
> though, and there is still concern over the right way to approach this,
> whether it should live in the kernel or libc, etc. Frankly, I don't know the
> ABI structure enough to understand why the register padding has to be
> different in this case, or what lower-level component is responsible for it. 
> For comparison, I had a look at the mips tree, since it's bi-endian and has a 
> similar 32/64 situation. There is a macro conditional upon endianness that is 
> responsible for munging long longs; it uses _

Re: [PATCH] powerpc/32: disable KASAN with pages bigger than 16k

2020-05-30 Thread Christophe Leroy




Le 28/05/2020 à 12:17, Christophe Leroy a écrit :

Mapping of early shadow area is implemented by using a single static
page table having all entries pointing to the same early shadow page.
The shadow area must therefore occupy full PGD entries.

The shadow area has a size of 128Mbytes starting at 0xf800.
With 4k pages, a PGD entry is 4Mbytes
With 16k pages, a PGD entry is 64Mbytes
With 64k pages, a PGD entry is 256Mbytes which is too big.


That's for 32k pages that a PGD is 256Mbytes.

With 64k pages, a PGD entry is 1Gbytes which is too big.

Michael, can you fix the commit log ?

Thanks
Christophe



Until we rework the early shadow mapping, disable KASAN when the
page size is too big.

Reported-by: kbuild test robot 
Fixes: 2edb16efc899 ("powerpc/32: Add KASAN support")
Cc: sta...@vger.kernel.org
Signed-off-by: Christophe Leroy 
---
  arch/powerpc/Kconfig | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1dfa59126fcf..066b36bf9efa 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -169,8 +169,8 @@ config PPC
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMAP  if PPC_BOOK3S_64 && 
PPC_RADIX_MMU
select HAVE_ARCH_JUMP_LABEL
-   select HAVE_ARCH_KASAN  if PPC32
-   select HAVE_ARCH_KASAN_VMALLOC  if PPC32
+   select HAVE_ARCH_KASAN  if PPC32 && PPC_PAGE_SHIFT <= 14
+   select HAVE_ARCH_KASAN_VMALLOC  if PPC32 && PPC_PAGE_SHIFT <= 14
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT



[PATCH v2] powerpc/32s: Fix another build failure with CONFIG_PPC_KUAP_DEBUG

2020-05-30 Thread Christophe Leroy
'thread' doesn't exist in kuap_check() macro.

Use 'current' instead.

Reported-by: kbuild test robot 
Fixes: a68c31fc01ef ("powerpc/32s: Implement Kernel Userspace Access 
Protection")
Cc: sta...@vger.kernel.org
Signed-off-by: Christophe Leroy 
---
v2: Changed author and signed-off-by ... and added asm/bug.h

There are days when you'd better go sleeping instead of wanting to send the fix.
And there are days you stare at your code, think it is good, prepare the patch,
test it, find another bug, fix it, test it ... and send the first patch you 
prepared :(
hence this second fix for the same bug.
---
 arch/powerpc/include/asm/book3s/32/kup.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/book3s/32/kup.h 
b/arch/powerpc/include/asm/book3s/32/kup.h
index db0a1c281587..a41cfc7cc669 100644
--- a/arch/powerpc/include/asm/book3s/32/kup.h
+++ b/arch/powerpc/include/asm/book3s/32/kup.h
@@ -2,6 +2,7 @@
 #ifndef _ASM_POWERPC_BOOK3S_32_KUP_H
 #define _ASM_POWERPC_BOOK3S_32_KUP_H
 
+#include 
 #include 
 
 #ifdef __ASSEMBLY__
@@ -75,7 +76,7 @@
 
 .macro kuap_check  current, gpr
 #ifdef CONFIG_PPC_KUAP_DEBUG
-   lwz \gpr, KUAP(thread)
+   lwz \gpr, THREAD + KUAP(\current)
 999:   twnei   \gpr, 0
EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | 
BUGFLAG_ONCE)
 #endif
-- 
2.25.0



Re: [RFC PATCH 1/2] libnvdimm: Add prctl control for disabling synchronous fault support.

2020-05-30 Thread Dan Williams
On Sat, May 30, 2020 at 12:18 AM Aneesh Kumar K.V
 wrote:
>
> On 5/30/20 12:52 AM, Dan Williams wrote:
> > On Fri, May 29, 2020 at 3:55 AM Aneesh Kumar K.V
> >  wrote:
> >>
> >> On 5/29/20 3:22 PM, Jan Kara wrote:
> >>> Hi!
> >>>
> >>> On Fri 29-05-20 15:07:31, Aneesh Kumar K.V wrote:
>  Thanks Michal. I also missed Jeff in this email thread.
> >>>
> >>> And I think you'll also need some of the sched maintainers for the prctl
> >>> bits...
> >>>
>  On 5/29/20 3:03 PM, Michal Suchánek wrote:
> > Adding Jan
> >
> > On Fri, May 29, 2020 at 11:11:39AM +0530, Aneesh Kumar K.V wrote:
> >> With POWER10, architecture is adding new pmem flush and sync 
> >> instructions.
> >> The kernel should prevent the usage of MAP_SYNC if applications are 
> >> not using
> >> the new instructions on newer hardware.
> >>
> >> This patch adds a prctl option MAP_SYNC_ENABLE that can be used to 
> >> enable
> >> the usage of MAP_SYNC. The kernel config option is added to allow the 
> >> user
> >> to control whether MAP_SYNC should be enabled by default or not.
> >>
> >> Signed-off-by: Aneesh Kumar K.V 
> >>> ...
> >> diff --git a/kernel/fork.c b/kernel/fork.c
> >> index 8c700f881d92..d5a9a363e81e 100644
> >> --- a/kernel/fork.c
> >> +++ b/kernel/fork.c
> >> @@ -963,6 +963,12 @@ __cacheline_aligned_in_smp 
> >> DEFINE_SPINLOCK(mmlist_lock);
> >> static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;
> >> +#ifdef CONFIG_ARCH_MAP_SYNC_DISABLE
> >> +unsigned long default_map_sync_mask = MMF_DISABLE_MAP_SYNC_MASK;
> >> +#else
> >> +unsigned long default_map_sync_mask = 0;
> >> +#endif
> >> +
> >>>
> >>> I'm not sure CONFIG is really the right approach here. For a distro that 
> >>> would
> >>> basically mean to disable MAP_SYNC for all PPC kernels unless application
> >>> explicitly uses the right prctl. Shouldn't we rather initialize
> >>> default_map_sync_mask on boot based on whether the CPU we run on requires
> >>> new flush instructions or not? Otherwise the patch looks sensible.
> >>>
> >>
> >> yes that is correct. We ideally want to deny MAP_SYNC only w.r.t
> >> POWER10. But on a virtualized platform there is no easy way to detect
> >> that. We could ideally hook this into the nvdimm driver where we look at
> >> the new compat string ibm,persistent-memory-v2 and then disable MAP_SYNC
> >> if we find a device with the specific value.
> >>
> >> BTW with the recent changes I posted for the nvdimm driver, older kernel
> >> won't initialize persistent memory device on newer hardware. Newer
> >> hardware will present the device to OS with a different device tree
> >> compat string.
> >>
> >> My expectation  w.r.t this patch was, Distro would want to  mark
> >> CONFIG_ARCH_MAP_SYNC_DISABLE=n based on the different application
> >> certification.  Otherwise application will have to end up calling the
> >> prctl(MMF_DISABLE_MAP_SYNC, 0) any way. If that is the case, should this
> >> be dependent on P10?
> >>
> >> With that I am wondering should we even have this patch? Can we expect
> >> userspace get updated to use new instruction?.
> >>
> >> With ppc64 we never had a real persistent memory device available for
> >> end user to try. The available persistent memory stack was using vPMEM
> >> which was presented as a volatile memory region for which there is no
> >> need to use any of the flush instructions. We could safely assume that
> >> as we get applications certified/verified for working with pmem device
> >> on ppc64, they would all be using the new instructions?
> >
> > I think prctl is the wrong interface for this. I was thinking a sysfs
> > interface along the same lines as /sys/block/pmemX/dax/write_cache.
> > That attribute is toggling DAXDEV_WRITE_CACHE for the determination of
> > whether the platform or the kernel needs to handle cache flushing
> > relative to power loss. A similar attribute can be established for
> > DAXDEV_SYNC, it would simply default to off based on a configuration
> > time policy, but be dynamically changeable at runtime via sysfs.
> >
> > These flags are device properties that affect the kernel and
> > userspace's handling of persistence.
> >
>
> That will not handle the scenario with multiple applications using the
> same fsdax mount point where one is updated to use the new instruction
> and the other is not.

Right, it needs to be a global setting / flag day to switch from one
regime to another. Per-process control is a recipe for disaster.


Re: ppc64le and 32-bit LE userland compatibility

2020-05-30 Thread Christophe Leroy




Le 29/05/2020 à 21:03, Will Springer a écrit :

[...]



Also worth noting is the one other outstanding bug, where the time-related
syscalls in the 32-bit vDSO seem to return garbage. It doesn't look like an
endian bug to me, and it doesn't affect standard syscalls (which is why if you
run `date` on musl it prints the correct time, unlike on glibc). The vDSO time
functions are implemented in ppc asm (arch/powerpc/kernel/vdso32/
gettimeofday.S), and I've never touched the stuff, so if anyone has a clue I'm
all ears.



There is a series at 
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=173231 to 
switch powerpc to the Generic C VDSO.


Can you try and see whether it fixes your issue ?

Christophe


[GIT PULL] Please pull powerpc/linux.git powerpc-5.7-6 tag

2020-05-30 Thread Michael Ellerman
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

Hi Linus,

Please pull two more powerpc fixes for 5.7. These are both regressions with
small "obviously correct" fixes.

cheers

The following changes since commit 8659a0e0efdd975c73355dbc033f79ba3b31e82c:

  powerpc/64s: Disable STRICT_KERNEL_RWX (2020-05-22 00:04:51 +1000)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
tags/powerpc-5.7-6

for you to fetch changes up to 2f26ed1764b42a8c40d9c48441c73a70d805decf:

  powerpc/64s: Disable sanitisers for C syscall/interrupt entry/exit code 
(2020-05-29 21:12:09 +1000)

- --
powerpc fixes for 5.7 #6

A fix for the recent change to how we restore non-volatile GPRs, which broke our
emulation of reading from the DSCR (Data Stream Control Register).

And a fix for the recent rewrite of interrupt/syscall exit in C, we need to
exclude KCOV from that code, otherwise it can lead to unrecoverable faults.

Thanks to:
  Daniel Axtens.

- --
Daniel Axtens (1):
  powerpc/64s: Disable sanitisers for C syscall/interrupt entry/exit code

Michael Ellerman (1):
  powerpc/64s: Fix restore of NV GPRs after facility unavailable exception


 arch/powerpc/kernel/Makefile | 3 +++
 arch/powerpc/kernel/exceptions-64s.S | 2 ++
 2 files changed, 5 insertions(+)
-BEGIN PGP SIGNATURE-

iQIzBAEBCAAdFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAl7SZ9oACgkQUevqPMjh
pYCF0g//cJYxcH020cVm2jZL5Smcfqr3mYRcGnY/IsEJ28y7HFc30HnoxiBtwO2Z
BwZqqW80IQpDieHS9GZ//IbGaHrrrj5HeyGfA5F6IsKrZXsb9EG++njaKqGZljX5
NStMVMJ+zFs8b+ZVPtA5yQVy4EQO5QlB3A19BIsI7VnqNI/h6R9wXHaAguVz2DUL
AydK/cdU0LdOXnPewY3S3P4HVaUkBE/UrqpekBePJ89obOvUVsbP1C+syDYQLgzA
y43zFPZurVb5UOpEXs9hKoqLnciM5LBKCbk6JV001Hvalb8Bobo/4vvrmxC/BSUs
B0kI6ZHvojTj/cQ7c26B0uEab6AZYdP7TzAIjpP2xoLHvLaWlbGlrOzSz5xNp5B5
lkT8WZCcU8/kQx2hsjOcOOQV6JIMkTDeB7lTm3iwcVQihJDemNu0XxZIAi8gbOzr
46BXNFKVv9ItjzxSIbUtcxl5mpiwnV0XoDw4IM7xDdKnpLG8z9yzrYuBPyQ2gEDB
KhnvTJQry9B4I98EoKoXvMGMttL9BmrYWJ/7P89hTWZT4fs6dOox9Pf+UOHBp3Tk
I/qxG9zzWlf5zXJKUKyTqLv4SIbQNCx7IAqkPkaR9AGCoLCNyapNfZ5orfh6TFHc
n4J9suaFG9TFF7frIMGZNcIt8MBjPlXcJhQQ+s2KCOD4NZE+534=
=KF+h
-END PGP SIGNATURE-


Re: [RFC PATCH 1/2] libnvdimm: Add prctl control for disabling synchronous fault support.

2020-05-30 Thread Aneesh Kumar K.V

On 5/30/20 12:52 AM, Dan Williams wrote:

On Fri, May 29, 2020 at 3:55 AM Aneesh Kumar K.V
 wrote:


On 5/29/20 3:22 PM, Jan Kara wrote:

Hi!

On Fri 29-05-20 15:07:31, Aneesh Kumar K.V wrote:

Thanks Michal. I also missed Jeff in this email thread.


And I think you'll also need some of the sched maintainers for the prctl
bits...


On 5/29/20 3:03 PM, Michal Suchánek wrote:

Adding Jan

On Fri, May 29, 2020 at 11:11:39AM +0530, Aneesh Kumar K.V wrote:

With POWER10, architecture is adding new pmem flush and sync instructions.
The kernel should prevent the usage of MAP_SYNC if applications are not using
the new instructions on newer hardware.

This patch adds a prctl option MAP_SYNC_ENABLE that can be used to enable
the usage of MAP_SYNC. The kernel config option is added to allow the user
to control whether MAP_SYNC should be enabled by default or not.

Signed-off-by: Aneesh Kumar K.V 

...

diff --git a/kernel/fork.c b/kernel/fork.c
index 8c700f881d92..d5a9a363e81e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -963,6 +963,12 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;
+#ifdef CONFIG_ARCH_MAP_SYNC_DISABLE
+unsigned long default_map_sync_mask = MMF_DISABLE_MAP_SYNC_MASK;
+#else
+unsigned long default_map_sync_mask = 0;
+#endif
+


I'm not sure CONFIG is really the right approach here. For a distro that would
basically mean to disable MAP_SYNC for all PPC kernels unless application
explicitly uses the right prctl. Shouldn't we rather initialize
default_map_sync_mask on boot based on whether the CPU we run on requires
new flush instructions or not? Otherwise the patch looks sensible.



yes that is correct. We ideally want to deny MAP_SYNC only w.r.t
POWER10. But on a virtualized platform there is no easy way to detect
that. We could ideally hook this into the nvdimm driver where we look at
the new compat string ibm,persistent-memory-v2 and then disable MAP_SYNC
if we find a device with the specific value.

BTW with the recent changes I posted for the nvdimm driver, older kernel
won't initialize persistent memory device on newer hardware. Newer
hardware will present the device to OS with a different device tree
compat string.

My expectation  w.r.t this patch was, Distro would want to  mark
CONFIG_ARCH_MAP_SYNC_DISABLE=n based on the different application
certification.  Otherwise application will have to end up calling the
prctl(MMF_DISABLE_MAP_SYNC, 0) any way. If that is the case, should this
be dependent on P10?

With that I am wondering should we even have this patch? Can we expect
userspace get updated to use new instruction?.

With ppc64 we never had a real persistent memory device available for
end user to try. The available persistent memory stack was using vPMEM
which was presented as a volatile memory region for which there is no
need to use any of the flush instructions. We could safely assume that
as we get applications certified/verified for working with pmem device
on ppc64, they would all be using the new instructions?


I think prctl is the wrong interface for this. I was thinking a sysfs
interface along the same lines as /sys/block/pmemX/dax/write_cache.
That attribute is toggling DAXDEV_WRITE_CACHE for the determination of
whether the platform or the kernel needs to handle cache flushing
relative to power loss. A similar attribute can be established for
DAXDEV_SYNC, it would simply default to off based on a configuration
time policy, but be dynamically changeable at runtime via sysfs.

These flags are device properties that affect the kernel and
userspace's handling of persistence.



That will not handle the scenario with multiple applications using the 
same fsdax mount point where one is updated to use the new instruction 
and the other is not.


-aneeseh