xen/hvc: If we use xen_raw_printk let it also work on HVM guests.

The xen_raw_printk works great for debugging purposes. We use
for PV guests and we can also use it for HVM guests.

However, for HVM guests we have a fallback of using the 0xe9
port in case the hypervisor does not support an HVM guest of
using the console_io hypercall. As such lets use 0xe9 during
early bootup, and once the hyper-page is setup and if the
console_io hypercall is supported - use that. Otherwise we
will fallback to using the 0xe9 after early bootup.

We also alter the return value for dom0_write_console to return
an error value instead of zero. The HVC API has been supporting
returning error values for quite some time.

P.S.
To use (and to see the output in the Xen ring buffer) one has to build
the hypervisor with 'debug=y'.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: ifdef xen_cpuid_base as it is X86 specific]
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index e61c36c..6458c9f 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -183,7 +183,7 @@
 {
 	int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
 	if (rc < 0)
-		return 0;
+		return rc;
 
 	return len;
 }
@@ -641,7 +641,22 @@
 
 void xen_raw_console_write(const char *str)
 {
-	dom0_write_console(0, str, strlen(str));
+	ssize_t len = strlen(str);
+	int rc = 0;
+
+	if (xen_domain()) {
+		rc = dom0_write_console(0, str, len);
+#ifdef CONFIG_X86
+		if (rc == -ENOSYS && xen_hvm_domain())
+			goto outb_print;
+
+	} else if (xen_cpuid_base()) {
+		int i;
+outb_print:
+		for (i = 0; i < len; i++)
+			outb(str[i], 0xe9);
+#endif
+	}
 }
 
 void xen_raw_printk(const char *fmt, ...)