mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
x86/mce: translate passed-in GPA to host machine address
This patch adds a new flag MC_MSRINJ_F_GPADDR to xen_mc_msrinject.mcinj_flags, and makes do_mca() to translate the guest physical address passed-in through xen_mc_msrinject.mcinj_msr[i].value to the host machine address if this flag is present. Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com> Acked-by: Christoph Egger <chegger@amazon.de>
This commit is contained in:
1 parent
191f025598
commit
26646f34c3
2 files changed
+52
-9
No files matched your search
@@ -21,6 +21,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/p2m.h>
|
||||
|
||||
#include "mce.h"
|
||||
#include "barrier.h"
|
||||
@@ -48,14 +49,15 @@ struct mca_banks *mca_allbanks;
|
||||
#define _MC_MSRINJ_F_REQ_HWCR_WREN (1 << 16)
|
||||
|
||||
#if 0
|
||||
static int x86_mcerr(const char *msg, int err)
|
||||
{
|
||||
gdprintk(XENLOG_WARNING, "x86_mcerr: %s, returning %d\n",
|
||||
msg != NULL ? msg : "", err);
|
||||
return err;
|
||||
}
|
||||
#define x86_mcerr(fmt, err, args...) \
|
||||
({ \
|
||||
int _err = (err); \
|
||||
gdprintk(XENLOG_WARNING, "x86_mcerr: " fmt ", returning %d\n", \
|
||||
## args, _err); \
|
||||
_err; \
|
||||
})
|
||||
#else
|
||||
#define x86_mcerr(msg, err) (err)
|
||||
#define x86_mcerr(fmt, err, args...) (err)
|
||||
#endif
|
||||
|
||||
int mce_verbosity;
|
||||
@@ -1307,7 +1309,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
|
||||
|
||||
ret = xsm_do_mca(XSM_PRIV);
|
||||
if ( ret )
|
||||
return x86_mcerr(NULL, ret);
|
||||
return x86_mcerr("", ret);
|
||||
|
||||
if ( copy_from_guest(op, u_xen_mc, 1) )
|
||||
return x86_mcerr("do_mca: failed copyin of xen_mc_t", -EFAULT);
|
||||
@@ -1422,6 +1424,44 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
|
||||
if (mc_msrinject->mcinj_count == 0)
|
||||
return 0;
|
||||
|
||||
if ( mc_msrinject->mcinj_flags & MC_MSRINJ_F_GPADDR )
|
||||
{
|
||||
struct domain *d;
|
||||
struct mcinfo_msr *msr;
|
||||
unsigned int i;
|
||||
paddr_t gaddr;
|
||||
unsigned long gfn, mfn;
|
||||
p2m_type_t t;
|
||||
|
||||
d = get_domain_by_id(mc_msrinject->mcinj_domid);
|
||||
if ( d == NULL )
|
||||
return x86_mcerr("do_mca inject: bad domain id %d",
|
||||
-EINVAL, mc_msrinject->mcinj_domid);
|
||||
|
||||
for ( i = 0, msr = &mc_msrinject->mcinj_msr[0];
|
||||
i < mc_msrinject->mcinj_count;
|
||||
i++, msr++ )
|
||||
{
|
||||
gaddr = msr->value;
|
||||
gfn = PFN_DOWN(gaddr);
|
||||
mfn = mfn_x(get_gfn(d, gfn, &t));
|
||||
|
||||
if ( mfn == INVALID_MFN )
|
||||
{
|
||||
put_gfn(d, gfn);
|
||||
put_domain(d);
|
||||
return x86_mcerr("do_mca inject: bad gfn %#lx of domain %d",
|
||||
-EINVAL, gfn, mc_msrinject->mcinj_domid);
|
||||
}
|
||||
|
||||
msr->value = pfn_to_paddr(mfn) | (gaddr & (PAGE_SIZE - 1));
|
||||
|
||||
put_gfn(d, gfn);
|
||||
}
|
||||
|
||||
put_domain(d);
|
||||
}
|
||||
|
||||
if (!x86_mc_msrinject_verify(mc_msrinject))
|
||||
return x86_mcerr("do_mca inject: illegal MSR", -EINVAL);
|
||||
|
||||
|
||||
@@ -392,12 +392,15 @@ struct xen_mc_msrinject {
|
||||
uint32_t mcinj_cpunr; /* target processor id */
|
||||
uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */
|
||||
uint32_t mcinj_count; /* 0 .. count-1 in array are valid */
|
||||
uint32_t _pad0;
|
||||
domid_t mcinj_domid; /* valid only if MC_MSRINJ_F_GPADDR is
|
||||
present in mcinj_flags */
|
||||
uint16_t _pad0;
|
||||
struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS];
|
||||
};
|
||||
|
||||
/* Flags for mcinj_flags above; bits 16-31 are reserved */
|
||||
#define MC_MSRINJ_F_INTERPOSE 0x1
|
||||
#define MC_MSRINJ_F_GPADDR 0x2
|
||||
|
||||
#define XEN_MC_mceinject 5
|
||||
struct xen_mc_mceinject {
|
||||
|
||||