diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index ef837dbad..d7a590908 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -284,7 +284,16 @@ int gva2gpa(struct vcpu *vcpu, uint64_t gva, uint64_t *gpa, pw_info.level = pm; pw_info.is_write_access = ((*err_code & PAGE_FAULT_WR_FLAG) != 0U); pw_info.is_inst_fetch = ((*err_code & PAGE_FAULT_ID_FLAG) != 0U); - pw_info.is_user_mode = ((exec_vmread16(VMX_GUEST_CS_SEL) & 0x3U) == 3U); + + /* SDM vol3 27.3.2 + * If the segment register was unusable, the base, select and some + * bits of access rights are undefined. With the exception of + * DPL of SS + * and others. + * So we use DPL of SS access rights field for guest DPL. + */ + pw_info.is_user_mode = + (((exec_vmread32(VMX_GUEST_SS_ATTR)>>5) & 0x3U) == 3U); pw_info.pse = true; pw_info.nxe = ((vcpu_get_efer(vcpu) & MSR_IA32_EFER_NXE_BIT) != 0UL); pw_info.wp = ((vcpu_get_cr0(vcpu) & CR0_WP) != 0UL);