Rig the hypercall callback page such that when the kernel happens to

run without a XEN domain loader having previously overwritten the
hypercall page with its hypercall trampoline machine code, we still
get to detect its presence by calling the xen_version hypercall stub.

We use this hack to detect the presence or absence of the hypervisor,
without relying on the MSR support on HVM domains.

This works as an added sanity check that the hypercall page
registration has indeed succeeded in HVM mode.
This commit is contained in:
cherry 2019-02-13 05:36:59 +00:00
parent 471cf8eaf8
commit a141ce0848
2 changed files with 31 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.176 2019/02/11 14:59:32 cherry Exp $ */
/* $NetBSD: locore.S,v 1.177 2019/02/13 05:36:59 cherry Exp $ */
/*
* Copyright-o-rama!
@ -278,6 +278,8 @@
#define __ASSEMBLY__
#include <xen/include/public/elfnote.h>
#include <xen/include/public/xen.h>
#endif /* XEN */
#ifdef XENPV
#define ELFNOTE(name, type, desctype, descdata...) \
.pushsection .note.name ; \
@ -312,7 +314,6 @@
ELFNOTE(Xen, XEN_ELFNOTE_BSD_SYMTAB, .asciz, "yes")
#endif
#endif /* XENPV */
#endif /* XEN */
/*
* Initialization
@ -979,9 +980,12 @@ END(start)
#if defined(XEN)
/* space for the hypercall call page */
#define HYPERCALL_PAGE_OFFSET 0x1000
.org HYPERCALL_PAGE_OFFSET
ENTRY(hypercall_page)
.skip 0x1000
.align HYPERCALL_PAGE_OFFSET
ENTRY(hypercall_page) /* Returns -1, on HYPERVISOR_xen_version() */
.skip (__HYPERVISOR_xen_version*32), 0x90
movq $-1, %rax
retq
.align HYPERCALL_PAGE_OFFSET, 0x90
END(hypercall_page)
#endif /* XEN */

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.163 2019/02/11 14:59:32 cherry Exp $ */
/* $NetBSD: locore.S,v 1.164 2019/02/13 05:36:59 cherry Exp $ */
/*
* Copyright-o-rama!
@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.163 2019/02/11 14:59:32 cherry Exp $");
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.164 2019/02/13 05:36:59 cherry Exp $");
#include "opt_copy_symtab.h"
#include "opt_ddb.h"
@ -242,6 +242,20 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.163 2019/02/11 14:59:32 cherry Exp $");
loop 1b ;
#ifdef XEN
/*
* Unfortunately, the Xen codebase uses nonstandard preprocessing tools.
* See: https://xenbits.xen.org/gitweb/?p=xen.git&a=search&h=HEAD&st=grep&s=__UnDeF__
* for a fine selection of examples.
*
* What this means for us here is that we can't include the standard
* xen.h header in assembler code.
*
* So we have to manually define, and keep track of the values we need, ourselves.
*/
#define __HYPERVISOR_xen_version 17
#endif /* XEN */
#ifdef XENPV
/*
* Xen guest identifier and loader selection
@ -916,9 +930,12 @@ END(start)
#if defined(XEN)
/* space for the hypercall call page */
#define HYPERCALL_PAGE_OFFSET 0x1000
.org HYPERCALL_PAGE_OFFSET
ENTRY(hypercall_page)
.skip 0x1000
.align HYPERCALL_PAGE_OFFSET
ENTRY(hypercall_page) /* Returns -1, on HYPERVISOR_xen_version() */
.skip (__HYPERVISOR_xen_version*32), 0x90
movl $-1, %eax
retl
.align HYPERCALL_PAGE_OFFSET, 0x90
END(hypercall_page)
#ifdef XENPV