mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1159.79.15 (4151a1aaxwsNrL2Uz8ag9J-2-2nVwQ)
Don't use fake clockframe for interrupt delivery. Fixes all cpu time getting accounted to the kernel and not to userspace programs.
This commit is contained in:
1 parent
262c170bd9
commit
ab8cc8dfe7
6 files changed
+52
-16
No files matched your search
@@ -151,7 +151,7 @@ stipending()
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void do_hypervisor_callback(struct trapframe *regs)
|
||||
void do_hypervisor_callback(struct intrframe *regs)
|
||||
{
|
||||
uint32_t l1;
|
||||
unsigned long l2;
|
||||
|
||||
@@ -1347,9 +1347,10 @@ ENTRY(hypervisor_callback)
|
||||
jb 11f
|
||||
cmpl $ecrit,%eax
|
||||
jb critical_region_fixup
|
||||
11: push %esp
|
||||
11: pushl CPUVAR(ILEVEL)
|
||||
push %esp
|
||||
call do_hypervisor_callback
|
||||
add $4,%esp
|
||||
add $8,%esp
|
||||
movl HYPERVISOR_shared_info,%esi
|
||||
xorl %eax,%eax
|
||||
movb TF_CS(%esp),%cl
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef int (*ev_handler_t)(void *);
|
||||
|
||||
void events_default_setup(void);
|
||||
void init_events(void);
|
||||
unsigned int do_event(int, struct trapframe *);
|
||||
unsigned int do_event(int, struct intrframe *);
|
||||
int event_set_handler(int, ev_handler_t, void *, int);
|
||||
|
||||
int bind_virq_to_irq(int);
|
||||
|
||||
@@ -83,7 +83,7 @@ extern union start_info_union start_info_union;
|
||||
|
||||
|
||||
/* hypervisor.c */
|
||||
void do_hypervisor_callback(struct trapframe *regs);
|
||||
void do_hypervisor_callback(struct intrframe *regs);
|
||||
void hypervisor_notify_via_evtchn(unsigned int);
|
||||
void hypervisor_enable_irq(unsigned int);
|
||||
void hypervisor_disable_irq(unsigned int);
|
||||
|
||||
@@ -51,7 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.1.2.2 2004/07/17 16:43:56 he Exp $");
|
||||
|
||||
#include "config_time.h" /* for CONFIG_TIME */
|
||||
|
||||
static int xen_timer_handler(void *, struct trapframe *);
|
||||
static int xen_timer_handler(void *, struct intrframe *);
|
||||
|
||||
/* These are peridically updated in shared_info, and then copied here. */
|
||||
static uint64_t shadow_tsc_stamp;
|
||||
@@ -213,7 +213,7 @@ xen_initclocks()
|
||||
}
|
||||
|
||||
static int
|
||||
xen_timer_handler(void *arg, struct trapframe *regs)
|
||||
xen_timer_handler(void *arg, struct intrframe *regs)
|
||||
{
|
||||
int64_t delta;
|
||||
|
||||
@@ -245,7 +245,7 @@ xen_timer_handler(void *arg, struct trapframe *regs)
|
||||
delta = (int64_t)(shadow_system_time + get_tsc_offset_ns() -
|
||||
processed_system_time);
|
||||
while (delta >= NS_PER_TICK) {
|
||||
hardclock((struct clockframe *)regs);
|
||||
hardclock(regs);
|
||||
delta -= NS_PER_TICK;
|
||||
processed_system_time += NS_PER_TICK;
|
||||
}
|
||||
|
||||
@@ -123,9 +123,13 @@ init_events()
|
||||
}
|
||||
|
||||
unsigned int
|
||||
do_event(int irq, struct trapframe *regs)
|
||||
do_event(int irq, struct intrframe *regs)
|
||||
{
|
||||
struct cpu_info *ci;
|
||||
int ilevel;
|
||||
struct intrhand *ih;
|
||||
int (*ih_fun)(void *, void *);
|
||||
extern struct uvmexp uvmexp;
|
||||
|
||||
if (irq >= NR_IRQS) {
|
||||
#ifdef DIAGNOSTIC
|
||||
@@ -144,15 +148,46 @@ do_event(int irq, struct trapframe *regs)
|
||||
|
||||
hypervisor_acknowledge_irq(irq);
|
||||
if (ci->ci_isources[irq] == NULL) {
|
||||
hypervisor_enable_irq(irq);
|
||||
return 0;
|
||||
}
|
||||
__asm__ __volatile__ (
|
||||
" movl $1f,%%esi ;"
|
||||
" jmp *%%eax ;"
|
||||
"1: "
|
||||
: : "a" (ci->ci_isources[irq]->is_recurse),
|
||||
"b" (ci->ci_ilevel)
|
||||
: "esi", "ecx", "edx", "memory");
|
||||
ilevel = ci->ci_ilevel;
|
||||
if (ci->ci_isources[irq]->is_maxlevel <= ilevel) {
|
||||
ci->ci_ipending |= 1 << irq;
|
||||
/* leave masked */
|
||||
return 0;
|
||||
}
|
||||
uvmexp.intrs++;
|
||||
ci->ci_isources[irq]->is_evcnt.ev_count++;
|
||||
ci->ci_ilevel = ci->ci_isources[irq]->is_maxlevel;
|
||||
/* sti */
|
||||
ci->ci_idepth++;
|
||||
#ifdef MULTIPROCESSOR
|
||||
x86_intlock(regs);
|
||||
#endif
|
||||
ih = ci->ci_isources[irq]->is_handlers;
|
||||
while (ih != NULL) {
|
||||
if (ih->ih_level <= ilevel) {
|
||||
#ifdef MULTIPROCESSOR
|
||||
x86_intunlock(regs);
|
||||
#endif
|
||||
ci->ci_ipending |= 1 << irq;
|
||||
/* leave masked */
|
||||
ci->ci_idepth--;
|
||||
splx(ilevel);
|
||||
return 0;
|
||||
}
|
||||
ci->ci_ilevel = ih->ih_level;
|
||||
ih_fun = (void *)ih->ih_fun;
|
||||
ih_fun(ih->ih_arg, regs);
|
||||
ih = ih->ih_next;
|
||||
}
|
||||
#ifdef MULTIPROCESSOR
|
||||
x86_intunlock(regs);
|
||||
#endif
|
||||
hypervisor_enable_irq(irq);
|
||||
ci->ci_idepth--;
|
||||
splx(ilevel);
|
||||
|
||||
if (0 && irq == 4)
|
||||
printf("do_event %d done, ipending %08x\n", irq,
|
||||
|
||||