On Mon, 22 Oct 2012, Konrad Rzeszutek Wilk wrote: > On Mon, Oct 22, 2012 at 11:31:54AM -0700, Mukesh Rathor wrote: > > On Mon, 22 Oct 2012 14:44:40 +0100 > > Stefano Stabellini <stefano.stabell...@eu.citrix.com> wrote: > > > > > On Sat, 20 Oct 2012, Konrad Rzeszutek Wilk wrote: > > > > From: Mukesh Rathor <mukesh.rat...@oracle.com> > > > > > > > > make gdt_frames[]/gdt_ents into a union with {gdtaddr, gdtsz}, as > > > > PVH only needs to send down gdtaddr and gdtsz. > > > > > > > > For interrupts, PVH uses native_irq_ops. > > > > vcpu hotplug is currently not available for PVH. > > > > > > > > For events we follow what PVHVM does - to use callback vector. > > > > Lastly, also use HVM path to setup XenBus. > > > > > > > > Signed-off-by: Mukesh Rathor <mukesh.rat...@oracle.com> > > > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> > > > > --- > > > > return true; > > > > } > > > > - xen_copy_trap_info(ctxt->trap_ctxt); > > > > + /* check for autoxlated to get it right for 32bit kernel */ > > > > > > I am not sure what this comment means, considering that in another > > > comment below you say that we don't support 32bit PVH kernels. > > > > Function is common to both 32bit and 64bit kernels. We need to check > > for auto xlated also in the if statement in addition to supervisor > > mode kernel, so 32 bit doesn't go down the wrong path. > > Can one just make it #ifdef CONFIG_X86_64 for the whole thing? > You are either way during bootup doing a 'BUG' when booting as 32-bit? > > > > > > PVH is not supported for 32bit kernels, and gs_base_user doesn't exist > > in the structure for 32bit so it needs to be if'def'd 64bit which is > > ok because PVH is not supprted on 32bit kernel. > > > > > > + (unsigned > > > > long)xen_hypervisor_callback; > > > > + ctxt->failsafe_callback_eip = > > > > + (unsigned > > > > long)xen_failsafe_callback; > > > > + } > > > > + ctxt->user_regs.cs = __KERNEL_CS; > > > > + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct > > > > pt_regs); > > > > per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); > > > > ctxt->ctrlreg[3] = > > > > xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir)); > > > > > > The tradional path looks the same as before, however it is hard to > > > tell whether the PVH path is correct without the Xen side. For > > > example, what is gdtsz? > > > > gdtsz is GUEST_GDTR_LIMIT and gdtaddr is GUEST_GDTR_BASE in the vmcs. > > looking at this I figured it could be a bit neater. So I split it in > two patches which should make it easier to read the PVH one.
It is much more readable now, thanks! You can have my ack on both of them. > >From f9455e293169d73e5698df62801bcd5fd64a5259 Mon Sep 17 00:00:00 2001 > From: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> > Date: Mon, 22 Oct 2012 11:35:16 -0400 > Subject: [PATCH 1/2] xen/smp: Move the common CPU init code a bit to prep for > PVH patch. > > The PV and PVH code CPU init code share some functionality. The > PVH code ("xen/pvh: Extend vcpu_guest_context, p2m, event, and XenBus") > sets some of these up, but not all. To make it easier to read, this > patch removes the PV specific out of the generic way. > > No functional change, just code move. > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> > --- > arch/x86/xen/smp.c | 42 +++++++++++++++++++++++------------------- > 1 files changed, 23 insertions(+), 19 deletions(-) > > diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c > index 353c50f..ba49a3a 100644 > --- a/arch/x86/xen/smp.c > +++ b/arch/x86/xen/smp.c > @@ -300,8 +300,6 @@ cpu_initialize_context(unsigned int cpu, struct > task_struct *idle) > gdt = get_cpu_gdt_table(cpu); > > ctxt->flags = VGCF_IN_KERNEL; > - ctxt->user_regs.ds = __USER_DS; > - ctxt->user_regs.es = __USER_DS; > ctxt->user_regs.ss = __KERNEL_DS; > #ifdef CONFIG_X86_32 > ctxt->user_regs.fs = __KERNEL_PERCPU; > @@ -310,35 +308,41 @@ cpu_initialize_context(unsigned int cpu, struct > task_struct *idle) > ctxt->gs_base_kernel = per_cpu_offset(cpu); > #endif > ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle; > - ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ > > memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); > > - xen_copy_trap_info(ctxt->trap_ctxt); > + { > + ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ > + ctxt->user_regs.ds = __USER_DS; > + ctxt->user_regs.es = __USER_DS; > > - ctxt->ldt_ents = 0; > + xen_copy_trap_info(ctxt->trap_ctxt); > > - BUG_ON((unsigned long)gdt & ~PAGE_MASK); > + ctxt->ldt_ents = 0; > > - gdt_mfn = arbitrary_virt_to_mfn(gdt); > - make_lowmem_page_readonly(gdt); > - make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); > + BUG_ON((unsigned long)gdt & ~PAGE_MASK); > > - ctxt->gdt_frames[0] = gdt_mfn; > - ctxt->gdt_ents = GDT_ENTRIES; > + gdt_mfn = arbitrary_virt_to_mfn(gdt); > + make_lowmem_page_readonly(gdt); > + make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); > > - ctxt->user_regs.cs = __KERNEL_CS; > - ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); > + ctxt->u.pv.gdt_frames[0] = gdt_mfn; > + ctxt->u.pv.gdt_ents = GDT_ENTRIES; > > - ctxt->kernel_ss = __KERNEL_DS; > - ctxt->kernel_sp = idle->thread.sp0; > + ctxt->kernel_ss = __KERNEL_DS; > + ctxt->kernel_sp = idle->thread.sp0; > > #ifdef CONFIG_X86_32 > - ctxt->event_callback_cs = __KERNEL_CS; > - ctxt->failsafe_callback_cs = __KERNEL_CS; > + ctxt->event_callback_cs = __KERNEL_CS; > + ctxt->failsafe_callback_cs = __KERNEL_CS; > #endif > - ctxt->event_callback_eip = (unsigned long)xen_hypervisor_callback; > - ctxt->failsafe_callback_eip = (unsigned long)xen_failsafe_callback; > + ctxt->event_callback_eip = > + (unsigned > long)xen_hypervisor_callback; > + ctxt->failsafe_callback_eip = > + (unsigned long)xen_failsafe_callback; > + } > + ctxt->user_regs.cs = __KERNEL_CS; > + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); > > per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir); > ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir)); > -- > 1.7.7.6 > > > > > >From 2c4dd7f567b229451f3dc1ae00d784da8b4a5072 Mon Sep 17 00:00:00 2001 > From: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> > Date: Mon, 22 Oct 2012 11:37:57 -0400 > Subject: [PATCH 2/2] xen/pvh: Extend vcpu_guest_context, p2m, event, and > XenBus. > > Make gdt_frames[]/gdt_ents into a union with {gdtaddr, gdtsz}, > as PVH only needs to send down gdtaddr and gdtsz in the > vcpu_guest_context structure.. > > For interrupts, PVH uses native_irq_ops so we can skip most of the > PV ones. In the future we can support the pirq_eoi_map.. > Also VCPU hotplug is currently not available for PVH. > > For events (and IRQs) we follow what PVHVM does - so use callback > vector. Lastly, for XenBus we use the same logic that is used in > the PVHVM case. > > Signed-off-by: Mukesh Rathor <mukesh.rat...@oracle.com> > [v2: Rebased it] > [v3: Move 64-bit ifdef and based on Stefan add extra comments.] > Signed-off-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com> > --- > arch/x86/include/asm/xen/interface.h | 11 +++++++++- > arch/x86/xen/irq.c | 5 +++- > arch/x86/xen/p2m.c | 2 +- > arch/x86/xen/smp.c | 36 ++++++++++++++++++++++++++------- > drivers/xen/cpu_hotplug.c | 4 ++- > drivers/xen/events.c | 9 +++++++- > drivers/xen/xenbus/xenbus_client.c | 3 +- > 7 files changed, 56 insertions(+), 14 deletions(-) > > diff --git a/arch/x86/include/asm/xen/interface.h > b/arch/x86/include/asm/xen/interface.h > index 6d2f75a..4c08f23 100644 > --- a/arch/x86/include/asm/xen/interface.h > +++ b/arch/x86/include/asm/xen/interface.h > @@ -144,7 +144,16 @@ struct vcpu_guest_context { > struct cpu_user_regs user_regs; /* User-level CPU registers > */ > struct trap_info trap_ctxt[256]; /* Virtual IDT > */ > unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) > */ > - unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) > */ > + union { > + struct { > + /* PV: GDT (machine frames, # ents).*/ > + unsigned long gdt_frames[16], gdt_ents; > + } pv; > + struct { > + /* PVH: GDTR addr and size */ > + unsigned long gdtaddr, gdtsz; > + } pvh; > + } u; > unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) > */ > /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ > unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) > */ > diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c > index 01a4dc0..fcbe56a 100644 > --- a/arch/x86/xen/irq.c > +++ b/arch/x86/xen/irq.c > @@ -5,6 +5,7 @@ > #include <xen/interface/xen.h> > #include <xen/interface/sched.h> > #include <xen/interface/vcpu.h> > +#include <xen/features.h> > #include <xen/events.h> > > #include <asm/xen/hypercall.h> > @@ -129,6 +130,8 @@ static const struct pv_irq_ops xen_irq_ops __initconst = { > > void __init xen_init_irq_ops(void) > { > - pv_irq_ops = xen_irq_ops; > + /* For PVH we use default pv_irq_ops settings */ > + if (!xen_feature(XENFEAT_hvm_callback_vector)) > + pv_irq_ops = xen_irq_ops; > x86_init.irqs.intr_init = xen_init_IRQ; > } > diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c > index 95fb2aa..ea553c8 100644 > --- a/arch/x86/xen/p2m.c > +++ b/arch/x86/xen/p2m.c > @@ -798,7 +798,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned > long mfn) > { > unsigned topidx, mididx, idx; > > - if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { > + if (xen_feature(XENFEAT_auto_translated_physmap)) { > BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); > return true; > } > diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c > index ba49a3a..6f831a1 100644 > --- a/arch/x86/xen/smp.c > +++ b/arch/x86/xen/smp.c > @@ -68,9 +68,11 @@ static void __cpuinit cpu_bringup(void) > touch_softlockup_watchdog(); > preempt_disable(); > > - xen_enable_sysenter(); > - xen_enable_syscall(); > - > + /* PVH runs in ring 0 and allows us to do native syscalls. Yay! */ > + if (!xen_feature(XENFEAT_supervisor_mode_kernel)) { > + xen_enable_sysenter(); > + xen_enable_syscall(); > + } > cpu = smp_processor_id(); > smp_store_cpu_info(cpu); > cpu_data(cpu).x86_max_cores = 1; > @@ -230,10 +232,11 @@ static void __init xen_smp_prepare_boot_cpu(void) > BUG_ON(smp_processor_id() != 0); > native_smp_prepare_boot_cpu(); > > - /* We've switched to the "real" per-cpu gdt, so make sure the > - old memory can be recycled */ > - make_lowmem_page_readwrite(xen_initial_gdt); > - > + if (!xen_feature(XENFEAT_writable_page_tables)) { > + /* We've switched to the "real" per-cpu gdt, so make sure the > + * old memory can be recycled */ > + make_lowmem_page_readwrite(xen_initial_gdt); > + } > xen_filter_cpu_maps(); > xen_setup_vcpu_info_placement(); > } > @@ -311,7 +314,24 @@ cpu_initialize_context(unsigned int cpu, struct > task_struct *idle) > > memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); > > - { > + /* check for autoxlated to get it right for 32bit kernel */ > + if (xen_feature(XENFEAT_auto_translated_physmap) && > + xen_feature(XENFEAT_supervisor_mode_kernel)) { > +#ifdef CONFIG_X86_64 > + ctxt->user_regs.ds = __KERNEL_DS; > + ctxt->user_regs.es = 0; > + ctxt->user_regs.gs = 0; > + > + /* GUEST_GDTR_BASE and */ > + ctxt->u.pvh.gdtaddr = (unsigned long)gdt; > + /* GUEST_GDTR_LIMIT in the VMCS. */ > + ctxt->u.pvh.gdtsz = (unsigned long)(GDT_SIZE - 1); > + > + /* Note: PVH is not supported on x86_32. */ > + ctxt->gs_base_user = (unsigned long) > + per_cpu(irq_stack_union.gs_base, cpu); > +#endif > + } else { > ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */ > ctxt->user_regs.ds = __USER_DS; > ctxt->user_regs.es = __USER_DS; > diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c > index 4dcfced..de6bcf9 100644 > --- a/drivers/xen/cpu_hotplug.c > +++ b/drivers/xen/cpu_hotplug.c > @@ -2,6 +2,7 @@ > > #include <xen/xen.h> > #include <xen/xenbus.h> > +#include <xen/features.h> > > #include <asm/xen/hypervisor.h> > #include <asm/cpu.h> > @@ -100,7 +101,8 @@ static int __init setup_vcpu_hotplug_event(void) > static struct notifier_block xsn_cpu = { > .notifier_call = setup_cpu_watcher }; > > - if (!xen_pv_domain()) > + /* PVH TBD/FIXME: future work */ > + if (!xen_pv_domain() || xen_feature(XENFEAT_auto_translated_physmap)) > return -ENODEV; > > register_xenstore_notifier(&xsn_cpu); > diff --git a/drivers/xen/events.c b/drivers/xen/events.c > index 59e10a1..7131fdd 100644 > --- a/drivers/xen/events.c > +++ b/drivers/xen/events.c > @@ -1774,7 +1774,7 @@ int xen_set_callback_via(uint64_t via) > } > EXPORT_SYMBOL_GPL(xen_set_callback_via); > > -#ifdef CONFIG_XEN_PVHVM > +#ifdef CONFIG_X86 > /* Vector callbacks are better than PCI interrupts to receive event > * channel notifications because we can receive vector callbacks on any > * vcpu and we don't need PCI support or APIC interactions. */ > @@ -1835,6 +1835,13 @@ void __init xen_init_IRQ(void) > if (xen_initial_domain()) > pci_xen_initial_domain(); > > + if (xen_feature(XENFEAT_hvm_callback_vector)) { > + xen_callback_vector(); > + return; > + } > + > + /* PVH: TBD/FIXME: debug and fix eio map to work with pvh */ > + > pirq_eoi_map = (void *)__get_free_page(GFP_KERNEL|__GFP_ZERO); > eoi_gmfn.gmfn = virt_to_mfn(pirq_eoi_map); > rc = HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn_v2, > &eoi_gmfn); > diff --git a/drivers/xen/xenbus/xenbus_client.c > b/drivers/xen/xenbus/xenbus_client.c > index bcf3ba4..356461e 100644 > --- a/drivers/xen/xenbus/xenbus_client.c > +++ b/drivers/xen/xenbus/xenbus_client.c > @@ -44,6 +44,7 @@ > #include <xen/grant_table.h> > #include <xen/xenbus.h> > #include <xen/xen.h> > +#include <xen/features.h> > > #include "xenbus_probe.h" > > @@ -741,7 +742,7 @@ static const struct xenbus_ring_ops ring_ops_hvm = { > > void __init xenbus_ring_ops_init(void) > { > - if (xen_pv_domain()) > + if (xen_pv_domain() && !xen_feature(XENFEAT_auto_translated_physmap)) > ring_ops = &ring_ops_pv; > else > ring_ops = &ring_ops_hvm; > -- > 1.7.7.6 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/