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:
Haozhong Zhang authored and Jan Beulich committed 2015-09-16 11:40:26 +02:00
1 parent 191f025598
commit 26646f34c3
2 files changed
+52 -9

No files matched your search

+48 -8
View File
@@ -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);
+4 -1
View File
@@ -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 {
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.