From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Egger Subject: [PATCH] MCE: support cpu notification chain Date: Thu, 25 Oct 2012 15:54:36 +0200 Message-ID: <5089449C.7020700@amd.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080306090603060904090803" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org --------------080306090603060904090803 Content-Type: text/plain; charset="ISO-8859-15" Content-Transfer-Encoding: 7bit Add support for cpu notification chain. This is useful with nested virtualization when Xen runs as l1 hypervisor. This cleans up mce initialization cleanup as a side-effect. Signed-off-by: Christoph Egger -- ---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85689 Dornach b. Muenchen Geschaeftsfuehrer: Alberto Bozzo Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632 --------------080306090603060904090803 Content-Type: text/plain; charset="us-ascii"; name="xen_mce_init.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="xen_mce_init.diff" Content-Description: xen_mce_init.diff diff -r 7abb25095de0 xen/arch/x86/cpu/mcheck/mce.c --- a/xen/arch/x86/cpu/mcheck/mce.c Thu Oct 25 13:15:19 2012 +0200 +++ b/xen/arch/x86/cpu/mcheck/mce.c Thu Oct 25 14:20:49 2012 +0200 @@ -560,30 +560,6 @@ void mcheck_mca_clearbanks(struct mca_ba } } -static enum mcheck_type amd_mcheck_init(struct cpuinfo_x86 *ci) -{ - enum mcheck_type rc = mcheck_none; - - switch (ci->x86) { - case 6: - rc = amd_k7_mcheck_init(ci); - break; - - default: - /* Assume that machine check support is available. - * The minimum provided support is at least the K8. */ - case 0xf: - rc = amd_k8_mcheck_init(ci); - break; - - case 0x10 ... 0x17: - rc = amd_f10_mcheck_init(ci); - break; - } - - return rc; -} - /*check the existence of Machine Check*/ int mce_available(struct cpuinfo_x86 *c) { @@ -774,7 +750,7 @@ void mcheck_init(struct cpuinfo_x86 *c, switch (c->x86_vendor) { case X86_VENDOR_AMD: - inited = amd_mcheck_init(c); + inited = amd_mcheck_init(c, bsp); break; case X86_VENDOR_INTEL: diff -r 7abb25095de0 xen/arch/x86/cpu/mcheck/mce.h --- a/xen/arch/x86/cpu/mcheck/mce.h Thu Oct 25 13:15:19 2012 +0200 +++ b/xen/arch/x86/cpu/mcheck/mce.h Thu Oct 25 14:20:49 2012 +0200 @@ -39,10 +39,7 @@ enum mcheck_type { }; /* Init functions */ -enum mcheck_type amd_k7_mcheck_init(struct cpuinfo_x86 *c); -enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); -enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); - +enum mcheck_type amd_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); void intel_mcheck_timer(struct cpuinfo_x86 *c); diff -r 7abb25095de0 xen/arch/x86/cpu/mcheck/mce_amd.c --- a/xen/arch/x86/cpu/mcheck/mce_amd.c Thu Oct 25 13:15:19 2012 +0200 +++ b/xen/arch/x86/cpu/mcheck/mce_amd.c Thu Oct 25 14:20:49 2012 +0200 @@ -19,6 +19,7 @@ #include #include +#include #include @@ -98,3 +99,85 @@ mc_amd_addrcheck(uint64_t status, uint64 BUG(); return 0; } + +static void +amd_cpu_mcabank_free(unsigned int cpu) +{ + struct mca_banks *mb; + + mb = per_cpu(mce_clear_banks, cpu); + mcabanks_free(mb); +} + +static int +amd_cpu_mcabank_alloc(unsigned int cpu) +{ + struct mca_banks *mb; + + mb = mcabanks_alloc(); + if (!mb) + return -ENOMEM; + + per_cpu(mce_clear_banks, cpu) = mb; + return 0; +} + +static int +amd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + int rc = 0; + + switch (action) { + case CPU_UP_PREPARE: + rc = amd_cpu_mcabank_alloc(cpu); + break; + case CPU_DYING: + clear_in_cr4(X86_CR4_MCE); + break; + case CPU_UP_CANCELED: + case CPU_DEAD: + amd_cpu_mcabank_free(cpu); + break; + default: + break; + } + + return !rc ? NOTIFY_DONE : notifier_from_errno(rc); +} + +static struct notifier_block cpu_nfb = { + .notifier_call = amd_cpu_callback +}; + +enum mcheck_type +amd_mcheck_init(struct cpuinfo_x86 *ci, bool_t bsp) +{ + enum mcheck_type rc = mcheck_none; + + if (bsp) { + /* Early MCE initialization for BSP. */ + if ( amd_cpu_mcabank_alloc(0) ) + BUG(); + register_cpu_notifier(&cpu_nfb); + } + + switch (ci->x86) { + case 6: + rc = amd_k7_mcheck_init(ci); + break; + + default: + /* Assume that machine check support is available. + * The minimum provided support is at least the K8. */ + case 0xf: + rc = amd_k8_mcheck_init(ci); + break; + + case 0x10 ... 0x17: + rc = amd_f10_mcheck_init(ci); + break; + } + + return rc; +} diff -r 7abb25095de0 xen/arch/x86/cpu/mcheck/mce_amd.h --- a/xen/arch/x86/cpu/mcheck/mce_amd.h Thu Oct 25 13:15:19 2012 +0200 +++ b/xen/arch/x86/cpu/mcheck/mce_amd.h Thu Oct 25 14:20:49 2012 +0200 @@ -1,6 +1,10 @@ #ifndef _MCHECK_AMD_H #define _MCHECK_AMD_H +enum mcheck_type amd_k7_mcheck_init(struct cpuinfo_x86 *c); +enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); +enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); + int mc_amd_recoverable_scan(uint64_t status); int mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype); --------------080306090603060904090803 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --------------080306090603060904090803--