mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/HVM: don't leak PFEC_implict to guests
Doing so may not only confuse them, but will - on VMX - lead to VMRESUME failures. Add respective ASSERT()s where the fields get set to guard against future similar issues (or - in the restore case - fail the operation). In that latter code at once convert the mis-used gdprintk() to dprintk(), as the vCPU of interest is not "current". Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
1 parent
60bbae0502
commit
b706e1c6af
3 files changed
+36
-13
No files matched your search
@@ -3126,7 +3126,7 @@ static enum hvm_copy_result __hvm_copy(
|
||||
if ( pfinfo )
|
||||
{
|
||||
pfinfo->linear = addr;
|
||||
pfinfo->ec = pfec;
|
||||
pfinfo->ec = pfec & ~PFEC_implicit;
|
||||
}
|
||||
return HVMCOPY_bad_gva_to_gfn;
|
||||
}
|
||||
|
||||
@@ -269,13 +269,23 @@ static int svm_vmcb_restore(struct vcpu *v, struct hvm_hw_cpu *c)
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
struct p2m_domain *p2m = p2m_get_hostp2m(v->domain);
|
||||
|
||||
if ( c->pending_valid &&
|
||||
((c->pending_type == 1) || (c->pending_type > 6) ||
|
||||
(c->pending_reserved != 0)) )
|
||||
if ( c->pending_valid )
|
||||
{
|
||||
gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n",
|
||||
c->pending_event);
|
||||
return -EINVAL;
|
||||
if ( (c->pending_type == 1) || (c->pending_type > 6) ||
|
||||
(c->pending_reserved != 0) )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32"\n",
|
||||
v, c->pending_event);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( c->pending_error_valid &&
|
||||
c->error_code != (uint16_t)c->error_code )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32"\n",
|
||||
v, c->error_code);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !paging_mode_hap(v->domain) )
|
||||
@@ -1421,6 +1431,8 @@ static void svm_inject_event(const struct x86_event *event)
|
||||
vmcb->nextrip = (uint32_t)vmcb->nextrip;
|
||||
}
|
||||
|
||||
ASSERT(!eventinj.fields.ev ||
|
||||
eventinj.fields.errorcode == (uint16_t)eventinj.fields.errorcode);
|
||||
vmcb->eventinj = eventinj;
|
||||
|
||||
if ( _event.vector == TRAP_page_fault )
|
||||
|
||||
@@ -731,13 +731,23 @@ static int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ( c->pending_valid &&
|
||||
((c->pending_type == 1) || (c->pending_type > 6) ||
|
||||
(c->pending_reserved != 0)) )
|
||||
if ( c->pending_valid )
|
||||
{
|
||||
gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n",
|
||||
c->pending_event);
|
||||
return -EINVAL;
|
||||
if ( (c->pending_type == 1) || (c->pending_type > 6) ||
|
||||
(c->pending_reserved != 0) )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32"\n",
|
||||
v, c->pending_event);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( c->pending_error_valid &&
|
||||
c->error_code != (uint16_t)c->error_code )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32"\n",
|
||||
v, c->error_code);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3);
|
||||
@@ -1660,6 +1670,7 @@ static void __vmx_inject_exception(int trap, int type, int error_code)
|
||||
MASK_INSR(trap, INTR_INFO_VECTOR_MASK);
|
||||
if ( error_code != X86_EVENT_NO_EC )
|
||||
{
|
||||
ASSERT(error_code == (uint16_t)error_code);
|
||||
__vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
|
||||
intr_fields |= INTR_INFO_DELIVER_CODE_MASK;
|
||||
}
|
||||
|
||||