diff --git a/kvm-bindings/CHANGELOG.md b/kvm-bindings/CHANGELOG.md index 16ec3d1f..92f9d9ea 100644 --- a/kvm-bindings/CHANGELOG.md +++ b/kvm-bindings/CHANGELOG.md @@ -2,6 +2,10 @@ ## Upcoming Release +### Added + +- Added bindings for riscv64 sbi ecall interface + ## v0.14.0 ### Changed diff --git a/kvm-bindings/src/riscv64/mod.rs b/kvm-bindings/src/riscv64/mod.rs index bef3bafc..2f110c13 100644 --- a/kvm-bindings/src/riscv64/mod.rs +++ b/kvm-bindings/src/riscv64/mod.rs @@ -7,6 +7,7 @@ pub mod bindings; #[cfg(feature = "fam-wrappers")] pub mod fam_wrappers; +pub mod sbi_bindings; #[cfg(feature = "serde")] mod serialize; @@ -14,3 +15,4 @@ mod serialize; pub use self::bindings::*; #[cfg(feature = "fam-wrappers")] pub use self::fam_wrappers::*; +pub use self::sbi_bindings::*; diff --git a/kvm-bindings/src/riscv64/sbi_bindings.rs b/kvm-bindings/src/riscv64/sbi_bindings.rs new file mode 100644 index 00000000..e885f568 --- /dev/null +++ b/kvm-bindings/src/riscv64/sbi_bindings.rs @@ -0,0 +1,58 @@ +/* automatically generated by rust-bindgen 0.72.1 */ + +pub const SBI_SUCCESS: u32 = 0; +pub const SBI_ERR_FAILED: i32 = -1; +pub const SBI_ERR_NOT_SUPPORTED: i32 = -2; +pub const SBI_ERR_INVALID_PARAM: i32 = -3; +pub const SBI_ERR_DENIED: i32 = -4; +pub const SBI_ERR_INVALID_ADDRESS: i32 = -5; +pub const SBI_ERR_ALREADY_AVAILABLE: i32 = -6; +pub const SBI_ERR_ALREADY_STARTED: i32 = -7; +pub const SBI_ERR_ALREADY_STOPPED: i32 = -8; +pub const SBI_ERR_NO_SHMEM: i32 = -9; +pub const SBI_EXT_0_1_SET_TIMER: u32 = 0; +pub const SBI_EXT_0_1_CONSOLE_PUTCHAR: u32 = 1; +pub const SBI_EXT_0_1_CONSOLE_GETCHAR: u32 = 2; +pub const SBI_EXT_0_1_CLEAR_IPI: u32 = 3; +pub const SBI_EXT_0_1_SEND_IPI: u32 = 4; +pub const SBI_EXT_0_1_REMOTE_FENCE_I: u32 = 5; +pub const SBI_EXT_0_1_REMOTE_SFENCE_VMA: u32 = 6; +pub const SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID: u32 = 7; +pub const SBI_EXT_0_1_SHUTDOWN: u32 = 8; +pub const SBI_EXT_BASE: u32 = 16; +pub const SBI_EXT_TIME: u32 = 1414090053; +pub const SBI_EXT_IPI: u32 = 7557193; +pub const SBI_EXT_RFENCE: u32 = 1380339267; +pub const SBI_EXT_HSM: u32 = 4739917; +pub const SBI_EXT_DBCN: u32 = 1145193294; +pub const SBI_EXT_BASE_GET_SPEC_VERSION: u32 = 0; +pub const SBI_EXT_BASE_GET_IMP_ID: u32 = 1; +pub const SBI_EXT_BASE_GET_IMP_VERSION: u32 = 2; +pub const SBI_EXT_BASE_PROBE_EXT: u32 = 3; +pub const SBI_EXT_BASE_GET_MVENDORID: u32 = 4; +pub const SBI_EXT_BASE_GET_MARCHID: u32 = 5; +pub const SBI_EXT_BASE_GET_MIMPID: u32 = 6; +pub const SBI_EXT_TIME_SET_TIMER: u32 = 0; +pub const SBI_EXT_IPI_SEND_IPI: u32 = 0; +pub const SBI_EXT_RFENCE_REMOTE_FENCE_I: u32 = 0; +pub const SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: u32 = 1; +pub const SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: u32 = 2; +pub const SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: u32 = 3; +pub const SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: u32 = 4; +pub const SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: u32 = 5; +pub const SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: u32 = 6; +pub const SBI_EXT_HSM_HART_START: u32 = 0; +pub const SBI_EXT_HSM_HART_STOP: u32 = 1; +pub const SBI_EXT_HSM_HART_GET_STATUS: u32 = 2; +pub const SBI_EXT_DBCN_CONSOLE_WRITE: u32 = 0; +pub const SBI_EXT_DBCN_CONSOLE_READ: u32 = 1; +pub const SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: u32 = 2; +pub const SBI_HSM_HART_STATUS_STARTED: u32 = 0; +pub const SBI_HSM_HART_STATUS_STOPPED: u32 = 1; +pub const SBI_HSM_HART_STATUS_START_PENDING: u32 = 2; +pub const SBI_HSM_HART_STATUS_STOP_PENDING: u32 = 3; +pub const SBI_SPEC_VERSION_MAJOR_OFFSET: u32 = 24; +pub const SBI_SPEC_VERSION_MAJOR_MASK: u32 = 127; +pub const SBI_SPEC_VERSION_MINOR_MASK: u32 = 16777215; +pub const SBI_EXT_VENDOR_START: u32 = 150994944; +pub const SBI_EXT_VENDOR_END: u32 = 167772159; diff --git a/kvm-ioctls/CHANGELOG.md b/kvm-ioctls/CHANGELOG.md index fd17f5f2..69a55533 100644 --- a/kvm-ioctls/CHANGELOG.md +++ b/kvm-ioctls/CHANGELOG.md @@ -3,6 +3,7 @@ ## Upcoming Release - Plumb through KVM_CAP_DIRTY_LOG_RING as DirtyLogRing cap. +- Handle console riscv64 sbi call ## v0.24.0 diff --git a/kvm-ioctls/src/ioctls/vcpu.rs b/kvm-ioctls/src/ioctls/vcpu.rs index a1002aa5..a3f4b2da 100644 --- a/kvm-ioctls/src/ioctls/vcpu.rs +++ b/kvm-ioctls/src/ioctls/vcpu.rs @@ -184,6 +184,10 @@ pub enum VcpuExit<'a> { /// size size: u64, }, + /// Corresponds to SBI_EXT_0_1_CONSOLE_PUTCHAR. + SbiExt0_1ConsolePutchar(u64), + /// Corresponds to SBI_EXT_0_1_CONSOLE_GETCHAR. + SbiExt0_1ConsoleGetchar(&'a mut [u64]), /// Corresponds to an exit reason that is unknown from the current version /// of the kvm-ioctls crate. Let the consumer decide about what to do with /// it. @@ -1688,6 +1692,26 @@ impl VcpuFd { Ok(VcpuExit::IoapicEoi(eoi.vector)) } KVM_EXIT_HYPERV => Ok(VcpuExit::Hyperv), + #[cfg(target_arch = "riscv64")] + KVM_EXIT_RISCV_SBI => { + // SAFETY: Safe because the exit_reason (which comes from the kernel) told us + // which union field to use and the type of extension_id is 'enum sbi_ext_id'. + match unsafe { run.__bindgen_anon_1.riscv_sbi.extension_id } as u32 { + SBI_EXT_0_1_CONSOLE_PUTCHAR => { + // SAFETY: Safe because the exit_reason (which comes from the kernel) told us + // which union field to use + let ch = unsafe { run.__bindgen_anon_1.riscv_sbi.args[0] }; + Ok(VcpuExit::SbiExt0_1ConsolePutchar(ch)) + } + SBI_EXT_0_1_CONSOLE_GETCHAR => { + // SAFETY: Safe because the exit_reason (which comes from the kernel) told us + // which union field to use + let ch = unsafe { &mut run.__bindgen_anon_1.riscv_sbi.ret[..1] }; + Ok(VcpuExit::SbiExt0_1ConsoleGetchar(ch)) + } + r => Ok(VcpuExit::Unsupported(r)), + } + } r => Ok(VcpuExit::Unsupported(r)), } } else { @@ -2630,6 +2654,25 @@ mod tests { 0x03, 0xa5, 0x0c, 0x00, // lw a0, 0(s9); test MMIO read 0x93, 0x05, 0x70, 0x60, // li a1, 0x0607; 0x23, 0xa0, 0xbc, 0x00, // sw a1, 0(s9); test MMIO write + //sbi_console_getchar + 0x01, 0x45, // li a0, 0 + 0x81, 0x45, // li a1, 0 + 0x01, 0x46, // li a2, 0 + 0x81, 0x46, // li a3, 0 + 0x01, 0x47, // li a4, 0 + 0x81, 0x47, // li a5, 0 + 0x01, 0x48, // li a6, 0 + 0x89, 0x48, // li a7, 2 + 0x73, 0x00, 0x00, 0x00, //ecall + //sbi_console_putchar + 0x81, 0x45, // li a1, 0 + 0x01, 0x46, // li a2, 0 + 0x81, 0x46, // li a3, 0 + 0x01, 0x47, // li a4, 0 + 0x81, 0x47, // li a5, 0 + 0x01, 0x48, // li a6, 0 + 0x85, 0x48, // li a7, 1 + 0x73, 0x00, 0x00, 0x00, //ecall 0x6f, 0x00, 0x00, 0x00, // j .; shouldn't get here, but if so loop forever ]; @@ -2701,6 +2744,12 @@ mod tests { .map(|page| page.count_ones()) .sum(); assert_eq!(dirty_pages, 1); + } + VcpuExit::SbiExt0_1ConsoleGetchar(data) => { + data[0] = 0x2a; + } + VcpuExit::SbiExt0_1ConsolePutchar(data) => { + assert_eq!(data, 0x2a); break; } r => panic!("unexpected exit reason: {:?}", r),