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 }