x86/vm_event: transfer nested p2m base info

Required to introspect events originating from nested VMs.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Tamas K Lengyel authored and Andrew Cooper committed 2021-01-05 23:00:27 +00:00
1 parent 2c5119d637
commit d581cf8839
2 files changed
+46 -3

No files matched your search

+30 -2
View File
@@ -26,6 +26,7 @@
#include <xen/mem_access.h>
#include <xen/monitor.h>
#include <asm/hvm/monitor.h>
#include <asm/hvm/nestedhvm.h>
#include <asm/altp2m.h>
#include <asm/monitor.h>
#include <asm/p2m.h>
@@ -33,6 +34,15 @@
#include <asm/vm_event.h>
#include <public/vm_event.h>
static void set_npt_base(struct vcpu *v, vm_event_request_t *req)
{
if ( nestedhvm_enabled(v->domain) && nestedhvm_vcpu_in_guestmode(v) )
{
req->flags |= VM_EVENT_FLAG_NESTED_P2M;
req->data.regs.x86.npt_base = nhvm_vcpu_p2m_base(v);
}
}
bool hvm_monitor_cr(unsigned int index, unsigned long value, unsigned long old)
{
struct vcpu *curr = current;
@@ -53,6 +63,8 @@ bool hvm_monitor_cr(unsigned int index, unsigned long value, unsigned long old)
.u.write_ctrlreg.old_value = old
};
set_npt_base(curr, &req);
return monitor_traps(curr, sync, &req) >= 0 &&
curr->domain->arch.monitor.control_register_values;
}
@@ -73,6 +85,8 @@ bool hvm_monitor_emul_unimplemented(void)
.vcpu_id = curr->vcpu_id,
};
set_npt_base(curr, &req);
return curr->domain->arch.monitor.emul_unimplemented_enabled &&
monitor_traps(curr, true, &req) == 1;
}
@@ -92,6 +106,8 @@ bool hvm_monitor_msr(unsigned int msr, uint64_t new_value, uint64_t old_value)
.u.mov_to_msr.old_value = old_value
};
set_npt_base(curr, &req);
return monitor_traps(curr, 1, &req) >= 0 &&
curr->domain->arch.monitor.control_register_values;
}
@@ -103,6 +119,7 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
uint64_t vmx_exit_qualification,
uint8_t descriptor, bool is_write)
{
struct vcpu *curr = current;
vm_event_request_t req = {
.reason = VM_EVENT_REASON_DESCRIPTOR_ACCESS,
.u.desc_access.descriptor = descriptor,
@@ -115,7 +132,9 @@ void hvm_monitor_descriptor_access(uint64_t exit_info,
req.u.desc_access.arch.vmx.exit_qualification = vmx_exit_qualification;
}
monitor_traps(current, true, &req);
set_npt_base(curr, &req);
monitor_traps(curr, true, &req);
}
static inline unsigned long gfn_of_rip(unsigned long rip)
@@ -189,6 +208,8 @@ int hvm_monitor_debug(unsigned long rip, enum hvm_monitor_debug_type type,
return -EOPNOTSUPP;
}
set_npt_base(curr, &req);
return monitor_traps(curr, sync, &req);
}
@@ -207,12 +228,15 @@ int hvm_monitor_cpuid(unsigned long insn_length, unsigned int leaf,
req.u.cpuid.leaf = leaf;
req.u.cpuid.subleaf = subleaf;
set_npt_base(curr, &req);
return monitor_traps(curr, 1, &req);
}
void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
unsigned int err, uint64_t cr2)
{
struct vcpu *curr = current;
vm_event_request_t req = {
.reason = VM_EVENT_REASON_INTERRUPT,
.u.interrupt.x86.vector = vector,
@@ -221,7 +245,9 @@ void hvm_monitor_interrupt(unsigned int vector, unsigned int type,
.u.interrupt.x86.cr2 = cr2,
};
monitor_traps(current, 1, &req);
set_npt_base(curr, &req);
monitor_traps(curr, 1, &req);
}
/*
@@ -297,6 +323,8 @@ bool hvm_monitor_check_p2m(unsigned long gla, gfn_t gfn, uint32_t pfec,
req.u.mem_access.gla = gla;
req.u.mem_access.offset = gpa & ~PAGE_MASK;
set_npt_base(curr, &req);
return monitor_traps(curr, true, &req) >= 0;
}
+16 -1
View File
@@ -29,7 +29,7 @@
#include "xen.h"
#define VM_EVENT_INTERFACE_VERSION 0x00000006
#define VM_EVENT_INTERFACE_VERSION 0x00000007
#if defined(__XEN__) || defined(__XEN_TOOLS__)
@@ -119,6 +119,10 @@
* which singlestep gets automatically disabled.
*/
#define VM_EVENT_FLAG_FAST_SINGLESTEP (1 << 11)
/*
* Set if the event comes from a nested VM and thus npt_base is valid.
*/
#define VM_EVENT_FLAG_NESTED_P2M (1 << 12)
/*
* Reasons for the vm event request
@@ -208,6 +212,17 @@ struct vm_event_regs_x86 {
uint64_t msr_star;
uint64_t msr_lstar;
uint64_t gdtr_base;
/*
* When VM_EVENT_FLAG_NESTED_P2M is set, this event comes from a nested
* VM. npt_base is the guest physical address of the L1 hypervisors
* EPT/NPT tables for the nested guest.
*
* All bits outside of architectural address ranges are reserved for
* future metadata.
*/
uint64_t npt_base;
uint32_t cs_base;
uint32_t ss_base;
uint32_t ds_base;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.