)]}'
{
  "commit": "b5f56910fda194eca94033bd72e833fea119d26e",
  "tree": "f040b8efa446cdd7440d91b70df9c32d537f4360",
  "parents": [
    "807daf9f5bc4b15f191279136cc5c97bd39135b5"
  ],
  "author": {
    "name": "Ghanan Gowripalan",
    "email": "ghanan@fuchsia.infra.roller.google.com",
    "time": "Mon Nov 06 19:05:47 2023 +0000"
  },
  "committer": {
    "name": "Copybara-Service",
    "email": "copybara-worker@google.com",
    "time": "Mon Nov 06 11:07:14 2023 -0800"
  },
  "message": "[roll] Roll fuchsia [starnix/usercopy] Avoid reads from multiple pages\n\n...in individual instructions.\n\nThe `hermetic_copy` function is written as a simple byte copy looping\nover the source/destination buffers. However, the compiler assumes\nthat the full buffers (with the caller specified size) is valid for\ncopying and no faults would normally occur (as is the normal user-mode\ncopying expectations). `hermetic_copy`\u0027s use-case is different - it may\ntrigger faults and we need to allow read/writes up until the faulting\naddress.\n\nOn x86_64, the compiler attempts to optimize for the regular user-mode\ncopying case where faults don\u0027t occur. By doing this, it ends up using\ninstructions like `MOVUPS` with `XMM` registers which ends up performing\n_unaligned_ moving of 64 byte values.\n\nIf the user requested a read at 1 byte before the end of a valid mapping\nbut provided a large buffer to read into, the `hermetic_copy` method may\nattempt to perform the read with instructions that read bytes across\nmultiple pages. When this happens, the whole read fails and no bytes are\nwritten to the destination buffer. Howevever, the fault handler will\nstill process the fault and `Usercopy` will return the number of bytes\nbetween the start address and the faulting address even though none of\nthose bytes were copied.\n\nBy adding the `volatile` qualifier to the buffers, we let the compiler\nknow that each byte access may have visible side-effects and that it\nshouldn\u0027t attempt to perform any optimizations to effectively batch\nthe reads/writes of memory since a fault within the batch will fail\nthe whole operation which prevents the read/write of bytes before\nthe faulting address.\n\nBelow is the disassembly for `hemetic_copy` in release builds without\nthis change:\n```\nghanan@ghanan-glinux:~/Projects/fuchsia/out/workbench_eng.qemu-x64$ objdump -b binary -m i386:x86-64 -D ./user.basic_x64/obj/src/starnix/lib/usercopy/hermetic_copy.bin\n\n./user.basic_x64/obj/src/starnix/lib/usercopy/hermetic_copy.bin:     file format binary\n\nDisassembly of section .data:\n\n0000000000000000 \u003c.data\u003e:\n   0:   55                      push   %rbp\n   1:   48 89 e5                mov    %rsp,%rbp\n   4:   48 85 d2                test   %rdx,%rdx\n   7:   0f 84 ee 00 00 00       je     0xfb\n   d:   31 c0                   xor    %eax,%eax\n   f:   48 83 fa 08             cmp    $0x8,%rdx\n  13:   0f 82 7d 00 00 00       jb     0x96\n  19:   48 89 f9                mov    %rdi,%rcx\n  1c:   48 29 f1                sub    %rsi,%rcx\n  1f:   90                      nop\n  20:   48 83 f9 20             cmp    $0x20,%rcx\n  24:   72 70                   jb     0x96\n  26:   48 83 fa 20             cmp    $0x20,%rdx\n  2a:   73 04                   jae    0x30\n  2c:   31 c0                   xor    %eax,%eax\n  2e:   eb 3e                   jmp    0x6e\n  30:   48 89 d0                mov    %rdx,%rax\n  33:   48 83 e0 e0             and    $0xffffffffffffffe0,%rax\n  37:   31 c9                   xor    %ecx,%ecx\n  39:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)\n  40:   0f 10 04 0e             movups (%rsi,%rcx,1),%xmm0\n  44:   0f 10 4c 0e 10          movups 0x10(%rsi,%rcx,1),%xmm1\n  49:   0f 11 04 0f             movups %xmm0,(%rdi,%rcx,1)\n  4d:   0f 11 4c 0f 10          movups %xmm1,0x10(%rdi,%rcx,1)\n  52:   48 83 c1 20             add    $0x20,%rcx\n  56:   48 39 c8                cmp    %rcx,%rax\n  59:   75 e5                   jne    0x40\n  5b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)\n  60:   48 39 d0                cmp    %rdx,%rax\n  63:   0f 84 92 00 00 00       je     0xfb\n  69:   f6 c2 18                test   $0x18,%dl\n  6c:   74 28                   je     0x96\n  6e:   48 89 c1                mov    %rax,%rcx\n  71:   48 89 d0                mov    %rdx,%rax\n  74:   48 83 e0 f8             and    $0xfffffffffffffff8,%rax\n  78:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)\n  7f:   00\n  80:   4c 8b 04 0e             mov    (%rsi,%rcx,1),%r8\n  84:   4c 89 04 0f             mov    %r8,(%rdi,%rcx,1)\n  88:   48 83 c1 08             add    $0x8,%rcx\n  8c:   48 39 c8                cmp    %rcx,%rax\n  8f:   75 ef                   jne    0x80\n  91:   48 39 d0                cmp    %rdx,%rax\n  94:   74 65                   je     0xfb\n  96:   48 89 c1                mov    %rax,%rcx\n  99:   48 f7 d1                not    %rcx\n  9c:   48 01 d1                add    %rdx,%rcx\n  9f:   49 89 d0                mov    %rdx,%r8\n  a2:   49 83 e0 03             and    $0x3,%r8\n  a6:   74 1d                   je     0xc5\n  a8:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)\n  af:   00\n  b0:   44 0f b6 0c 06          movzbl (%rsi,%rax,1),%r9d\n  b5:   44 88 0c 07             mov    %r9b,(%rdi,%rax,1)\n  b9:   48 ff c0                inc    %rax\n  bc:   0f 1f 40 00             nopl   0x0(%rax)\n  c0:   49 ff c8                dec    %r8\n  c3:   75 eb                   jne    0xb0\n  c5:   48 83 f9 03             cmp    $0x3,%rcx\n  c9:   72 30                   jb     0xfb\n  cb:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)\n  d0:   0f b6 0c 06             movzbl (%rsi,%rax,1),%ecx\n  d4:   88 0c 07                mov    %cl,(%rdi,%rax,1)\n  d7:   0f b6 4c 06 01          movzbl 0x1(%rsi,%rax,1),%ecx\n  dc:   88 4c 07 01             mov    %cl,0x1(%rdi,%rax,1)\n  e0:   0f b6 4c 06 02          movzbl 0x2(%rsi,%rax,1),%ecx\n  e5:   88 4c 07 02             mov    %cl,0x2(%rdi,%rax,1)\n  e9:   0f b6 4c 06 03          movzbl 0x3(%rsi,%rax,1),%ecx\n  ee:   88 4c 07 03             mov    %cl,0x3(%rdi,%rax,1)\n  f2:   48 83 c0 04             add    $0x4,%rax\n  f6:   48 39 c2                cmp    %rax,%rdx\n  f9:   75 d5                   jne    0xd0\n  fb:   31 c0                   xor    %eax,%eax\n  fd:   5d                      pop    %rbp\n  fe:   c3                      ret\n```\n\nBelow is the disassembly for `hemetic_copy` in release builds with this\nchange:\n```\nghanan@ghanan-glinux:~/Projects/fuchsia/out/workbench_eng.qemu-x64$ objdump -b binary -m i386:x86-64 -D ./user.basic_x64/obj/src/starnix/lib/usercopy/hermetic_copy.bin\n\n./user.basic_x64/obj/src/starnix/lib/usercopy/hermetic_copy.bin:     file format binary\n\nDisassembly of section .data:\n\n0000000000000000 \u003c.data\u003e:\n   0:   55                      push   %rbp\n   1:   48 89 e5                mov    %rsp,%rbp\n   4:   48 85 d2                test   %rdx,%rdx\n   7:   74 66                   je     0x6f\n   9:   89 d0                   mov    %edx,%eax\n   b:   83 e0 03                and    $0x3,%eax\n   e:   48 83 fa 04             cmp    $0x4,%rdx\n  12:   73 04                   jae    0x18\n  14:   31 c9                   xor    %ecx,%ecx\n  16:   eb 3b                   jmp    0x53\n  18:   48 83 e2 fc             and    $0xfffffffffffffffc,%rdx\n  1c:   31 c9                   xor    %ecx,%ecx\n  1e:   66 90                   xchg   %ax,%ax\n  20:   44 0f b6 04 0e          movzbl (%rsi,%rcx,1),%r8d\n  25:   44 88 04 0f             mov    %r8b,(%rdi,%rcx,1)\n  29:   44 0f b6 44 0e 01       movzbl 0x1(%rsi,%rcx,1),%r8d\n  2f:   44 88 44 0f 01          mov    %r8b,0x1(%rdi,%rcx,1)\n  34:   44 0f b6 44 0e 02       movzbl 0x2(%rsi,%rcx,1),%r8d\n  3a:   44 88 44 0f 02          mov    %r8b,0x2(%rdi,%rcx,1)\n  3f:   44 0f b6 44 0e 03       movzbl 0x3(%rsi,%rcx,1),%r8d\n  45:   44 88 44 0f 03          mov    %r8b,0x3(%rdi,%rcx,1)\n  4a:   48 83 c1 04             add    $0x4,%rcx\n  4e:   48 39 ca                cmp    %rcx,%rdx\n  51:   75 cd                   jne    0x20\n  53:   48 85 c0                test   %rax,%rax\n  56:   74 17                   je     0x6f\n  58:   48 01 cf                add    %rcx,%rdi\n  5b:   48 01 ce                add    %rcx,%rsi\n  5e:   31 c9                   xor    %ecx,%ecx\n  60:   0f b6 14 0e             movzbl (%rsi,%rcx,1),%edx\n  64:   88 14 0f                mov    %dl,(%rdi,%rcx,1)\n  67:   48 ff c1                inc    %rcx\n  6a:   48 39 c8                cmp    %rcx,%rax\n  6d:   75 f1                   jne    0x60\n  6f:   31 c0                   xor    %eax,%eax\n  71:   5d                      pop    %rbp\n  72:   c3                      ret\n```\n\nOriginal-Bug: b/276973344, b/309108366\nOriginal-Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/941432\nOriginal-Revision: 202074b0c3a0b67ad0f19631ceede2edbb370f52\nGitOrigin-RevId: cf6203b1eba66d79f49d1e8c002229c00909cb65\nChange-Id: I9fa2dd42dbb8091e3318c2f187530f2bd16cf22a\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "2339437f356b8f466668e5c9608a46cb52e5e57d",
      "old_mode": 33188,
      "old_path": "stem",
      "new_id": "3a03900dd862f0ee91ba15de5e59eab28d23a7d2",
      "new_mode": 33188,
      "new_path": "stem"
    }
  ]
}
