diff options
Diffstat (limited to 'drivers/xen/xenbus')
-rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 131dec04794e..acedeabe589c 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -48,6 +48,7 @@ #include <xen/xenbus.h> #include <xen/xen.h> #include "xenbus_comms.h" +#include <asm/xen/hypervisor.h> struct xs_stored_msg { struct list_head list; @@ -618,7 +619,26 @@ static struct xenbus_watch *find_watch(const char *token) return NULL; } +/* + * Certain older XenBus toolstack cannot handle reading values that are + * not populated. Some Xen 3.4 installation are incapable of doing this + * so if we are running on anything older than 4 do not attempt to read + * control/platform-feature-xs_reset_watches. + */ +static bool xen_strict_xenbus_quirk(void) +{ +#ifdef CONFIG_X86 + uint32_t eax, ebx, ecx, edx, base; + + base = xen_cpuid_base(); + cpuid(base + 1, &eax, &ebx, &ecx, &edx); + if ((eax >> 16) < 4) + return true; +#endif + return false; + +} static void xs_reset_watches(void) { int err, supported = 0; @@ -626,6 +646,9 @@ static void xs_reset_watches(void) if (!xen_hvm_domain() || xen_initial_domain()) return; + if (xen_strict_xenbus_quirk()) + return; + err = xenbus_scanf(XBT_NIL, "control", "platform-feature-xs_reset_watches", "%d", &supported); if (err != 1 || !supported) |