Mukesh Rathor
2012-Oct-11 21:57 UTC
[PATCH V2 2/7]: PVH: use native irq, enable callback, use HVM ring ops,...
PVH: make gdt_frames[]/gdt_ents into a union with {gdtaddr, gdtsz}, PVH only needs to send down gdtaddr and gdtsz. irq.c: PVH uses native_irq_ops. vcpu hotplug is currently not available for PVH. events.c: setup callback vector for PVH. Finally, PVH ring ops uses HVM paths for xenbus. Signed-off-by: Mukesh R <mukesh.rathor@oracle.com> --- arch/x86/include/asm/xen/interface.h | 8 +++++++- arch/x86/xen/irq.c | 5 ++++- arch/x86/xen/p2m.c | 2 +- arch/x86/xen/smp.c | 4 ++-- drivers/xen/cpu_hotplug.c | 4 +++- drivers/xen/events.c | 9 ++++++++- drivers/xen/xenbus/xenbus_client.c | 3 ++- 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h index 555f94d..f11edb0 100644 --- a/arch/x86/include/asm/xen/interface.h +++ b/arch/x86/include/asm/xen/interface.h @@ -143,7 +143,13 @@ 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; + } s; + unsigned long gdtaddr, gdtsz; /* PVH: GDTR addr and size */ + } 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 1573376..31959a7 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 <asm/xen/hypercall.h> #include <asm/xen/hypervisor.h> @@ -128,6 +129,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 f58dca7..bd92698 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -324,8 +324,8 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) make_lowmem_page_readonly(gdt); make_lowmem_page_readonly(mfn_to_virt(gdt_mfn)); - ctxt->gdt_frames[0] = gdt_mfn; - ctxt->gdt_ents = GDT_ENTRIES; + ctxt->u.s.gdt_frames[0] = gdt_mfn; + ctxt->u.s.gdt_ents = GDT_ENTRIES; ctxt->user_regs.cs = __KERNEL_CS; ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs); 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 c60d162..a977612 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -1767,7 +1767,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. */ @@ -1826,6 +1826,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 b3e146e..1bac743 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" @@ -743,7 +744,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.2.3
Ian Campbell
2012-Oct-12 08:52 UTC
Re: [Xen-devel] [PATCH V2 2/7]: PVH: use native irq, enable callback, use HVM ring ops, ...
On Thu, 2012-10-11 at 22:57 +0100, Mukesh Rathor wrote:> PVH: make gdt_frames[]/gdt_ents into a union with {gdtaddr, gdtsz}, PVH > only needs to send down gdtaddr and gdtsz. irq.c: PVH uses > native_irq_ops. vcpu hotplug is currently not available for PVH. > events.c: setup callback vector for PVH. Finally, PVH ring ops uses HVM > paths for xenbus. > > Signed-off-by: Mukesh R <mukesh.rathor@oracle.com> > --- > arch/x86/include/asm/xen/interface.h | 8 +++++++- > arch/x86/xen/irq.c | 5 ++++- > arch/x86/xen/p2m.c | 2 +- > arch/x86/xen/smp.c | 4 ++-- > drivers/xen/cpu_hotplug.c | 4 +++- > drivers/xen/events.c | 9 ++++++++- > drivers/xen/xenbus/xenbus_client.c | 3 ++- > 7 files changed, 27 insertions(+), 8 deletions(-) > > diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h > index 555f94d..f11edb0 100644 > --- a/arch/x86/include/asm/xen/interface.h > +++ b/arch/x86/include/asm/xen/interface.h > @@ -143,7 +143,13 @@ 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; > + } s; > + unsigned long gdtaddr, gdtsz; /* PVH: GDTR addr and size */I''ve pointed out a few times that I think this is wrong -- gdtaddr and gdtsz will overlap each other in the union. I''m not sure how it even works, unless the hypervisor is ignoring one or the other. You need: union { struct { unsigned long gdt_frames[16], gdt_ents; } pv; struct { unsigned long gdtaddr, gdtsz; } pvh; } gdt; (I''ve gone with naming the union gdt instead of u. You might want therefore to also drop the gdt prefix from the members?) Ian.
Mukesh Rathor
2012-Oct-12 19:06 UTC
Re: [Xen-devel] [PATCH V2 2/7]: PVH: use native irq, enable callback, use HVM ring ops, ...
On Fri, 12 Oct 2012 09:52:17 +0100 Ian Campbell <Ian.Campbell@citrix.com> wrote:> > drivers/xen/cpu_hotplug.c | 4 +++- > > drivers/xen/events.c | 9 ++++++++- > > drivers/xen/xenbus/xenbus_client.c | 3 ++- > > 7 files changed, 27 insertions(+), 8 deletions(-) > > > > diff --git a/arch/x86/include/asm/xen/interface.h > > b/arch/x86/include/asm/xen/interface.h index 555f94d..f11edb0 100644 > > --- a/arch/x86/include/asm/xen/interface.h > > +++ b/arch/x86/include/asm/xen/interface.h > > @@ -143,7 +143,13 @@ 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; > > + } s; > > + unsigned long gdtaddr, gdtsz; /* PVH: GDTR addr > > and size */ > > I''ve pointed out a few times that I think this is wrong -- gdtaddr and > gdtsz will overlap each other in the union. I''m not sure how it even > works, unless the hypervisor is ignoring one or the other. You need: > > union { > struct { > unsigned long gdt_frames[16], gdt_ents; > } pv; > struct { > unsigned long gdtaddr, gdtsz; > } pvh; > } gdt; > > (I''ve gone with naming the union gdt instead of u. You might want > therefore to also drop the gdt prefix from the members?)Is it worth it, I mean, making it a union. Would you be OK if I just used gdt_frames[0] and gdt_ends for gdtaddr and size? thanks Mukesh
Ian Campbell
2012-Oct-15 08:58 UTC
Re: [Xen-devel] [PATCH V2 2/7]: PVH: use native irq, enable callback, use HVM ring ops, ...
On Fri, 2012-10-12 at 20:06 +0100, Mukesh Rathor wrote:> On Fri, 12 Oct 2012 09:52:17 +0100 > Ian Campbell <Ian.Campbell@citrix.com> wrote: > > > > drivers/xen/cpu_hotplug.c | 4 +++- > > > drivers/xen/events.c | 9 ++++++++- > > > drivers/xen/xenbus/xenbus_client.c | 3 ++- > > > 7 files changed, 27 insertions(+), 8 deletions(-) > > > > > > diff --git a/arch/x86/include/asm/xen/interface.h > > > b/arch/x86/include/asm/xen/interface.h index 555f94d..f11edb0 100644 > > > --- a/arch/x86/include/asm/xen/interface.h > > > +++ b/arch/x86/include/asm/xen/interface.h > > > @@ -143,7 +143,13 @@ 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; > > > + } s; > > > + unsigned long gdtaddr, gdtsz; /* PVH: GDTR addr > > > and size */ > > > > I''ve pointed out a few times that I think this is wrong -- gdtaddr and > > gdtsz will overlap each other in the union. I''m not sure how it even > > works, unless the hypervisor is ignoring one or the other. You need: > > > > union { > > struct { > > unsigned long gdt_frames[16], gdt_ents; > > } pv; > > struct { > > unsigned long gdtaddr, gdtsz; > > } pvh; > > } gdt; > > > > (I''ve gone with naming the union gdt instead of u. You might want > > therefore to also drop the gdt prefix from the members?) > > Is it worth it, I mean, making it a union. Would you be OK if I just > used gdt_frames[0] and gdt_ends for gdtaddr and size?What''s the problem with making it a union? Seems like you are 80% of the way there. Why is this different between PV and PVH in the first place (at the API level I mean, obviously the handling in the h/v will differ)? At the very least gdtsz and gdt_ents are the same thing with different units AFAICT and so can be combined. How come you don''t need the same stuff for ldt*? Ian.
Mukesh Rathor
2012-Oct-16 22:11 UTC
Re: [Xen-devel] [PATCH V2 2/7]: PVH: use native irq, enable callback, use HVM ring ops, ...
On Mon, 15 Oct 2012 09:58:17 +0100 Ian Campbell <Ian.Campbell@citrix.com> wrote:> On Fri, 2012-10-12 at 20:06 +0100, Mukesh Rathor wrote: > > On Fri, 12 Oct 2012 09:52:17 +0100 > > Ian Campbell <Ian.Campbell@citrix.com> wrote: > > > > > > drivers/xen/cpu_hotplug.c | 4 +++- > > > > drivers/xen/events.c | 9 ++++++++- > > > > drivers/xen/xenbus/xenbus_client.c | 3 ++- > > > > 7 files changed, 27 insertions(+), 8 deletions(-) > > > > > > > union { > > > struct { > > > unsigned long gdt_frames[16], gdt_ents; > > > } pv; > > > struct { > > > unsigned long gdtaddr, gdtsz; > > > } pvh; > > > } gdt; > > > > > > (I''ve gone with naming the union gdt instead of u. You might want > > > therefore to also drop the gdt prefix from the members?) > > > > Is it worth it, I mean, making it a union. Would you be OK if I just > > used gdt_frames[0] and gdt_ends for gdtaddr and size? > > What''s the problem with making it a union? Seems like you are 80% of > the way there.No problem. It resutls in a patch on xen side too. I''ll send that too.> units AFAICT and so can be combined. > > How come you don''t need the same stuff for ldt*?Happens natively. Isn''t PVH great! thanks mukesh