lib/sys/src/kvm/linux.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const builtin = @import("builtin");
3 const sys = @import("../root.zig");
4 const abi = @import("abi.zig");
5 const types = @import("types.zig");
6
7 pub const supported = builtin.os.tag == .linux and builtin.cpu.arch == .x86_64;
8
9 const LinuxOperations = struct {
10 pub fn platformSupported(_: *@This()) bool {
11 return supported;
12 }
13
14 pub fn openDevice(_: *@This()) types.RawResult {
15 if (comptime !supported) return .{ .failure = .NOSYS };
16 const result = std.os.linux.open(abi.device_path, .{
17 .ACCMODE = .RDWR,
18 .CLOEXEC = true,
19 }, 0);
20 return rawResult(result);
21 }
22
23 pub fn control(
24 _: *@This(),
25 descriptor: types.Descriptor,
26 request: u32,
27 argument: usize,
28 ) types.RawResult {
29 if (comptime !supported) return .{ .failure = .NOSYS };
30 return rawResult(std.os.linux.ioctl(descriptor, request, argument));
31 }
32
33 pub fn mapRun(
34 _: *@This(),
35 descriptor: types.Descriptor,
36 len: usize,
37 ) types.MapResult {
38 if (comptime !supported) return .{ .failure = .NOSYS };
39 const mapping = sys.memory.mapSharedFile(
40 descriptor,
41 len,
42 .{ .read = true, .write = true },
43 0,
44 ) catch |failure| return .{ .failure = mapErrno(failure) };
45 return .{ .mapping = mapping };
46 }
47
48 pub fn unmap(_: *@This(), mapping: []align(types.page_size) u8) void {
49 if (comptime !supported) return;
50 sys.memory.unmap(mapping);
51 }
52
53 pub fn close(_: *@This(), descriptor: types.Descriptor) void {
54 if (comptime !supported) return;
55 const code = std.os.linux.errno(std.os.linux.close(descriptor));
56 switch (code) {
57 .SUCCESS, .INTR => {},
58 else => unreachable,
59 }
60 }
61 };
62
63 var linux_operations: LinuxOperations = .{};
64
65 pub fn operations() types.Operations {
66 return types.operationsFor(&linux_operations);
67 }
68
69 fn rawResult(result: usize) types.RawResult {
70 const code = std.os.linux.errno(result);
71 return if (code == .SUCCESS)
72 .{ .value = result }
73 else
74 .{ .failure = code };
75 }
76
77 fn mapErrno(failure: sys.memory.MapError) types.Errno {
78 return switch (failure) {
79 error.AccessDenied => .ACCES,
80 error.PermissionDenied => .PERM,
81 error.OutOfMemory => .NOMEM,
82 error.UnsupportedPlatform => .NOSYS,
83 error.MapFailed => .IO,
84 };
85 }