#define SATP_ASID_SHIFT                                44
 #define SATP_ASID_MASK                         _AC(0xFFFF, UL)
 
+/* SBI return error codes */
+#define SBI_SUCCESS                            0
+#define SBI_ERR_FAILURE                                -1
+#define SBI_ERR_NOT_SUPPORTED                  -2
+#define SBI_ERR_INVALID_PARAM                  -3
+#define SBI_ERR_DENIED                         -4
+#define SBI_ERR_INVALID_ADDRESS                        -5
+#define SBI_ERR_ALREADY_AVAILABLE              -6
+#define SBI_ERR_ALREADY_STARTED                        -7
+#define SBI_ERR_ALREADY_STOPPED                        -8
+
 #define SBI_EXT_EXPERIMENTAL_START             0x08000000
 #define SBI_EXT_EXPERIMENTAL_END               0x08FFFFFF
 
 #define KVM_RISCV_SELFTESTS_SBI_UCALL          0
 #define KVM_RISCV_SELFTESTS_SBI_UNEXP          1
 
+enum sbi_ext_id {
+       SBI_EXT_BASE = 0x10,
+};
+
+enum sbi_ext_base_fid {
+       SBI_EXT_BASE_PROBE_EXT = 3,
+};
+
 struct sbiret {
        long error;
        long value;
                        unsigned long arg3, unsigned long arg4,
                        unsigned long arg5);
 
+bool guest_sbi_probe_extension(int extid, long *out_val);
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
 
 
        return ret;
 }
+
+bool guest_sbi_probe_extension(int extid, long *out_val)
+{
+       struct sbiret ret;
+
+       ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid,
+                       0, 0, 0, 0, 0);
+
+       __GUEST_ASSERT(!ret.error || ret.error == SBI_ERR_NOT_SUPPORTED,
+                      "ret.error=%ld, ret.value=%ld\n", ret.error, ret.value);
+
+       if (ret.error == SBI_ERR_NOT_SUPPORTED)
+               return false;
+
+       if (out_val)
+               *out_val = ret.value;
+
+       return true;
+}