Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204780
b: refs/heads/master
c: 38e20b0
h: refs/heads/master
v: v3
  • Loading branch information
Sheng Yang authored and Jeremy Fitzhardinge committed Jul 22, 2010
1 parent 9ee08d3 commit 4783c0c
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bee6ab53e652a414af20392899879b58cd80d033
refs/heads/master: 38e20b07efd541a959de367dc90a17f92ce2e8a6
3 changes: 3 additions & 0 deletions trunk/arch/x86/include/asm/irq_vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
*/
#define MCE_SELF_VECTOR 0xeb

/* Xen vector callback to receive events in a HVM domain */
#define XEN_HVM_EVTCHN_CALLBACK 0xe9

#define NR_VECTORS 256

#define FPU_IRQ 13
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,9 @@ ENTRY(xen_failsafe_callback)
.previous
ENDPROC(xen_failsafe_callback)

BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
xen_evtchn_do_upcall)

#endif /* CONFIG_XEN */

#ifdef CONFIG_FUNCTION_TRACER
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,9 @@ ENTRY(xen_failsafe_callback)
CFI_ENDPROC
END(xen_failsafe_callback)

apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
xen_hvm_callback_vector xen_evtchn_do_upcall

#endif /* CONFIG_XEN */

/*
Expand Down
28 changes: 28 additions & 0 deletions trunk/arch/x86/xen/enlighten.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007
*/

#include <linux/cpu.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
Expand Down Expand Up @@ -38,6 +39,7 @@
#include <xen/interface/memory.h>
#include <xen/features.h>
#include <xen/page.h>
#include <xen/hvm.h>
#include <xen/hvc-console.h>

#include <asm/paravirt.h>
Expand Down Expand Up @@ -80,6 +82,8 @@ struct shared_info xen_dummy_shared_info;
void *xen_initial_gdt;

RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
__read_mostly int xen_have_vector_callback;
EXPORT_SYMBOL_GPL(xen_have_vector_callback);

/*
* Point at some empty memory to start with. We map the real shared_info
Expand Down Expand Up @@ -1277,6 +1281,24 @@ static void __init init_shared_info(void)
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
}

static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
int cpu = (long)hcpu;
switch (action) {
case CPU_UP_PREPARE:
per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
break;
default:
break;
}
return NOTIFY_OK;
}

static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = {
.notifier_call = xen_hvm_cpu_notify,
};

static void __init xen_hvm_guest_init(void)
{
int r;
Expand All @@ -1287,6 +1309,12 @@ static void __init xen_hvm_guest_init(void)
return;

init_shared_info();

if (xen_feature(XENFEAT_hvm_callback_vector))
xen_have_vector_callback = 1;
register_cpu_notifier(&xen_hvm_cpu_notifier);
have_vcpu_info_placement = 0;
x86_init.irqs.intr_init = xen_init_IRQ;
}

static bool __init xen_hvm_platform(void)
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86/xen/xen-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ void xen_enable_sysenter(void);
void xen_enable_syscall(void);
void xen_vcpu_restore(void);

void xen_callback_vector(void);

void __init xen_build_dynamic_phys_to_machine(void);

void xen_init_irq_ops(void);
Expand Down
70 changes: 63 additions & 7 deletions trunk/drivers/xen/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@
#include <linux/bootmem.h>
#include <linux/slab.h>

#include <asm/desc.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
#include <asm/idle.h>
#include <asm/sync_bitops.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>

#include <xen/xen.h>
#include <xen/hvm.h>
#include <xen/xen-ops.h>
#include <xen/events.h>
#include <xen/interface/xen.h>
#include <xen/interface/event_channel.h>
#include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/hvm/params.h>

/*
* This lock protects updates to the following mapping and reference-count
Expand Down Expand Up @@ -617,17 +622,13 @@ static DEFINE_PER_CPU(unsigned, xed_nesting_count);
* a bitset of words which contain pending event bits. The second
* level is a bitset of pending events themselves.
*/
void xen_evtchn_do_upcall(struct pt_regs *regs)
static void __xen_evtchn_do_upcall(void)
{
int cpu = get_cpu();
struct pt_regs *old_regs = set_irq_regs(regs);
struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
unsigned count;

exit_idle();
irq_enter();

do {
unsigned long pending_words;

Expand Down Expand Up @@ -667,10 +668,26 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
} while(count != 1);

out:

put_cpu();
}

void xen_evtchn_do_upcall(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);

exit_idle();
irq_enter();

__xen_evtchn_do_upcall();

irq_exit();
set_irq_regs(old_regs);
}

put_cpu();
void xen_hvm_evtchn_do_upcall(void)
{
__xen_evtchn_do_upcall();
}

/* Rebind a new event channel to an existing irq. */
Expand Down Expand Up @@ -933,6 +950,40 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
.retrigger = retrigger_dynirq,
};

int xen_set_callback_via(uint64_t via)
{
struct xen_hvm_param a;
a.domid = DOMID_SELF;
a.index = HVM_PARAM_CALLBACK_IRQ;
a.value = via;
return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
}
EXPORT_SYMBOL_GPL(xen_set_callback_via);

/* 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. */
void xen_callback_vector(void)
{
int rc;
uint64_t callback_via;
if (xen_have_vector_callback) {
callback_via = HVM_CALLBACK_VECTOR(XEN_HVM_EVTCHN_CALLBACK);
rc = xen_set_callback_via(callback_via);
if (rc) {
printk(KERN_ERR "Request for Xen HVM callback vector"
" failed.\n");
xen_have_vector_callback = 0;
return;
}
printk(KERN_INFO "Xen HVM callback vector for event delivery is "
"enabled\n");
/* in the restore case the vector has already been allocated */
if (!test_bit(XEN_HVM_EVTCHN_CALLBACK, used_vectors))
alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
}
}

void __init xen_init_IRQ(void)
{
int i;
Expand All @@ -947,5 +998,10 @@ void __init xen_init_IRQ(void)
for (i = 0; i < NR_EVENT_CHANNELS; i++)
mask_evtchn(i);

irq_ctx_init(smp_processor_id());
if (xen_hvm_domain()) {
xen_callback_vector();
native_init_IRQ();
} else {
irq_ctx_init(smp_processor_id());
}
}
7 changes: 7 additions & 0 deletions trunk/include/xen/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,11 @@ void xen_poll_irq(int irq);
/* Determine the IRQ which is bound to an event channel */
unsigned irq_from_evtchn(unsigned int evtchn);

/* Xen HVM evtchn vector callback */
extern void xen_hvm_callback_vector(void);
extern int xen_have_vector_callback;
int xen_set_callback_via(uint64_t via);
void xen_evtchn_do_upcall(struct pt_regs *regs);
void xen_hvm_evtchn_do_upcall(void);

#endif /* _XEN_EVENTS_H */
6 changes: 6 additions & 0 deletions trunk/include/xen/hvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define XEN_HVM_H__

#include <xen/interface/hvm/params.h>
#include <asm/xen/hypercall.h>

static inline int hvm_get_parameter(int idx, uint64_t *value)
{
Expand All @@ -21,4 +22,9 @@ static inline int hvm_get_parameter(int idx, uint64_t *value)
return r;
}

#define HVM_CALLBACK_VIA_TYPE_VECTOR 0x2
#define HVM_CALLBACK_VIA_TYPE_SHIFT 56
#define HVM_CALLBACK_VECTOR(x) (((uint64_t)HVM_CALLBACK_VIA_TYPE_VECTOR)<<\
HVM_CALLBACK_VIA_TYPE_SHIFT | (x))

#endif /* XEN_HVM_H__ */
3 changes: 3 additions & 0 deletions trunk/include/xen/interface/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
/* x86: Does this Xen host support the MMU_PT_UPDATE_PRESERVE_AD hypercall? */
#define XENFEAT_mmu_pt_update_preserve_ad 5

/* x86: Does this Xen host support the HVM callback vector type? */
#define XENFEAT_hvm_callback_vector 8

#define XENFEAT_NR_SUBMAPS 1

#endif /* __XEN_PUBLIC_FEATURES_H__ */

0 comments on commit 4783c0c

Please sign in to comment.