The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/xen/arch-x86/xen-mca.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  * arch-x86/mca.h
    3  *
    4  * Contributed by Advanced Micro Devices, Inc.
    5  * Author: Christoph Egger <Christoph.Egger@amd.com>
    6  *
    7  * Guest OS machine check interface to x86 Xen.
    8  *
    9  * Permission is hereby granted, free of charge, to any person obtaining a copy
   10  * of this software and associated documentation files (the "Software"), to
   11  * deal in the Software without restriction, including without limitation the
   12  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   13  * sell copies of the Software, and to permit persons to whom the Software is
   14  * furnished to do so, subject to the following conditions:
   15  *
   16  * The above copyright notice and this permission notice shall be included in
   17  * all copies or substantial portions of the Software.
   18  *
   19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   25  * DEALINGS IN THE SOFTWARE.
   26  */
   27 
   28 /* Full MCA functionality has the following Usecases from the guest side:
   29  *
   30  * Must have's:
   31  * 1. Dom0 and DomU register machine check trap callback handlers
   32  *    (already done via "set_trap_table" hypercall)
   33  * 2. Dom0 registers machine check event callback handler
   34  *    (doable via EVTCHNOP_bind_virq)
   35  * 3. Dom0 and DomU fetches machine check data
   36  * 4. Dom0 wants Xen to notify a DomU
   37  * 5. Dom0 gets DomU ID from physical address
   38  * 6. Dom0 wants Xen to kill DomU (already done for "xm destroy")
   39  *
   40  * Nice to have's:
   41  * 7. Dom0 wants Xen to deactivate a physical CPU
   42  *    This is better done as separate task, physical CPU hotplugging,
   43  *    and hypercall(s) should be sysctl's
   44  * 8. Page migration proposed from Xen NUMA work, where Dom0 can tell Xen to
   45  *    move a DomU (or Dom0 itself) away from a malicious page
   46  *    producing correctable errors.
   47  * 9. offlining physical page:
   48  *    Xen free's and never re-uses a certain physical page.
   49  * 10. Testfacility: Allow Dom0 to write values into machine check MSR's
   50  *     and tell Xen to trigger a machine check
   51  */
   52 
   53 #ifndef __XEN_PUBLIC_ARCH_X86_MCA_H__
   54 #define __XEN_PUBLIC_ARCH_X86_MCA_H__
   55 
   56 /* Hypercall */
   57 #define __HYPERVISOR_mca __HYPERVISOR_arch_0
   58 
   59 /*
   60  * The xen-unstable repo has interface version 0x03000001; out interface
   61  * is incompatible with that and any future minor revisions, so we
   62  * choose a different version number range that is numerically less
   63  * than that used in xen-unstable.
   64  */
   65 #define XEN_MCA_INTERFACE_VERSION 0x01ecc003
   66 
   67 /* IN: Dom0 calls hypercall to retrieve nonurgent telemetry */
   68 #define XEN_MC_NONURGENT  0x0001
   69 /* IN: Dom0/DomU calls hypercall to retrieve urgent telemetry */
   70 #define XEN_MC_URGENT     0x0002
   71 /* IN: Dom0 acknowledges previosly-fetched telemetry */
   72 #define XEN_MC_ACK        0x0004
   73 
   74 /* OUT: All is ok */
   75 #define XEN_MC_OK           0x0
   76 /* OUT: Domain could not fetch data. */
   77 #define XEN_MC_FETCHFAILED  0x1
   78 /* OUT: There was no machine check data to fetch. */
   79 #define XEN_MC_NODATA       0x2
   80 /* OUT: Between notification time and this hypercall an other
   81  *  (most likely) correctable error happened. The fetched data,
   82  *  does not match the original machine check data. */
   83 #define XEN_MC_NOMATCH      0x4
   84 
   85 /* OUT: DomU did not register MC NMI handler. Try something else. */
   86 #define XEN_MC_CANNOTHANDLE 0x8
   87 /* OUT: Notifying DomU failed. Retry later or try something else. */
   88 #define XEN_MC_NOTDELIVERED 0x10
   89 /* Note, XEN_MC_CANNOTHANDLE and XEN_MC_NOTDELIVERED are mutually exclusive. */
   90 
   91 /* Applicable to all mc_vcpuid fields below. */
   92 #define XEN_MC_VCPUID_INVALID 0xffff
   93 
   94 #ifndef __ASSEMBLY__
   95 
   96 #define VIRQ_MCA VIRQ_ARCH_0 /* G. (DOM0) Machine Check Architecture */
   97 
   98 /*
   99  * Machine Check Architecure:
  100  * structs are read-only and used to report all kinds of
  101  * correctable and uncorrectable errors detected by the HW.
  102  * Dom0 and DomU: register a handler to get notified.
  103  * Dom0 only: Correctable errors are reported via VIRQ_MCA
  104  * Dom0 and DomU: Uncorrectable errors are reported via nmi handlers
  105  */
  106 #define MC_TYPE_GLOBAL          0
  107 #define MC_TYPE_BANK            1
  108 #define MC_TYPE_EXTENDED        2
  109 #define MC_TYPE_RECOVERY        3
  110 
  111 struct mcinfo_common {
  112     uint16_t type;      /* structure type */
  113     uint16_t size;      /* size of this struct in bytes */
  114 };
  115 typedef struct mcinfo_common xen_mcinfo_common_t;
  116 
  117 #define MC_FLAG_CORRECTABLE     (1 << 0)
  118 #define MC_FLAG_UNCORRECTABLE   (1 << 1)
  119 #define MC_FLAG_RECOVERABLE     (1 << 2)
  120 #define MC_FLAG_POLLED          (1 << 3)
  121 #define MC_FLAG_RESET           (1 << 4)
  122 #define MC_FLAG_CMCI            (1 << 5)
  123 #define MC_FLAG_MCE             (1 << 6)
  124 /* contains global x86 mc information */
  125 struct mcinfo_global {
  126     xen_mcinfo_common_t common;
  127 
  128     /* running domain at the time in error (most likely the impacted one) */
  129     uint16_t mc_domid;
  130     uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
  131     uint32_t mc_socketid; /* physical socket of the physical core */
  132     uint16_t mc_coreid; /* physical impacted core */
  133     uint16_t mc_core_threadid; /* core thread of physical core */
  134     uint32_t mc_apicid;
  135     uint32_t mc_flags;
  136     uint64_t mc_gstatus; /* global status */
  137 };
  138 
  139 /* contains bank local x86 mc information */
  140 struct mcinfo_bank {
  141     xen_mcinfo_common_t common;
  142 
  143     uint16_t mc_bank; /* bank nr */
  144     uint16_t mc_domid; /* Usecase 5: domain referenced by mc_addr on dom0
  145                         * and if mc_addr is valid. Never valid on DomU. */
  146     uint64_t mc_status; /* bank status */
  147     uint64_t mc_addr;   /* bank address, only valid
  148                          * if addr bit is set in mc_status */
  149     uint64_t mc_misc;
  150     uint64_t mc_ctrl2;
  151     uint64_t mc_tsc;
  152 };
  153 
  154 
  155 struct mcinfo_msr {
  156     uint64_t reg;   /* MSR */
  157     uint64_t value; /* MSR value */
  158 };
  159 typedef struct mcinfo_msr xen_mcinfo_msr_t;
  160 
  161 /* contains mc information from other
  162  * or additional mc MSRs */
  163 struct mcinfo_extended {
  164     xen_mcinfo_common_t common;
  165 
  166     /* You can fill up to five registers.
  167      * If you need more, then use this structure
  168      * multiple times. */
  169 
  170     uint32_t mc_msrs; /* Number of msr with valid values. */
  171     /*
  172      * Currently Intel extended MSR (32/64) include all gp registers
  173      * and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be
  174      * useful at present. So expand this array to 32 to leave room.
  175      */
  176     xen_mcinfo_msr_t mc_msr[32];
  177 };
  178 
  179 /* Recovery Action flags. Giving recovery result information to DOM0 */
  180 
  181 /* Xen takes successful recovery action, the error is recovered */
  182 #define REC_ACTION_RECOVERED (0x1 << 0)
  183 /* No action is performed by XEN */
  184 #define REC_ACTION_NONE (0x1 << 1)
  185 /* It's possible DOM0 might take action ownership in some case */
  186 #define REC_ACTION_NEED_RESET (0x1 << 2)
  187 
  188 /* Different Recovery Action types, if the action is performed successfully,
  189  * REC_ACTION_RECOVERED flag will be returned.
  190  */
  191 
  192 /* Page Offline Action */
  193 #define MC_ACTION_PAGE_OFFLINE (0x1 << 0)
  194 /* CPU offline Action */
  195 #define MC_ACTION_CPU_OFFLINE (0x1 << 1)
  196 /* L3 cache disable Action */
  197 #define MC_ACTION_CACHE_SHRINK (0x1 << 2)
  198 
  199 /* Below interface used between XEN/DOM0 for passing XEN's recovery action
  200  * information to DOM0.
  201  * usage Senario: After offlining broken page, XEN might pass its page offline
  202  * recovery action result to DOM0. DOM0 will save the information in
  203  * non-volatile memory for further proactive actions, such as offlining the
  204  * easy broken page earlier when doing next reboot.
  205 */
  206 struct page_offline_action
  207 {
  208     /* Params for passing the offlined page number to DOM0 */
  209     uint64_t mfn;
  210     uint64_t status;
  211 };
  212 typedef struct page_offline_action xen_page_offline_action_t;
  213 
  214 struct cpu_offline_action
  215 {
  216     /* Params for passing the identity of the offlined CPU to DOM0 */
  217     uint32_t mc_socketid;
  218     uint16_t mc_coreid;
  219     uint16_t mc_core_threadid;
  220 };
  221 typedef struct cpu_offline_action xen_cpu_offline_action_t;
  222 
  223 #define MAX_UNION_SIZE 16
  224 struct mcinfo_recovery
  225 {
  226     xen_mcinfo_common_t common;
  227     uint16_t mc_bank; /* bank nr */
  228     uint8_t action_flags;
  229     uint8_t action_types;
  230     union {
  231         xen_page_offline_action_t page_retire;
  232         xen_cpu_offline_action_t cpu_offline;
  233         uint8_t pad[MAX_UNION_SIZE];
  234     } action_info;
  235 };
  236 
  237 
  238 #define MCINFO_HYPERCALLSIZE    1024
  239 #define MCINFO_MAXSIZE          768
  240 
  241 #define MCINFO_FLAGS_UNCOMPLETE 0x1
  242 struct mc_info {
  243     /* Number of mcinfo_* entries in mi_data */
  244     uint32_t mi_nentries;
  245     uint32_t flags;
  246     uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
  247 };
  248 typedef struct mc_info mc_info_t;
  249 DEFINE_XEN_GUEST_HANDLE(mc_info_t);
  250 
  251 #define __MC_MSR_ARRAYSIZE 8
  252 #if __XEN_INTERFACE_VERSION__ <= 0x00040d00
  253 #define __MC_NMSRS 1
  254 #endif
  255 #define MC_NCAPS        7       /* 7 CPU feature flag words */
  256 #define MC_CAPS_STD_EDX 0       /* cpuid level 0x00000001 (%edx) */
  257 #define MC_CAPS_AMD_EDX 1       /* cpuid level 0x80000001 (%edx) */
  258 #define MC_CAPS_TM      2       /* cpuid level 0x80860001 (TransMeta) */
  259 #define MC_CAPS_LINUX   3       /* Linux-defined */
  260 #define MC_CAPS_STD_ECX 4       /* cpuid level 0x00000001 (%ecx) */
  261 #define MC_CAPS_VIA     5       /* cpuid level 0xc0000001 */
  262 #define MC_CAPS_AMD_ECX 6       /* cpuid level 0x80000001 (%ecx) */
  263 
  264 struct mcinfo_logical_cpu {
  265     uint32_t mc_cpunr;
  266     uint32_t mc_chipid;
  267     uint16_t mc_coreid;
  268     uint16_t mc_threadid;
  269     uint32_t mc_apicid;
  270     uint32_t mc_clusterid;
  271     uint32_t mc_ncores;
  272     uint32_t mc_ncores_active;
  273     uint32_t mc_nthreads;
  274     int32_t mc_cpuid_level;
  275     uint32_t mc_family;
  276     uint32_t mc_vendor;
  277     uint32_t mc_model;
  278     uint32_t mc_step;
  279     char mc_vendorid[16];
  280     char mc_brandid[64];
  281     uint32_t mc_cpu_caps[MC_NCAPS];
  282     uint32_t mc_cache_size;
  283     uint32_t mc_cache_alignment;
  284     int32_t mc_nmsrvals;
  285     xen_mcinfo_msr_t mc_msrvalues[__MC_MSR_ARRAYSIZE];
  286 };
  287 typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t;
  288 DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t);
  289 
  290 
  291 /*
  292  * OS's should use these instead of writing their own lookup function
  293  * each with its own bugs and drawbacks.
  294  * We use macros instead of static inline functions to allow guests
  295  * to include this header in assembly files (*.S).
  296  */
  297 /* Prototype:
  298  *    uint32_t x86_mcinfo_nentries(struct mc_info *mi);
  299  */
  300 #define x86_mcinfo_nentries(_mi)    \
  301     (_mi)->mi_nentries
  302 /* Prototype:
  303  *    struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi);
  304  */
  305 #define x86_mcinfo_first(_mi)       \
  306     ((struct mcinfo_common *)(_mi)->mi_data)
  307 /* Prototype:
  308  *    struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic);
  309  */
  310 #define x86_mcinfo_next(_mic)       \
  311     ((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size))
  312 
  313 /* Prototype:
  314  *    void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type);
  315  */
  316 #define x86_mcinfo_lookup(_ret, _mi, _type)    \
  317     do {                                                        \
  318         uint32_t found, i;                                      \
  319         struct mcinfo_common *_mic;                             \
  320                                                                 \
  321         found = 0;                                              \
  322         (_ret) = NULL;                                          \
  323         if (_mi == NULL) break;                                 \
  324         _mic = x86_mcinfo_first(_mi);                           \
  325         for (i = 0; i < x86_mcinfo_nentries(_mi); i++) {        \
  326             if (_mic->type == (_type)) {                        \
  327                 found = 1;                                      \
  328                 break;                                          \
  329             }                                                   \
  330             _mic = x86_mcinfo_next(_mic);                       \
  331         }                                                       \
  332         (_ret) = found ? _mic : NULL;                           \
  333     } while (0)
  334 
  335 
  336 /* Usecase 1
  337  * Register machine check trap callback handler
  338  *    (already done via "set_trap_table" hypercall)
  339  */
  340 
  341 /* Usecase 2
  342  * Dom0 registers machine check event callback handler
  343  * done by EVTCHNOP_bind_virq
  344  */
  345 
  346 /* Usecase 3
  347  * Fetch machine check data from hypervisor.
  348  * Note, this hypercall is special, because both Dom0 and DomU must use this.
  349  */
  350 #define XEN_MC_fetch            1
  351 struct xen_mc_fetch {
  352     /* IN/OUT variables. */
  353     uint32_t flags;     /* IN: XEN_MC_NONURGENT, XEN_MC_URGENT,
  354                            XEN_MC_ACK if ack'ing an earlier fetch */
  355                        /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED,
  356                           XEN_MC_NODATA, XEN_MC_NOMATCH */
  357     uint32_t _pad0;
  358     uint64_t fetch_id;  /* OUT: id for ack, IN: id we are ack'ing */
  359 
  360     /* OUT variables. */
  361     XEN_GUEST_HANDLE(mc_info_t) data;
  362 };
  363 typedef struct xen_mc_fetch xen_mc_fetch_t;
  364 DEFINE_XEN_GUEST_HANDLE(xen_mc_fetch_t);
  365 
  366 
  367 /* Usecase 4
  368  * This tells the hypervisor to notify a DomU about the machine check error
  369  */
  370 #define XEN_MC_notifydomain     2
  371 struct xen_mc_notifydomain {
  372     /* IN variables. */
  373     uint16_t mc_domid;    /* The unprivileged domain to notify. */
  374     uint16_t mc_vcpuid;   /* The vcpu in mc_domid to notify.
  375                            * Usually echo'd value from the fetch hypercall. */
  376 
  377     /* IN/OUT variables. */
  378     uint32_t flags;
  379 
  380 /* IN: XEN_MC_CORRECTABLE, XEN_MC_TRAP */
  381 /* OUT: XEN_MC_OK, XEN_MC_CANNOTHANDLE, XEN_MC_NOTDELIVERED, XEN_MC_NOMATCH */
  382 };
  383 typedef struct xen_mc_notifydomain xen_mc_notifydomain_t;
  384 DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t);
  385 
  386 #define XEN_MC_physcpuinfo 3
  387 struct xen_mc_physcpuinfo {
  388     /* IN/OUT */
  389     uint32_t ncpus;
  390     uint32_t _pad0;
  391     /* OUT */
  392     XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info;
  393 };
  394 typedef struct xen_mc_physcpuinfo xen_mc_physcpuinfo_t;
  395 
  396 #define XEN_MC_msrinject    4
  397 #define MC_MSRINJ_MAXMSRS       8
  398 struct xen_mc_msrinject {
  399     /* IN */
  400     uint32_t mcinj_cpunr;           /* target processor id */
  401     uint32_t mcinj_flags;           /* see MC_MSRINJ_F_* below */
  402     uint32_t mcinj_count;           /* 0 .. count-1 in array are valid */
  403     domid_t  mcinj_domid;           /* valid only if MC_MSRINJ_F_GPADDR is
  404                                        present in mcinj_flags */
  405     uint16_t _pad0;
  406     xen_mcinfo_msr_t mcinj_msr[MC_MSRINJ_MAXMSRS];
  407 };
  408 typedef struct xen_mc_msrinject xen_mc_msrinject_t;
  409 
  410 /* Flags for mcinj_flags above; bits 16-31 are reserved */
  411 #define MC_MSRINJ_F_INTERPOSE   0x1
  412 #define MC_MSRINJ_F_GPADDR      0x2
  413 
  414 #define XEN_MC_mceinject    5
  415 struct xen_mc_mceinject {
  416     unsigned int mceinj_cpunr;      /* target processor id */
  417 };
  418 typedef struct xen_mc_mceinject xen_mc_mceinject_t;
  419 
  420 #if defined(__XEN__) || defined(__XEN_TOOLS__)
  421 #define XEN_MC_inject_v2        6
  422 #define XEN_MC_INJECT_TYPE_MASK     0x7
  423 #define XEN_MC_INJECT_TYPE_MCE      0x0
  424 #define XEN_MC_INJECT_TYPE_CMCI     0x1
  425 #define XEN_MC_INJECT_TYPE_LMCE     0x2
  426 
  427 #define XEN_MC_INJECT_CPU_BROADCAST 0x8
  428 
  429 struct xen_mc_inject_v2 {
  430     uint32_t flags;
  431     xenctl_bitmap_t cpumap;
  432 };
  433 typedef struct xen_mc_inject_v2 xen_mc_inject_v2_t;
  434 #endif
  435 
  436 struct xen_mc {
  437     uint32_t cmd;
  438     uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
  439     union {
  440         xen_mc_fetch_t             mc_fetch;
  441         xen_mc_notifydomain_t      mc_notifydomain;
  442         xen_mc_physcpuinfo_t       mc_physcpuinfo;
  443         xen_mc_msrinject_t         mc_msrinject;
  444         xen_mc_mceinject_t         mc_mceinject;
  445 #if defined(__XEN__) || defined(__XEN_TOOLS__)
  446         xen_mc_inject_v2_t         mc_inject_v2;
  447 #endif
  448     } u;
  449 };
  450 typedef struct xen_mc xen_mc_t;
  451 DEFINE_XEN_GUEST_HANDLE(xen_mc_t);
  452 
  453 #endif /* __ASSEMBLY__ */
  454 
  455 #endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */

Cache object: 227ec7adcea410d3775c55f6077323c0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.