Uh oh!
There was an error while loading. Please reload this page.
Stop ppoll calling a live descriptor invalid - #316
Merged
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
macOS poll() answers POLLNVAL for any descriptor it will not put on a kqueue: /dev/null, /dev/zero, /dev/random, /dev/urandom, directories, and kqueue descriptors themselves. sys_ppoll copies host revents to the guest unchanged, so a guest polling an open /dev/null is told the descriptor is closed. Linux polls every one of them: the character devices and directories through the default always-ready mask, an epoll descriptor through its own readiness. POLLNVAL is not a vague error at the call site. A program that redirects its output to /dev/null and polls it reads POLLNVAL as a descriptor that no longer exists, closes it and drops it from the set, so the guest tears down a working descriptor of its own accord. macOS select() accepts every descriptor its poll() refuses, and reports real readiness for a kqueue descriptor rather than a fixed answer. poll_eval_unpollable() evaluates those entries through select(). They leave the poll set on the pass that exposes them and stay out; a refused entry makes poll() return at once, so that single restart waits for nothing, and a call holding none of them issues no extra syscall. Entries that sys_ppoll marked need_pollnval keep their POLLNVAL, so a closed guest fd still reports one. A guest's events reach the host untranslated, and Linux POLLWRNORM is the bit macOS spells POLLWRBAND, so the write test names the pair rather than POLLOUT alone. Verified: tests/test-poll.c carries five new cases and reports 19 passed, 0 failed both under elfuse and inside the qemu-system-aarch64 reference VM. The probe that exposed this returns revents=0x05 (POLLIN|POLLOUT) for /dev/null, /dev/zero, /dev/urandom and a directory descriptor on both sides. make check is clean, and tests/test-matrix.sh all stays within baseline with zero failures: elfuse-aarch64 255 passed, qemu-aarch64 234 passed, elfuse-x86_64 78 passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ppolltells the guest a descriptor is invalid when macOSpoll()will not put it on a kqueue:/dev/null,/dev/zero,/dev/urandom, directory descriptors and epoll descriptors are all open and, on Linux, ready.Summary by cubic
Stops ppoll on macOS from reporting POLLNVAL for live descriptors, matching Linux readiness for devices, directories, and epoll fds. Old: we propagated host poll()’s POLLNVAL; New: detect host-refused entries once and compute their readiness via select(), keeping POLLNVAL only for invalid fds.
Written for commit f0c25bf. Summary will update on new commits.