lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190509172540.12398-7-ankur.a.arora@oracle.com>
Date:   Thu,  9 May 2019 10:25:30 -0700
From:   Ankur Arora <ankur.a.arora@...cle.com>
To:     linux-kernel@...r.kernel.org, xen-devel@...ts.xenproject.org
Cc:     jgross@...e.com, pbonzini@...hat.com, boris.ostrovsky@...cle.com,
        konrad.wilk@...cle.com, sstabellini@...nel.org,
        joao.m.martins@...cle.com, ankur.a.arora@...cle.com
Subject: [RFC PATCH 06/16] x86/xen: add shared_info support to xenhost_t

HYPERVISOR_shared_info is used for irq/evtchn communication between the
guest and the host. Abstract out the setup/reset in xenhost_t such that
nested configurations can use both xenhosts simultaneously.

In addition to irq/evtchn communication, shared_info is also used for
pvclock and p2m related state. For both of those, remote xenhost is not
of interest so we only use the default xenhost.

Signed-off-by: Ankur Arora <ankur.a.arora@...cle.com>
---
 arch/x86/include/asm/xen/hypervisor.h |  1 -
 arch/x86/xen/enlighten.c              | 10 ++-----
 arch/x86/xen/enlighten_hvm.c          | 38 +++++++++++++++++---------
 arch/x86/xen/enlighten_pv.c           | 28 ++++++++++++++++---
 arch/x86/xen/p2m.c                    | 24 ++++++++---------
 arch/x86/xen/suspend_hvm.c            |  6 ++++-
 arch/x86/xen/suspend_pv.c             | 14 +++++-----
 arch/x86/xen/time.c                   |  4 +--
 arch/x86/xen/xen-ops.h                |  2 --
 arch/x86/xen/xenhost.c                | 13 ++++++++-
 drivers/xen/events/events_2l.c        | 16 +++++------
 include/xen/xenhost.h                 | 39 +++++++++++++++++++++++++++
 12 files changed, 138 insertions(+), 57 deletions(-)

diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index 6c4cdcdf997d..3e6bd455fbd0 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -33,7 +33,6 @@
 #ifndef _ASM_X86_XEN_HYPERVISOR_H
 #define _ASM_X86_XEN_HYPERVISOR_H
 
-extern struct shared_info *HYPERVISOR_shared_info;
 extern struct start_info *xen_start_info;
 
 #include <asm/processor.h>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index f88bb14da3f2..20e0de844442 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -72,12 +72,6 @@ EXPORT_SYMBOL_GPL(xen_have_vector_callback);
 uint32_t xen_start_flags __attribute__((section(".data"))) = 0;
 EXPORT_SYMBOL(xen_start_flags);
 
-/*
- * Point at some empty memory to start with. We map the real shared_info
- * page as soon as fixmap is up and running.
- */
-struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
-
 /*
  * Flag to determine whether vcpu info placement is available on all
  * VCPUs.  We assume it is to start with, and then set it to zero on
@@ -187,7 +181,7 @@ void xen_vcpu_info_reset(int cpu)
 {
 	if (xen_vcpu_nr(cpu) < MAX_VIRT_CPUS) {
 		per_cpu(xen_vcpu, cpu) =
-			&HYPERVISOR_shared_info->vcpu_info[xen_vcpu_nr(cpu)];
+			&xh_default->HYPERVISOR_shared_info->vcpu_info[xen_vcpu_nr(cpu)];
 	} else {
 		/* Set to NULL so that if somebody accesses it we get an OOPS */
 		per_cpu(xen_vcpu, cpu) = NULL;
@@ -200,7 +194,7 @@ int xen_vcpu_setup(int cpu)
 	int err;
 	struct vcpu_info *vcpup;
 
-	BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
+	BUG_ON(xh_default->HYPERVISOR_shared_info == &xen_dummy_shared_info);
 
 	/*
 	 * This path is called on PVHVM at bootup (xen_hvm_smp_prepare_boot_cpu)
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index a118b61a1a8a..0e53363f9d1f 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -26,21 +26,25 @@
 #include "mmu.h"
 #include "smp.h"
 
-static unsigned long shared_info_pfn;
-
-void xen_hvm_init_shared_info(void)
+static void xen_hvm_init_shared_info(xenhost_t *xh)
 {
 	struct xen_add_to_physmap xatp;
 
 	xatp.domid = DOMID_SELF;
 	xatp.idx = 0;
 	xatp.space = XENMAPSPACE_shared_info;
-	xatp.gpfn = shared_info_pfn;
-	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+	xatp.gpfn = xh->shared_info_pfn;
+	if (hypervisor_memory_op(xh, XENMEM_add_to_physmap, &xatp))
 		BUG();
 }
 
-static void __init reserve_shared_info(void)
+static void xen_hvm_reset_shared_info(xenhost_t *xh)
+{
+	early_memunmap(xh->HYPERVISOR_shared_info, PAGE_SIZE);
+	xh->HYPERVISOR_shared_info = __va(PFN_PHYS(xh->shared_info_pfn));
+}
+
+static void __init reserve_shared_info(xenhost_t *xh)
 {
 	u64 pa;
 
@@ -58,16 +62,18 @@ static void __init reserve_shared_info(void)
 	     pa += PAGE_SIZE)
 		;
 
-	shared_info_pfn = PHYS_PFN(pa);
+	xh->shared_info_pfn = PHYS_PFN(pa);
 
 	memblock_reserve(pa, PAGE_SIZE);
-	HYPERVISOR_shared_info = early_memremap(pa, PAGE_SIZE);
+	xh->HYPERVISOR_shared_info = early_memremap(pa, PAGE_SIZE);
 }
 
 static void __init xen_hvm_init_mem_mapping(void)
 {
-	early_memunmap(HYPERVISOR_shared_info, PAGE_SIZE);
-	HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn));
+	xenhost_t **xh;
+
+	for_each_xenhost(xh)
+		xenhost_reset_shared_info(*xh);
 
 	/*
 	 * The virtual address of the shared_info page has changed, so
@@ -79,6 +85,7 @@ static void __init xen_hvm_init_mem_mapping(void)
 	 *
 	 * It is, in any case, bad to have a stale vcpu_info pointer
 	 * so reset it now.
+	 * For now, this uses xh_default implictly.
 	 */
 	xen_vcpu_info_reset(0);
 }
@@ -99,6 +106,8 @@ void xen_hvm_setup_hypercall_page(xenhost_t *xh)
 xenhost_ops_t xh_hvm_ops = {
 	.cpuid_base = xen_pv_cpuid_base,
 	.setup_hypercall_page = xen_hvm_setup_hypercall_page,
+	.setup_shared_info = xen_hvm_init_shared_info,
+	.reset_shared_info = xen_hvm_reset_shared_info,
 };
 
 xenhost_ops_t xh_hvm_nested_ops = {
@@ -204,6 +213,8 @@ static int xen_cpu_dead_hvm(unsigned int cpu)
 
 static void __init xen_hvm_guest_init(void)
 {
+	xenhost_t **xh;
+
 	if (xen_pv_domain())
 		return;
 	/*
@@ -215,13 +226,16 @@ static void __init xen_hvm_guest_init(void)
 
 	init_hvm_pv_info();
 
-	reserve_shared_info();
-	xen_hvm_init_shared_info();
+	for_each_xenhost(xh) {
+		reserve_shared_info(*xh);
+		xenhost_setup_shared_info(*xh);
+	}
 
 	/*
 	 * xen_vcpu is a pointer to the vcpu_info struct in the shared_info
 	 * page, we use it in the event channel upcall and in some pvclock
 	 * related functions.
+	 * For now, this uses xh_default implictly.
 	 */
 	xen_vcpu_info_reset(0);
 
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index 484968ff16a4..1a9eded4b76b 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -122,12 +122,15 @@ static void __init xen_banner(void)
 
 static void __init xen_pv_init_platform(void)
 {
+	xenhost_t **xh;
+
 	populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
 
-	set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
-	HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
+	for_each_xenhost(xh)
+		xenhost_setup_shared_info(*xh);
 
 	/* xen clock uses per-cpu vcpu_info, need to init it for boot cpu */
+	/* For now this uses xh_default implicitly. */
 	xen_vcpu_info_reset(0);
 
 	/* pvclock is in shared info area */
@@ -1109,10 +1112,10 @@ static unsigned char xen_get_nmi_reason(void)
 
 	/* Construct a value which looks like it came from port 0x61. */
 	if (test_bit(_XEN_NMIREASON_io_error,
-		     &HYPERVISOR_shared_info->arch.nmi_reason))
+		     &xh_default->HYPERVISOR_shared_info->arch.nmi_reason))
 		reason |= NMI_REASON_IOCHK;
 	if (test_bit(_XEN_NMIREASON_pci_serr,
-		     &HYPERVISOR_shared_info->arch.nmi_reason))
+		     &xh_default->HYPERVISOR_shared_info->arch.nmi_reason))
 		reason |= NMI_REASON_SERR;
 
 	return reason;
@@ -1205,10 +1208,27 @@ static void xen_pv_setup_hypercall_page(xenhost_t *xh)
 	xh->hypercall_page = xen_hypercall_page;
 }
 
+static void xen_pv_setup_shared_info(xenhost_t *xh)
+{
+	set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
+	xh->HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
+}
+
+static void xen_pv_reset_shared_info(xenhost_t *xh)
+{
+	xh->HYPERVISOR_shared_info = &xen_dummy_shared_info;
+	if (hypervisor_update_va_mapping(xh, fix_to_virt(FIX_PARAVIRT_BOOTMAP),
+						 __pte_ma(0), 0))
+		BUG();
+}
+
 xenhost_ops_t xh_pv_ops = {
 	.cpuid_base = xen_pv_cpuid_base,
 
 	.setup_hypercall_page = xen_pv_setup_hypercall_page,
+
+	.setup_shared_info = xen_pv_setup_shared_info,
+	.reset_shared_info = xen_pv_reset_shared_info,
 };
 
 xenhost_ops_t xh_pv_nested_ops = {
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 055e37e43541..8200a9582246 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -270,17 +270,17 @@ void __ref xen_build_mfn_list_list(void)
 
 void xen_setup_mfn_list_list(void)
 {
-	BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
+	BUG_ON(xh_default->HYPERVISOR_shared_info == &xen_dummy_shared_info);
 
 	if (xen_start_info->flags & SIF_VIRT_P2M_4TOOLS)
-		HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = ~0UL;
+		xh_default->HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = ~0UL;
 	else
-		HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+		xh_default->HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
 			virt_to_mfn(p2m_top_mfn);
-	HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
-	HYPERVISOR_shared_info->arch.p2m_generation = 0;
-	HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr;
-	HYPERVISOR_shared_info->arch.p2m_cr3 =
+	xh_default->HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
+	xh_default->HYPERVISOR_shared_info->arch.p2m_generation = 0;
+	xh_default->HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr;
+	xh_default->HYPERVISOR_shared_info->arch.p2m_cr3 =
 		xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
 }
 
@@ -496,12 +496,12 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
 
 		ptechk = lookup_address(vaddr, &level);
 		if (ptechk == pte_pg) {
-			HYPERVISOR_shared_info->arch.p2m_generation++;
+			xh_default->HYPERVISOR_shared_info->arch.p2m_generation++;
 			wmb(); /* Tools are synchronizing via p2m_generation. */
 			set_pmd(pmdp,
 				__pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
 			wmb(); /* Tools are synchronizing via p2m_generation. */
-			HYPERVISOR_shared_info->arch.p2m_generation++;
+			xh_default->HYPERVISOR_shared_info->arch.p2m_generation++;
 			pte_newpg[i] = NULL;
 		}
 
@@ -597,12 +597,12 @@ int xen_alloc_p2m_entry(unsigned long pfn)
 		spin_lock_irqsave(&p2m_update_lock, flags);
 
 		if (pte_pfn(*ptep) == p2m_pfn) {
-			HYPERVISOR_shared_info->arch.p2m_generation++;
+			xh_default->HYPERVISOR_shared_info->arch.p2m_generation++;
 			wmb(); /* Tools are synchronizing via p2m_generation. */
 			set_pte(ptep,
 				pfn_pte(PFN_DOWN(__pa(p2m)), PAGE_KERNEL));
 			wmb(); /* Tools are synchronizing via p2m_generation. */
-			HYPERVISOR_shared_info->arch.p2m_generation++;
+			xh_default->HYPERVISOR_shared_info->arch.p2m_generation++;
 			if (mid_mfn)
 				mid_mfn[p2m_mid_index(pfn)] = virt_to_mfn(p2m);
 			p2m = NULL;
@@ -617,7 +617,7 @@ int xen_alloc_p2m_entry(unsigned long pfn)
 	/* Expanded the p2m? */
 	if (pfn > xen_p2m_last_pfn) {
 		xen_p2m_last_pfn = pfn;
-		HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
+		xh_default->HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
 	}
 
 	return 0;
diff --git a/arch/x86/xen/suspend_hvm.c b/arch/x86/xen/suspend_hvm.c
index e666b614cf6d..cc9a0163845c 100644
--- a/arch/x86/xen/suspend_hvm.c
+++ b/arch/x86/xen/suspend_hvm.c
@@ -2,6 +2,7 @@
 #include <linux/types.h>
 
 #include <xen/xen.h>
+#include <xen/xenhost.h>
 #include <xen/features.h>
 #include <xen/interface/features.h>
 
@@ -10,7 +11,10 @@
 void xen_hvm_post_suspend(int suspend_cancelled)
 {
 	if (!suspend_cancelled) {
-		xen_hvm_init_shared_info();
+		xenhost_t **xh;
+
+		for_each_xenhost(xh)
+			xenhost_setup_shared_info(*xh);
 		xen_vcpu_restore();
 	}
 	xen_callback_vector();
diff --git a/arch/x86/xen/suspend_pv.c b/arch/x86/xen/suspend_pv.c
index 8303b58c79a9..87af0c0cc66f 100644
--- a/arch/x86/xen/suspend_pv.c
+++ b/arch/x86/xen/suspend_pv.c
@@ -10,6 +10,8 @@
 
 void xen_pv_pre_suspend(void)
 {
+	xenhost_t **xh;
+
 	xen_mm_pin_all();
 
 	xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
@@ -18,17 +20,17 @@ void xen_pv_pre_suspend(void)
 
 	BUG_ON(!irqs_disabled());
 
-	HYPERVISOR_shared_info = &xen_dummy_shared_info;
-	if (HYPERVISOR_update_va_mapping(fix_to_virt(FIX_PARAVIRT_BOOTMAP),
-					 __pte_ma(0), 0))
-		BUG();
+	for_each_xenhost(xh)
+		xenhost_reset_shared_info(*xh);
 }
 
 void xen_pv_post_suspend(int suspend_cancelled)
 {
+	xenhost_t **xh;
+
 	xen_build_mfn_list_list();
-	set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
-	HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
+	for_each_xenhost(xh)
+		xenhost_setup_shared_info(*xh);
 	xen_setup_mfn_list_list();
 
 	if (suspend_cancelled) {
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 6e29794573b7..d4bb1f8b4f58 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -37,7 +37,7 @@ static u64 xen_sched_clock_offset __read_mostly;
 static unsigned long xen_tsc_khz(void)
 {
 	struct pvclock_vcpu_time_info *info =
-		&HYPERVISOR_shared_info->vcpu_info[0].time;
+		&xh_default->HYPERVISOR_shared_info->vcpu_info[0].time;
 
 	return pvclock_tsc_khz(info);
 }
@@ -66,7 +66,7 @@ static u64 xen_sched_clock(void)
 
 static void xen_read_wallclock(struct timespec64 *ts)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	struct pvclock_wall_clock *wall_clock = &(s->wc);
         struct pvclock_vcpu_time_info *vcpu_time;
 
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 0e60bd918695..5085ce88a8d7 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -28,7 +28,6 @@ DECLARE_PER_CPU(unsigned long, xen_current_cr3);
 
 extern struct start_info *xen_start_info;
 extern struct shared_info xen_dummy_shared_info;
-extern struct shared_info *HYPERVISOR_shared_info;
 
 void xen_setup_mfn_list_list(void);
 void xen_build_mfn_list_list(void);
@@ -56,7 +55,6 @@ void xen_enable_syscall(void);
 void xen_vcpu_restore(void);
 
 void xen_callback_vector(void);
-void xen_hvm_init_shared_info(void);
 void xen_unplug_emulated_devices(void);
 
 void __init xen_build_dynamic_phys_to_machine(void);
diff --git a/arch/x86/xen/xenhost.c b/arch/x86/xen/xenhost.c
index ca90acd7687e..3d8ccef89dcd 100644
--- a/arch/x86/xen/xenhost.c
+++ b/arch/x86/xen/xenhost.c
@@ -2,8 +2,19 @@
 #include <linux/bug.h>
 #include <xen/xen.h>
 #include <xen/xenhost.h>
+#include "xen-ops.h"
 
-xenhost_t xenhosts[2];
+/*
+ * Point at some empty memory to start with. On PV, we map the real shared_info
+ * page as soon as fixmap is up and running and PVH* doesn't use this.
+ */
+xenhost_t xenhosts[2] = {
+	/*
+	 * We should probably have two separate dummy shared_info pages.
+	 */
+	[0].HYPERVISOR_shared_info = &xen_dummy_shared_info,
+	[1].HYPERVISOR_shared_info = &xen_dummy_shared_info,
+};
 /*
  * xh_default: interface to the regular hypervisor. xenhost_type is xenhost_r0
  * or xenhost_r1.
diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c
index 8edef51c92e5..f09dbe4e9c33 100644
--- a/drivers/xen/events/events_2l.c
+++ b/drivers/xen/events/events_2l.c
@@ -55,37 +55,37 @@ static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu)
 
 static void evtchn_2l_clear_pending(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_clear_bit(port, BM(&s->evtchn_pending[0]));
 }
 
 static void evtchn_2l_set_pending(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_set_bit(port, BM(&s->evtchn_pending[0]));
 }
 
 static bool evtchn_2l_is_pending(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	return sync_test_bit(port, BM(&s->evtchn_pending[0]));
 }
 
 static bool evtchn_2l_test_and_set_mask(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0]));
 }
 
 static void evtchn_2l_mask(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	sync_set_bit(port, BM(&s->evtchn_mask[0]));
 }
 
 static void evtchn_2l_unmask(unsigned port)
 {
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	unsigned int cpu = get_cpu();
 	int do_hypercall = 0, evtchn_pending = 0;
 
@@ -167,7 +167,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
 	int start_word_idx, start_bit_idx;
 	int word_idx, bit_idx;
 	int i;
-	struct shared_info *s = HYPERVISOR_shared_info;
+	struct shared_info *s = xh_default->HYPERVISOR_shared_info;
 	struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
 
 	/* Timer interrupt has highest priority. */
@@ -264,7 +264,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
 
 irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
 {
-	struct shared_info *sh = HYPERVISOR_shared_info;
+	struct shared_info *sh = xh_default->HYPERVISOR_shared_info;
 	int cpu = smp_processor_id();
 	xen_ulong_t *cpu_evtchn = per_cpu(cpu_evtchn_mask, cpu);
 	int i;
diff --git a/include/xen/xenhost.h b/include/xen/xenhost.h
index dd1e2b64f50d..7c19c361d16e 100644
--- a/include/xen/xenhost.h
+++ b/include/xen/xenhost.h
@@ -82,6 +82,14 @@ typedef struct {
 	 * bounce callbacks via L1-Xen.
 	 */
 	u8 features[XENFEAT_NR_SUBMAPS * 32];
+
+	/*
+	 * shared-info to communicate with this xenhost instance.
+	 */
+	struct {
+		struct shared_info *HYPERVISOR_shared_info;
+		unsigned long shared_info_pfn;
+	};
 } xenhost_t;
 
 typedef struct xenhost_ops {
@@ -111,6 +119,26 @@ typedef struct xenhost_ops {
 	 *    to decide which particular L1-guest was the caller.
 	 */
 	void (*setup_hypercall_page)(xenhost_t *xenhost);
+
+	/*
+	 * shared_info: needed before vcpu-info setup.
+	 *
+	 * Needed early because Xen needs it for irq_disable() and such.
+	 * On PV first a dummy_shared_info is setup which eventually gets
+	 * switched to the real one so this needs to support switching
+	 * xenhost.
+	 *
+	 * Reset for PV is done differently from HVM, so provide a
+	 * separate interface.
+	 *
+	 *  xenhost_r0: point xenhost->HYPERVISOR_shared_info to a
+	 *    newly allocated shared_info page.
+	 *  xenhost_r1: similar to what we do now.
+	 *  xenhost_r2: new remote hypercall to setup a shared_info page.
+	 *    This is where we would now handle L0-Xen irq/evtchns.
+	 */
+	void (*setup_shared_info)(xenhost_t *xenhost);
+	void (*reset_shared_info)(xenhost_t *xenhost);
 } xenhost_ops_t;
 
 extern xenhost_t *xh_default, *xh_remote;
@@ -146,4 +174,15 @@ static inline void xenhost_setup_hypercall_page(xenhost_t *xh)
 	(xh->ops->setup_hypercall_page)(xh);
 }
 
+
+static inline void xenhost_setup_shared_info(xenhost_t *xh)
+{
+	(xh->ops->setup_shared_info)(xh);
+}
+
+static inline void xenhost_reset_shared_info(xenhost_t *xh)
+{
+	(xh->ops->reset_shared_info)(xh);
+}
+
 #endif /* __XENHOST_H */
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ