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/xen/interface/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 
   92 #ifndef __ASSEMBLY__
   93 
   94 #define VIRQ_MCA VIRQ_ARCH_0 /* G. (DOM0) Machine Check Architecture */
   95 
   96 /*
   97  * Machine Check Architecure:
   98  * structs are read-only and used to report all kinds of
   99  * correctable and uncorrectable errors detected by the HW.
  100  * Dom0 and DomU: register a handler to get notified.
  101  * Dom0 only: Correctable errors are reported via VIRQ_MCA
  102  * Dom0 and DomU: Uncorrectable errors are reported via nmi handlers
  103  */
  104 #define MC_TYPE_GLOBAL          0
  105 #define MC_TYPE_BANK            1
  106 #define MC_TYPE_EXTENDED        2
  107 #define MC_TYPE_RECOVERY        3
  108 
  109 struct mcinfo_common {
  110     uint16_t type;      /* structure type */
  111     uint16_t size;      /* size of this struct in bytes */
  112 };
  113 
  114 
  115 #define MC_FLAG_CORRECTABLE     (1 << 0)
  116 #define MC_FLAG_UNCORRECTABLE   (1 << 1)
  117 #define MC_FLAG_RECOVERABLE     (1 << 2)
  118 #define MC_FLAG_POLLED          (1 << 3)
  119 #define MC_FLAG_RESET           (1 << 4)
  120 #define MC_FLAG_CMCI            (1 << 5)
  121 #define MC_FLAG_MCE             (1 << 6)
  122 /* contains global x86 mc information */
  123 struct mcinfo_global {
  124     struct mcinfo_common common;
  125 
  126     /* running domain at the time in error (most likely the impacted one) */
  127     uint16_t mc_domid;
  128     uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
  129     uint32_t mc_socketid; /* physical socket of the physical core */
  130     uint16_t mc_coreid; /* physical impacted core */
  131     uint16_t mc_core_threadid; /* core thread of physical core */
  132     uint32_t mc_apicid;
  133     uint32_t mc_flags;
  134     uint64_t mc_gstatus; /* global status */
  135 };
  136 
  137 /* contains bank local x86 mc information */
  138 struct mcinfo_bank {
  139     struct mcinfo_common common;
  140 
  141     uint16_t mc_bank; /* bank nr */
  142     uint16_t mc_domid; /* Usecase 5: domain referenced by mc_addr on dom0
  143                         * and if mc_addr is valid. Never valid on DomU. */
  144     uint64_t mc_status; /* bank status */
  145     uint64_t mc_addr;   /* bank address, only valid
  146                          * if addr bit is set in mc_status */
  147     uint64_t mc_misc;
  148     uint64_t mc_ctrl2;
  149     uint64_t mc_tsc;
  150 };
  151 
  152 
  153 struct mcinfo_msr {
  154     uint64_t reg;   /* MSR */
  155     uint64_t value; /* MSR value */
  156 };
  157 
  158 /* contains mc information from other
  159  * or additional mc MSRs */ 
  160 struct mcinfo_extended {
  161     struct mcinfo_common common;
  162 
  163     /* You can fill up to five registers.
  164      * If you need more, then use this structure
  165      * multiple times. */
  166 
  167     uint32_t mc_msrs; /* Number of msr with valid values. */
  168     /*
  169      * Currently Intel extended MSR (32/64) include all gp registers
  170      * and E(R)FLAGS, E(R)IP, E(R)MISC, up to 11/19 of them might be
  171      * useful at present. So expand this array to 16/32 to leave room.
  172      */
  173     struct mcinfo_msr mc_msr[sizeof(void *) * 4];
  174 };
  175 
  176 /* Recovery Action flags. Giving recovery result information to DOM0 */
  177 
  178 /* Xen takes successful recovery action, the error is recovered */
  179 #define REC_ACTION_RECOVERED (0x1 << 0)
  180 /* No action is performed by XEN */
  181 #define REC_ACTION_NONE (0x1 << 1)
  182 /* It's possible DOM0 might take action ownership in some case */
  183 #define REC_ACTION_NEED_RESET (0x1 << 2)
  184 
  185 /* Different Recovery Action types, if the action is performed successfully,
  186  * REC_ACTION_RECOVERED flag will be returned.
  187  */
  188 
  189 /* Page Offline Action */
  190 #define MC_ACTION_PAGE_OFFLINE (0x1 << 0)
  191 /* CPU offline Action */
  192 #define MC_ACTION_CPU_OFFLINE (0x1 << 1)
  193 /* L3 cache disable Action */
  194 #define MC_ACTION_CACHE_SHRINK (0x1 << 2)
  195 
  196 /* Below interface used between XEN/DOM0 for passing XEN's recovery action 
  197  * information to DOM0. 
  198  * usage Senario: After offlining broken page, XEN might pass its page offline
  199  * recovery action result to DOM0. DOM0 will save the information in 
  200  * non-volatile memory for further proactive actions, such as offlining the
  201  * easy broken page earlier when doing next reboot.
  202 */
  203 struct page_offline_action
  204 {
  205     /* Params for passing the offlined page number to DOM0 */
  206     uint64_t mfn;
  207     uint64_t status;
  208 };
  209 
  210 struct cpu_offline_action
  211 {
  212     /* Params for passing the identity of the offlined CPU to DOM0 */
  213     uint32_t mc_socketid;
  214     uint16_t mc_coreid;
  215     uint16_t mc_core_threadid;
  216 };
  217 
  218 #define MAX_UNION_SIZE 16
  219 struct mcinfo_recovery
  220 {
  221     struct mcinfo_common common;
  222     uint16_t mc_bank; /* bank nr */
  223     uint8_t action_flags;
  224     uint8_t action_types;
  225     union {
  226         struct page_offline_action page_retire;
  227         struct cpu_offline_action cpu_offline;
  228         uint8_t pad[MAX_UNION_SIZE];
  229     } action_info;
  230 };
  231 
  232 
  233 #define MCINFO_HYPERCALLSIZE    1024
  234 #define MCINFO_MAXSIZE          768
  235 
  236 #define MCINFO_FLAGS_UNCOMPLETE 0x1
  237 struct mc_info {
  238     /* Number of mcinfo_* entries in mi_data */
  239     uint32_t mi_nentries;
  240     uint32_t flags;
  241     uint64_t mi_data[(MCINFO_MAXSIZE - 1) / 8];
  242 };
  243 typedef struct mc_info mc_info_t;
  244 DEFINE_XEN_GUEST_HANDLE(mc_info_t);
  245 
  246 #define __MC_MSR_ARRAYSIZE 8
  247 #define __MC_NMSRS 1
  248 #define MC_NCAPS        7       /* 7 CPU feature flag words */
  249 #define MC_CAPS_STD_EDX 0       /* cpuid level 0x00000001 (%edx) */
  250 #define MC_CAPS_AMD_EDX 1       /* cpuid level 0x80000001 (%edx) */
  251 #define MC_CAPS_TM      2       /* cpuid level 0x80860001 (TransMeta) */
  252 #define MC_CAPS_LINUX   3       /* Linux-defined */
  253 #define MC_CAPS_STD_ECX 4       /* cpuid level 0x00000001 (%ecx) */
  254 #define MC_CAPS_VIA     5       /* cpuid level 0xc0000001 */
  255 #define MC_CAPS_AMD_ECX 6       /* cpuid level 0x80000001 (%ecx) */
  256 
  257 struct mcinfo_logical_cpu {
  258     uint32_t mc_cpunr;          
  259     uint32_t mc_chipid; 
  260     uint16_t mc_coreid;
  261     uint16_t mc_threadid;
  262     uint32_t mc_apicid;
  263     uint32_t mc_clusterid;
  264     uint32_t mc_ncores;
  265     uint32_t mc_ncores_active;
  266     uint32_t mc_nthreads;
  267     int32_t mc_cpuid_level;
  268     uint32_t mc_family;
  269     uint32_t mc_vendor;
  270     uint32_t mc_model;
  271     uint32_t mc_step;
  272     char mc_vendorid[16];
  273     char mc_brandid[64];
  274     uint32_t mc_cpu_caps[MC_NCAPS];
  275     uint32_t mc_cache_size;
  276     uint32_t mc_cache_alignment;
  277     int32_t mc_nmsrvals;
  278     struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE];
  279 };
  280 typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t;
  281 DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t);
  282 
  283 
  284 /* 
  285  * OS's should use these instead of writing their own lookup function
  286  * each with its own bugs and drawbacks.
  287  * We use macros instead of static inline functions to allow guests
  288  * to include this header in assembly files (*.S).
  289  */
  290 /* Prototype:
  291  *    uint32_t x86_mcinfo_nentries(struct mc_info *mi);
  292  */
  293 #define x86_mcinfo_nentries(_mi)    \
  294     (_mi)->mi_nentries
  295 /* Prototype:
  296  *    struct mcinfo_common *x86_mcinfo_first(struct mc_info *mi);
  297  */
  298 #define x86_mcinfo_first(_mi)       \
  299     ((struct mcinfo_common *)(_mi)->mi_data)
  300 /* Prototype:
  301  *    struct mcinfo_common *x86_mcinfo_next(struct mcinfo_common *mic);
  302  */
  303 #define x86_mcinfo_next(_mic)       \
  304     ((struct mcinfo_common *)((uint8_t *)(_mic) + (_mic)->size))
  305 
  306 /* Prototype:
  307  *    void x86_mcinfo_lookup(void *ret, struct mc_info *mi, uint16_t type);
  308  */
  309 #define x86_mcinfo_lookup(_ret, _mi, _type)    \
  310     do {                                                        \
  311         uint32_t found, i;                                      \
  312         struct mcinfo_common *_mic;                             \
  313                                                                 \
  314         found = 0;                                              \
  315         (_ret) = NULL;                                          \
  316         if (_mi == NULL) break;                                 \
  317         _mic = x86_mcinfo_first(_mi);                           \
  318         for (i = 0; i < x86_mcinfo_nentries(_mi); i++) {        \
  319             if (_mic->type == (_type)) {                        \
  320                 found = 1;                                      \
  321                 break;                                          \
  322             }                                                   \
  323             _mic = x86_mcinfo_next(_mic);                       \
  324         }                                                       \
  325         (_ret) = found ? _mic : NULL;                           \
  326     } while (0)
  327 
  328 
  329 /* Usecase 1
  330  * Register machine check trap callback handler
  331  *    (already done via "set_trap_table" hypercall)
  332  */
  333 
  334 /* Usecase 2
  335  * Dom0 registers machine check event callback handler
  336  * done by EVTCHNOP_bind_virq
  337  */
  338 
  339 /* Usecase 3
  340  * Fetch machine check data from hypervisor.
  341  * Note, this hypercall is special, because both Dom0 and DomU must use this.
  342  */
  343 #define XEN_MC_fetch            1
  344 struct xen_mc_fetch {
  345     /* IN/OUT variables. */
  346     uint32_t flags;     /* IN: XEN_MC_NONURGENT, XEN_MC_URGENT,
  347                            XEN_MC_ACK if ack'ing an earlier fetch */
  348                         /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED,
  349                            XEN_MC_NODATA, XEN_MC_NOMATCH */
  350     uint32_t _pad0;
  351     uint64_t fetch_id;  /* OUT: id for ack, IN: id we are ack'ing */
  352 
  353     /* OUT variables. */
  354     XEN_GUEST_HANDLE(mc_info_t) data;
  355 };
  356 typedef struct xen_mc_fetch xen_mc_fetch_t;
  357 DEFINE_XEN_GUEST_HANDLE(xen_mc_fetch_t);
  358 
  359 
  360 /* Usecase 4
  361  * This tells the hypervisor to notify a DomU about the machine check error
  362  */
  363 #define XEN_MC_notifydomain     2
  364 struct xen_mc_notifydomain {
  365     /* IN variables. */
  366     uint16_t mc_domid;    /* The unprivileged domain to notify. */
  367     uint16_t mc_vcpuid;   /* The vcpu in mc_domid to notify.
  368                            * Usually echo'd value from the fetch hypercall. */
  369 
  370     /* IN/OUT variables. */
  371     uint32_t flags;
  372 
  373 /* IN: XEN_MC_CORRECTABLE, XEN_MC_TRAP */
  374 /* OUT: XEN_MC_OK, XEN_MC_CANNOTHANDLE, XEN_MC_NOTDELIVERED, XEN_MC_NOMATCH */
  375 };
  376 typedef struct xen_mc_notifydomain xen_mc_notifydomain_t;
  377 DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t);
  378 
  379 #define XEN_MC_physcpuinfo 3
  380 struct xen_mc_physcpuinfo {
  381         /* IN/OUT */
  382         uint32_t ncpus;
  383         uint32_t _pad0;
  384         /* OUT */
  385         XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info;
  386 };
  387 
  388 #define XEN_MC_msrinject    4
  389 #define MC_MSRINJ_MAXMSRS       8
  390 struct xen_mc_msrinject {
  391        /* IN */
  392         uint32_t mcinj_cpunr;           /* target processor id */
  393         uint32_t mcinj_flags;           /* see MC_MSRINJ_F_* below */
  394         uint32_t mcinj_count;           /* 0 .. count-1 in array are valid */
  395         uint32_t _pad0;
  396         struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS];
  397 };
  398 
  399 /* Flags for mcinj_flags above; bits 16-31 are reserved */
  400 #define MC_MSRINJ_F_INTERPOSE   0x1
  401 
  402 #define XEN_MC_mceinject    5
  403 struct xen_mc_mceinject {
  404         unsigned int mceinj_cpunr;      /* target processor id */
  405 };
  406 
  407 #if defined(__XEN__) || defined(__XEN_TOOLS__)
  408 #define XEN_MC_inject_v2        6
  409 #define XEN_MC_INJECT_TYPE_MASK     0x7
  410 #define XEN_MC_INJECT_TYPE_MCE      0x0
  411 #define XEN_MC_INJECT_TYPE_CMCI     0x1
  412 
  413 #define XEN_MC_INJECT_CPU_BROADCAST 0x8
  414 
  415 struct xen_mc_inject_v2 {
  416         uint32_t flags;
  417         struct xenctl_cpumap cpumap;
  418 };
  419 #endif
  420 
  421 struct xen_mc {
  422     uint32_t cmd;
  423     uint32_t interface_version; /* XEN_MCA_INTERFACE_VERSION */
  424     union {
  425         struct xen_mc_fetch        mc_fetch;
  426         struct xen_mc_notifydomain mc_notifydomain;
  427         struct xen_mc_physcpuinfo  mc_physcpuinfo;
  428         struct xen_mc_msrinject    mc_msrinject;
  429         struct xen_mc_mceinject    mc_mceinject;
  430 #if defined(__XEN__) || defined(__XEN_TOOLS__)
  431         struct xen_mc_inject_v2    mc_inject_v2;
  432 #endif
  433     } u;
  434 };
  435 typedef struct xen_mc xen_mc_t;
  436 DEFINE_XEN_GUEST_HANDLE(xen_mc_t);
  437 
  438 #endif /* __ASSEMBLY__ */
  439 
  440 #endif /* __XEN_PUBLIC_ARCH_X86_MCA_H__ */

Cache object: 52ba8ae9ba330dd134903a602c226280


[ 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.