QEMU timerfd_create support on PowerPC

Bug #1807743 reported by Wes Tarro on 2018-12-10
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
qemu (Ubuntu)
Undecided
Unassigned
Precise
Undecided
Unassigned
Trusty
Undecided
Unassigned
Xenial
Undecided
Christian Ehrhardt 
Bionic
Undecided
Unassigned
Cosmic
Undecided
Unassigned

Bug Description

[Impact]

 * A bad named define made timerfd_create be in the code but not available

 * two smaller fixes to be backported from upstream that change the define
   names; This will enable the timerfd_create in qemu-user

[Test Case]

 * Compile the attached source code using your host C compiler.
   => https://launchpadlibrarian.net/401131808/timerfd_support_test.c
    $ apt install build-essential
    $ gcc -Wall timertest.c -o timertest
 * Run the resulting binary.
   It should run for 3 seconds and print timer information. (sanity
   test)
    $ ./timertest
 * Compile the attached source code using a PowerPC cross compiler with
   static linking enabled (to make the remaining steps simpler).
     $ apt install gcc-powerpc64-linux-gnu
     $ powerpc64-linux-gnu-gcc -static -Wall timertest.c -o timertest
 * Run the resulting binary using the unpatched qemu-user or qemu-user-
   static executable for your selected PowerPC architecture. It should
   exit immediately complaining about an unsupported syscall.
     $ apt install qemu-user
     $ qemu-ppc64 ./timertest
       qemu: Unsupported syscall: 306
       timerfd_create(CLOCK_REALTIME): Function not implemented

 * Run the same binary using the patched qemu-user or qemu-user-static
   executable for your selected PowerPC architecture.
   It should behave as the host version did.

Note: If you chose a big-endian PowerPC architecture, the "timer expirations" output may be "72057594037927936" instead of "1" because the bytes read were in host byte order instead of target byte order.

[Regression Potential]

 * The headers are only used internally so no outside regression should
   happen.
 * Even then only the names changed but the number stayed, that means even
   if it would be an external ABI (it isn't) the number would be the same
 * Internally the old define was only used when defining it, but not used
   (see grep in comment #1)
 * The one regression I could think of is software running in qemu-user
   today and working by having a path like "does this have timerfd create
   -> no, ok then do A", with the change this might become "-> yes, so do
   B" and if that B is broken there would be a regression, but I'd
   consider it unlikely since all versions after Xenials 2.5 had the new
   variant and I have seen no complaints about it.

[Other Info]

 * n/a

---

QEMU erroneously fails to detect support for the timerfd_create syscall when running user-mode emulation of PowerPC targets. QEMU supports the timerfd_create syscall, but because the PowerPC target syscall header has it named "timerfd" instead of "timerfd_create", support is erroneously not enabled. This notably affects anything that uses Boost.Asio with deadline timers because it uses timerfds under the hood. I have attached a patch to fix the problem. For now I have a custom-built qemu-user-static.deb file with this fix implemented, but I would appreciate it if you could officially backport this patch to 16.04 LTS (Xenial) so our developers can use the official package repositories.

Related branches

The attachment "Add an extra define to enable timerfd_create support." seems to be a patch. If it isn't, please remove the "patch" flag from the attachment, remove the "patch" tag, and if you are a member of the ~ubuntu-reviewers, unsubscribe the team.

[This is an automated message performed by a Launchpad user owned by ~brian-murray, for any issues please contact him.]

tags: added: patch

I agree to the case, but not fully to the fix.
The old syscall definitions came in in 2007 via [1] "Update Linux kernel syscall list" (v0.10.0)
The feature adding the timerfd was added in 2014 with [2] "linux-user: support timerfd_{create, gettime, settime} syscalls" (v2.2.0) using the wrong definitions.

Later this was fixed 2015 for arm [3] "linux-user/arm: Correct TARGET_NR_timerfd to TARGET_NR_timerfd_create" (v2.4.0) and for the rest 2016 in [4] "linux-user: correct timerfd_create syscall numbers" (2.6.0).

No follow on fixes after that seen in upstream/master

That said things are fixed in Yakkety and later.
And the feature didn't exist in Trusty.
So only Xenial is affected.

The changes seem doable, and even if one used the old header on a backport it became the number which still is the same number. Also those headers are not meant for external use (no one links on that, and even if one would - again - it is the same number now).

Old value only used in the defines:
$ grep -Hrn 'TARGET_NR_timerfd\s'
linux-user/sparc/syscall_nr.h:281:#define TARGET_NR_timerfd 312
linux-user/unicore32/syscall_nr.h:361:#define TARGET_NR_timerfd 350
linux-user/ppc/syscall_nr.h:322:#define TARGET_NR_timerfd 306
linux-user/sparc64/syscall_nr.h:313:#define TARGET_NR_timerfd 312
linux-user/mips/syscall_nr.h:323:#define TARGET_NR_timerfd (TARGET_NR_Linux + 318)
linux-user/sh4/syscall_nr.h:326:#define TARGET_NR_timerfd 322
linux-user/m68k/syscall_nr.h:320:#define TARGET_NR_timerfd 318
linux-user/x86_64/syscall_nr.h:284:#define TARGET_NR_timerfd 283
linux-user/s390x/syscall_nr.h:246:#define TARGET_NR_timerfd 317
linux-user/i386/syscall_nr.h:327:#define TARGET_NR_timerfd 322
linux-user/mips64/syscall_nr.h:287:#define TARGET_NR_timerfd (TARGET_NR_Linux + 281)
linux-user/mips64/syscall_nr.h:601:#define TARGET_NR_timerfd (TARGET_NR_Linux + 277)
linux-user/alpha/syscall_nr.h:416:#define TARGET_NR_timerfd 477

That said, that LGTM - except I'd backport the official upstream fixes [3] and [4].
@Wes - would you mind outlining steps to reproduce as that is an integral part of any SRU [5]

[1]: https://git.qemu.org/?p=qemu.git;a=commit;h=8dd77cca03ac6325bda61dbdb8b8a2021fe524c3
[2]: https://git.qemu.org/?p=qemu.git;a=commit;h=518343413fd311a3d95798b2c1d51853fd8d3c85
[3]: https://git.qemu.org/?p=qemu.git;a=commit;h=d82322e175d58c0c8951cbc905da1ca9ee2e008c
[4]: https://git.qemu.org/?p=qemu.git;a=commit;h=93a92d3bd649cd315db47b9fb5dcb6af657cc22c
[5]: https://wiki.ubuntu.com/StableReleaseUpdates#SRU_Bug_Template

Changed in qemu (Ubuntu Precise):
status: New → Invalid
Changed in qemu (Ubuntu Trusty):
status: New → Invalid
Changed in qemu (Ubuntu Xenial):
status: New → Confirmed
Changed in qemu (Ubuntu Bionic):
status: New → Fix Released
Changed in qemu (Ubuntu Cosmic):
status: New → Fix Released
Changed in qemu (Ubuntu):
status: New → Fix Released

@Wes: I added the SRU template and filled all but the testcase which I'd ask you to do.

description: updated
Wes Tarro (wesley.m.tarro) wrote :

I've attached source code to use for the test case. I tested it using the Ubuntu standard compiler (gcc package), the Ubuntu standard powerpc64 cross compiler (gcc-powerpc64-linux-gnu package), and a custom GCC 4.9.2 targeting PowerPC64 on an embedded board.

When I try to edit the description I'm getting timeout errors (maybe because I'm behind a corporate proxy?). I've written the test case below. Please add it to the bug description.

[Test Case]

 * Compile the attached source code using your host C compiler.
 * Run the resulting binary.
   > It should run for 3 seconds and print timer information. (sanity test)
 * Compile the attached source code using a PowerPC cross compiler with
   static linking enabled (to make the remaining steps simpler).
 * Run the resulting binary using the unpatched qemu-user or qemu-user-static
   executable for your selected PowerPC architecture.
   > It should exit immediately complaining about an unsupported syscall.
 * Run the same binary using the patched qemu-user or qemu-user-static
   executable for your selected PowerPC architecture.
   > It should behave as the host version did.
   > If you chose a big-endian PowerPC architecture, the "timer expirations"
     output may be "72057594037927936" instead of "1" because the bytes read
     were in host byte order instead of target byte order.

description: updated
description: updated

Tested on X-container - triggered the bug (slightly improved the test description)

Now:
# qemu-ppc64 ./timertest
Setting timerfd delay to 3 seconds ...
        2 seconds remaining
        current time: Wed Dec 12 14:27:15 2018

Checking delay after 1 second ...
        1 seconds remaining
        current time: Wed Dec 12 14:27:16 2018

Waiting for remaining delay ...
        timer expirations: 72057594037927936
        0 seconds remaining
        current time: Wed Dec 12 14:27:18 2018

That said test complete and verified

Changed in qemu (Ubuntu Xenial):
status: Confirmed → In Progress
assignee: nobody → Christian Ehrhardt  (paelzer)

Hello Wes, or anyone else affected,

Accepted qemu into xenial-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/qemu/1:2.5+dfsg-5ubuntu10.34 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed. Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested and change the tag from verification-needed-xenial to verification-done-xenial. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-xenial. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance for helping!

N.B. The updated package will be released to -updates after the bug(s) fixed by this package have been verified and the package has been in -proposed for a minimum of 7 days.

Changed in qemu (Ubuntu Xenial):
status: In Progress → Fix Committed
tags: added: verification-needed verification-needed-xenial
Wes Tarro (wesley.m.tarro) wrote :

I have tested this package and it fixes the bug without causing any regressions in my tests. To test the update I re-performed the test case procedure to verify the updated package fixed the bug and then used the updated package to run the unit tests for an internal application compiled for ppc64.

Is that enough to move this from verification-needed to verification-done?

Some tag updates needed for the automatism's to pick it up, thanks for testing Wes!

tags: added: verification-done verification-done-xenial
removed: verification-needed verification-needed-xenial
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package qemu - 1:2.5+dfsg-5ubuntu10.34

---------------
qemu (1:2.5+dfsg-5ubuntu10.34) xenial; urgency=medium

  * d/p/ubuntu/lp1807743-linux-user-timerfd.patch: fix define for
    timerfd_create system call (LP: #1807743)

 -- Christian Ehrhardt <email address hidden> Wed, 12 Dec 2018 13:18:01 +0100

Changed in qemu (Ubuntu Xenial):
status: Fix Committed → Fix Released

The verification of the Stable Release Update for qemu has completed successfully and the package has now been released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers