[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [XEN v5] xen/arm64: io: Decode ldr/str post-indexing instructions


  • To: Julien Grall <julien@xxxxxxx>, Ayan Kumar Halder <ayan.kumar.halder@xxxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxxxxx>
  • Date: Wed, 2 Feb 2022 13:05:22 +0000
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 149.199.80.198) smtp.rcpttodomain=xen.org smtp.mailfrom=xilinx.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=xilinx.com; dkim=none (message not signed); arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=BM/Hm2dDrulzU4PiPd7pKZq0LqWuFnahVAuLDnzu5zo=; b=m02K6GCwWV/hLN8lcCI+V28BxNHQi2Cpo9HnDup9dkKZ3aOBGFsCi0aU3T+TmzzYwSQYy91qG4NPk//3TTWH684Gkg9ktyQMwaZJpoDjsOqCE7/WFfGu9h7MqL20bcb2gcuL27Mydfw4Ty4m+JgaAmFUDZ7kO/KR750DTfiTHFct6201ruL/r7sS7bxAQ+Dh2jM4aWAeUDqYSyK6NUeTtszHdB2nhMtSD4+OtSyNDG8v1crZ1KRnXjYQhnwgAunF3NgiYSkvmMCdSxkaPQ1wL2pa6ekbU9noG5a7VNFwNcQ29Pi+XLgUj8WkIuBFnCH7ljlNix42tFHU6hwrKxn0Dg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XfcZYzjJFawgkCu+j7KmfxzyIsK1me+DjJT91PW8HvmjDDCD+JWVvMR/It1/7DFBDbBwe+x9ZCQy00N2tIl0gAi49soiJGqaJzfJ1H1fbgPhGZvXL3lbZu+7Hwgqg0GhiCRoD/+2j6vE3FVpqYC4dFMm3+3sCIEeVYj4nAoT0JBIH0jWiWF/c+H2v2W7qdWc2ZzLiKHOoIiPt646KrSf32buezCbO01WkiowZShuZN6WsKLfomziWd8Zx050rnBw4ikRpzw2li1BdyoctvMEdthSTxukGEZUSyjFgPFbivnCM7MF0fyPX17MG/JMe2zQv86L2pABWa/IgPDdjPKfng==
  • Cc: <sstabellini@xxxxxxxxxx>, <stefanos@xxxxxxxxxx>, <Volodymyr_Babchuk@xxxxxxxx>, <bertrand.marquis@xxxxxxx>
  • Delivery-date: Wed, 02 Feb 2022 13:05:37 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Julien,

I have a question.

On 31/01/2022 19:37, Ayan Kumar Halder wrote:
diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c
index 308650b400..f19fb46f72 100644
--- a/xen/arch/arm/ioreq.c
+++ b/xen/arch/arm/ioreq.c
@@ -23,16 +23,35 @@
    #include <public/hvm/ioreq.h>
  +#include "decode.h"
+
  enum io_state handle_ioserv(struct cpu_user_regs *regs, struct vcpu *v)
  {
      const union hsr hsr = { .bits = regs->hsr };
-    const struct hsr_dabt dabt = hsr.dabt;
+    struct hsr_dabt dabt = hsr.dabt;
+
      /* Code is similar to handle_read */
      register_t r = v->io.req.data;
        /* We are done with the IO */
      v->io.req.state = STATE_IOREQ_NONE;
  +    /*
+     * Note that we have already decoded the instruction in try_fwd_ioserv(). +     * We decode the instruction again to obtain rn and imm9. This will be used
+     * to do the post increment.
+     * Also there is no need to check whether the instruction can be decoded or +     * was successfully decoded. The reason being if there was an error, then +     * try_fwd_ioserv() would have returned error and this function would not +     * have been called. Thus, there is an assumption that handle_iosev() is
+     * invoked when try_fwd_ioserv() has returned successfully.

I am afraid this is not a correct assumption. Another vCPU can modify the instruction between the two decoding. So the right solution is to stash the information for latter consumption.

+     */
+    if ( !dabt.valid )
+    {
+        decode_instruction(regs, &dabt);
+        post_increment_register(&dabt.dabt_instr);
+    }
+
      if ( dabt.write )
          return IO_HANDLED;
  @@ -65,6 +84,8 @@ enum io_state try_fwd_ioserv(struct cpu_user_regs *regs,
      };
      struct ioreq_server *s = NULL;
      enum io_state rc;
+    bool instr_decoded = false;
+    const union hsr hsr = { .bits = regs->hsr };
        if ( vio->req.state != STATE_IOREQ_NONE )
      {
@@ -76,8 +97,18 @@ enum io_state try_fwd_ioserv(struct cpu_user_regs *regs,
      if ( !s )
          return IO_UNHANDLED;
  +    /*
+     * Armv8 processor does not provide a valid syndrome for decoding some +     * instructions (for eg post-indexing ldr/str instructions). So in order to
+     * process these instructions, Xen must decode them.
+     */
      if ( !info->dabt.valid )
-        return IO_ABORT;
+    {
+        rc = try_decode_instruction_invalid_iss(regs, &info->dabt);
+
+        if ( rc != IO_HANDLED)
+            return rc;
+    }

As you pointed out previously, the field SAS (Syndrome Access Size) is invalid when the ISV=0. So the decoding needs to be done *before* we select the IOREQ server.

But as I said, this would result to decode the instruciton when this is not necessary. This is where Stefano's suggestion in [1] is useful.

For ISV=0, it will be a lot more common to trap because of a P2M translation fault (of the MMIO is not mapped). So we should call that first and then, if it still not resolved, try to decode the instruction.

With that in place, you are avoiding the issue in try_fwd_ioserv().

Can you please coordinate with Stefano?

I am a bit confused regarding where we need to handle to post increment of Rn in case of ioreq.

I can see the following two places where PC gets incremented :-

1. handle_ioserv() returns IO_HANDLED via try_handle_mmio(). And then in "case IO_HANDLED:", PC is incremented.

2. leave_hypervisor_to_guest() ---> check_for_vcpu_work() --> vcpu_ioreq_handle_completion() --> arch_ioreq_complete_mmio(). Here PC is incremented as well.

So, do I need to update Rn in both the above places.

And if I understood your previous comment "Another vCPU can modify the instruction between the two decoding....", you are suggesting to save the instruction opcode (from PC) before invoking try_fwd_ioserv(). So, that it can be decoded again in arch_ioreq_complete_mmio() without reading PC.

- Ayan


[1] alpine.DEB.2.22.394.2201271327430.27308@ubuntu-linux-20-04-desktop




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.