Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a "custom" platform configuration for Wasmtime #7995

Merged
merged 11 commits into from
Feb 28, 2024

Conversation

alexcrichton
Copy link
Member

This commit leverages adds a new "platform" to Wasmtime to be supported in the crates/runtime/src/sys folder. This joins preexisting platforms such as Unix and Windows. The goal of this platform is to be an opt-in way to build Wasmtime for targets that don't have a predefined way to run.

The new "custom" platform requires --cfg wasmtime_custom_platform to be passed to the Rust compiler, for example by using RUSTFLAGS. This new platform bottoms out in a C API that is intended to be small and Linux-like. The C API is effectively the interface to virtual memory that Wasmtime requires. This C API is also available as a header file at examples/min-platform/embedding/wasmtime-platform.h (generated by cbindgen).

The main purpose of this is to make it easier to experiment with porting Wasmtime to new platforms. By decoupling a platform implementation from Wasmtime itself it should be possible to run these experiments out-of-tree. An example of this I've been working on is getting Wasmtime running on bare-metal with a custom kernel. This support enables defining the platform interface of the custom kernel's syscalls outside of Wasmtime.

@alexcrichton alexcrichton requested review from a team as code owners February 24, 2024 00:49
@alexcrichton alexcrichton requested review from fitzgen and removed request for a team February 24, 2024 00:49
@github-actions github-actions bot added the wasmtime:docs Issues related to Wasmtime's documentation label Feb 24, 2024
* with `wasmtime_memory_image_free` and `wasmtime_memory_image_map_at`
* will be used to map the image into new regions of the address space.
*/
extern struct wasmtime_memory_image *wasmtime_memory_image_new(const uint8_t *ptr, uintptr_t len);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ptr guaranteed to stay valid until the memory image is freed or does the implementation need to copy the data elsewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I'll expand the docs to indicate that a copy is required.

*/
extern void wasmtime_memory_image_remap_zeros(struct wasmtime_memory_image *image,
uint8_t *addr,
uintptr_t len);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need access to the memory image? It only modifies the VM mapping, right? And doesn't need to read the original content of the memory image.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mostly just reflecting the existing Wasmtime API, which has not been meticulously thought out, onto the C API. You're right though that this entire function I think is not necessary, and I've replaced it with a call to wasmtime_mmap_remap.

/**
* Deallocates the provided `wasmtime_memory_image`.
*/
extern void wasmtime_memory_image_free(struct wasmtime_memory_image *image);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all derived VM mappings guaranteed to be unmapped before calling this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not currently, no, I'll expand the documentation.

}

match sym.name()? {
"" | "memmove" | "memset" | "memcmp" | "memcpy" | "bcmp" | "__tls_get_addr" => {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the empty symbol used for? Is it for the STT_FILE symbols? If so skipping SymbolKind::File above makes more sense I think.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I didn't question it much, but turns out it's SymbolKind::Null so I filtered that out to remove this case.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me with answers to bjorn3's questions/comments

Comment on lines 31 to 32
/// If this function returns then the trap was not handled. This probably means
/// that a fatal exception happened and the process should be aborted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove "probably" here? If I were attempting to implement this API, I wouldn't know what to do with that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort of, but also sort of not. I've expanded the words here to describe that the meaning of an unhandled trap is embedder-specific. Basically if Wasmtime doesn't handle a SIGSEGV, for example, it's up to the application of what to do next. Wasmtime can't know whether that is surely an "abort the process" kind of exception.

Comment on lines +39 to +45
/// Abstract pointer type used in the `wasmtime_memory_image_*` APIs which
/// is defined by the embedder.
pub enum wasmtime_memory_image {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nomicon recommends against uninhabited types to represent C opaque types: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs

Any reason not to follow their guidance here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately that recommendation doesn't generate the right C header bindings.

I'm also not aware of any compiler issues using *mut Uninhabited, which is what these bindings are doing. While I know &mut Uninhabited is bad, the former is not plagued with the same issues as far as I'm aware.

crates/runtime/src/sys/custom/capi.rs Outdated Show resolved Hide resolved
Comment on lines 132 to 138
/// Attempts to create a new in-memory image of the `ptr`/`len` combo which
/// can be mapped to virtual addresses in the future. The returned
/// `wasmtime_memory_image` pointer can be `NULL` to indicate that an image
/// cannot be created. The structure otherwise will later be deallocated
/// with `wasmtime_memory_image_free` and `wasmtime_memory_image_map_at`
/// will be used to map the image into new regions of the address space.
pub fn wasmtime_memory_image_new(ptr: *const u8, len: usize) -> *mut wasmtime_memory_image;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does len have to be a multiple of the system's page size? Is the resulting memory image rounded up to the page size? Is this stuff visible at all to Wasmtime?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes they're both guaranteed to be page aligned, updated docs to match.

Is this stuff visible at all to Wasmtime?

Could you elaborate on this? (e.g. what you mean by "stuff")

@alexcrichton
Copy link
Member Author

Ok I've updated to make the C API fallible and Wasmtime propagates the error codes (thanks for pushing back on that @bjorn3!)

@alexcrichton alexcrichton added this pull request to the merge queue Feb 28, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 28, 2024
This commit leverages adds a new "platform" to Wasmtime to be supported
in the `crates/runtime/src/sys` folder. This joins preexisting platforms
such as Unix and Windows. The goal of this platform is to be an opt-in
way to build Wasmtime for targets that don't have a predefined way to
run.

The new "custom" platform requires `--cfg wasmtime_custom_platform` to
be passed to the Rust compiler, for example by using `RUSTFLAGS`. This
new platform bottoms out in a C API that is intended to be small and
Linux-like. The C API is effectively the interface to virtual memory
that Wasmtime requires. This C API is also available as a header file at
`examples/min-platform/embedding/wasmtime-platform.h` (generated by
`cbindgen`).

The main purpose of this is to make it easier to experiment with porting
Wasmtime to new platforms. By decoupling a platform implementation from
Wasmtime itself it should be possible to run these experiments
out-of-tree. An example of this I've been working on is getting
Wasmtime running on bare-metal with a custom kernel. This support
enables defining the platform interface of the custom kernel's syscalls
outside of Wasmtime.
@alexcrichton alexcrichton added this pull request to the merge queue Feb 28, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 28, 2024
@alexcrichton alexcrichton added this pull request to the merge queue Feb 28, 2024
@alexcrichton alexcrichton removed this pull request from the merge queue due to a manual request Feb 28, 2024
@alexcrichton alexcrichton added this pull request to the merge queue Feb 28, 2024
Merged via the queue into bytecodealliance:main with commit b81bb7a Feb 28, 2024
19 checks passed
@alexcrichton alexcrichton deleted the min-platform-upstream branch February 28, 2024 20:52
@bjorn3 bjorn3 mentioned this pull request Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasmtime:docs Issues related to Wasmtime's documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants