@@ -887,6 +887,38 @@ Modifies the XSAVE area.
* -KVM_EINVAL - the padding is not zero
* -KVM_EAGAIN - the selected vCPU can't be introspected yet
+21. KVMI_VCPU_GET_MTRR_TYPE
+---------------------------
+
+:Architectures: x86
+:Versions: >= 1
+:Parameters:
+
+::
+
+ struct kvmi_vcpu_hdr;
+ struct kvmi_vcpu_get_mtrr_type {
+ __u64 gpa;
+ };
+
+:Returns:
+
+::
+
+ struct kvmi_error_code;
+ struct kvmi_vcpu_get_mtrr_type_reply {
+ __u8 type;
+ __u8 padding[7];
+ };
+
+Returns the guest memory type for a specific guest physical address (``gpa``).
+
+:Errors:
+
+* -KVM_EINVAL - the selected vCPU is invalid
+* -KVM_EINVAL - the padding is not zero
+* -KVM_EAGAIN - the selected vCPU can't be introspected yet
+
Events
======
@@ -119,4 +119,13 @@ struct kvmi_vcpu_set_xsave {
struct kvm_xsave xsave;
};
+struct kvmi_vcpu_get_mtrr_type {
+ __u64 gpa;
+};
+
+struct kvmi_vcpu_get_mtrr_type_reply {
+ __u8 type;
+ __u8 padding[7];
+};
+
#endif /* _UAPI_ASM_X86_KVMI_H */
@@ -232,10 +232,27 @@ static int handle_vcpu_set_xsave(const struct kvmi_vcpu_msg_job *job,
return kvmi_msg_vcpu_reply(job, msg, ec, NULL, 0);
}
+static int handle_vcpu_get_mtrr_type(const struct kvmi_vcpu_msg_job *job,
+ const struct kvmi_msg_hdr *msg,
+ const void *_req)
+{
+ const struct kvmi_vcpu_get_mtrr_type *req = _req;
+ struct kvmi_vcpu_get_mtrr_type_reply rpl;
+ gfn_t gfn;
+
+ gfn = gpa_to_gfn(req->gpa);
+
+ memset(&rpl, 0, sizeof(rpl));
+ rpl.type = kvm_mtrr_get_guest_memory_type(job->vcpu, gfn);
+
+ return kvmi_msg_vcpu_reply(job, msg, 0, &rpl, sizeof(rpl));
+}
+
static kvmi_vcpu_msg_job_fct const msg_vcpu[] = {
[KVMI_VCPU_CONTROL_CR] = handle_vcpu_control_cr,
[KVMI_VCPU_GET_CPUID] = handle_vcpu_get_cpuid,
[KVMI_VCPU_GET_INFO] = handle_vcpu_get_info,
+ [KVMI_VCPU_GET_MTRR_TYPE] = handle_vcpu_get_mtrr_type,
[KVMI_VCPU_GET_REGISTERS] = handle_vcpu_get_registers,
[KVMI_VCPU_GET_XCR] = handle_vcpu_get_xcr,
[KVMI_VCPU_GET_XSAVE] = handle_vcpu_get_xsave,
@@ -47,6 +47,7 @@ enum {
KVMI_VCPU_GET_XCR = KVMI_VCPU_MESSAGE_ID(8),
KVMI_VCPU_GET_XSAVE = KVMI_VCPU_MESSAGE_ID(9),
KVMI_VCPU_SET_XSAVE = KVMI_VCPU_MESSAGE_ID(10),
+ KVMI_VCPU_GET_MTRR_TYPE = KVMI_VCPU_MESSAGE_ID(11),
KVMI_NEXT_VCPU_MESSAGE
};
@@ -1488,6 +1488,23 @@ static void test_cmd_vcpu_xsave(struct kvm_vm *vm)
cmd_vcpu_set_xsave(vm, &xsave);
}
+static void test_cmd_vcpu_get_mtrr_type(struct kvm_vm *vm)
+{
+ struct {
+ struct kvmi_msg_hdr hdr;
+ struct kvmi_vcpu_hdr vcpu_hdr;
+ struct kvmi_vcpu_get_mtrr_type cmd;
+ } req = {};
+ struct kvmi_vcpu_get_mtrr_type_reply rpl;
+
+ req.cmd.gpa = test_gpa;
+
+ test_vcpu0_command(vm, KVMI_VCPU_GET_MTRR_TYPE,
+ &req.hdr, sizeof(req), &rpl, sizeof(rpl), 0);
+
+ pr_debug("mtrr_type: gpa 0x%lx type 0x%x\n", test_gpa, rpl.type);
+}
+
static void test_introspection(struct kvm_vm *vm)
{
srandom(time(0));
@@ -1517,6 +1534,7 @@ static void test_introspection(struct kvm_vm *vm)
test_event_xsetbv(vm);
test_cmd_vcpu_get_xcr(vm);
test_cmd_vcpu_xsave(vm);
+ test_cmd_vcpu_get_mtrr_type(vm);
unhook_introspection(vm);
}