summaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2018-11-23 11:24:51 -0500
committerJuergen Gross <jgross@suse.com>2018-11-29 11:53:16 -0500
commita7b403104e17209ea71eea59d4a71bf9e0d8cb83 (patch)
treebd7131d6f10ab30b62d72b904fa2f76e09875416 /arch/x86/xen
parentf2a5fef1248beccacec0deecb67c1be693d72ae6 (diff)
xen/x86: add diagnostic printout to xen_mc_flush() in case of error
Failure of an element of a Xen multicall is signalled via a WARN() only if the kernel is compiled with MC_DEBUG. It is impossible to know which element failed and why it did so. Change that by printing the related information even without MC_DEBUG, even if maybe in some limited form (e.g. without information which caller produced the failing element). Move the printing out of the switch statement in order to have the same information for a single call. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: Juergen Gross <jgross@suse.com>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/multicalls.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c
index 2bce7958ce8b..0766a08bdf45 100644
--- a/arch/x86/xen/multicalls.c
+++ b/arch/x86/xen/multicalls.c
@@ -69,6 +69,11 @@ void xen_mc_flush(void)
69 69
70 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); 70 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
71 71
72#if MC_DEBUG
73 memcpy(b->debug, b->entries,
74 b->mcidx * sizeof(struct multicall_entry));
75#endif
76
72 switch (b->mcidx) { 77 switch (b->mcidx) {
73 case 0: 78 case 0:
74 /* no-op */ 79 /* no-op */
@@ -87,32 +92,34 @@ void xen_mc_flush(void)
87 break; 92 break;
88 93
89 default: 94 default:
90#if MC_DEBUG
91 memcpy(b->debug, b->entries,
92 b->mcidx * sizeof(struct multicall_entry));
93#endif
94
95 if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0) 95 if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0)
96 BUG(); 96 BUG();
97 for (i = 0; i < b->mcidx; i++) 97 for (i = 0; i < b->mcidx; i++)
98 if (b->entries[i].result < 0) 98 if (b->entries[i].result < 0)
99 ret++; 99 ret++;
100 }
100 101
102 if (WARN_ON(ret)) {
103 pr_err("%d of %d multicall(s) failed: cpu %d\n",
104 ret, b->mcidx, smp_processor_id());
105 for (i = 0; i < b->mcidx; i++) {
106 if (b->entries[i].result < 0) {
101#if MC_DEBUG 107#if MC_DEBUG
102 if (ret) { 108 pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pF\n",
103 printk(KERN_ERR "%d multicall(s) failed: cpu %d\n", 109 i + 1,
104 ret, smp_processor_id());
105 dump_stack();
106 for (i = 0; i < b->mcidx; i++) {
107 printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n",
108 i+1, b->mcidx,
109 b->debug[i].op, 110 b->debug[i].op,
110 b->debug[i].args[0], 111 b->debug[i].args[0],
111 b->entries[i].result, 112 b->entries[i].result,
112 b->caller[i]); 113 b->caller[i]);
114#else
115 pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n",
116 i + 1,
117 b->entries[i].op,
118 b->entries[i].args[0],
119 b->entries[i].result);
120#endif
113 } 121 }
114 } 122 }
115#endif
116 } 123 }
117 124
118 b->mcidx = 0; 125 b->mcidx = 0;
@@ -126,8 +133,6 @@ void xen_mc_flush(void)
126 b->cbidx = 0; 133 b->cbidx = 0;
127 134
128 local_irq_restore(flags); 135 local_irq_restore(flags);
129
130 WARN_ON(ret);
131} 136}
132 137
133struct multicall_space __xen_mc_entry(size_t args) 138struct multicall_space __xen_mc_entry(size_t args)