ia64/xen-unstable
changeset 7634:65c3b9382caa
This patch is to remove the pit_timer when the vmx domain is
inactive to save HV external IRQ caused by ac_time and some cleanup for
ioapic in HV.
Thx,eddie
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
inactive to save HV external IRQ caused by ac_time and some cleanup for
ioapic in HV.
Thx,eddie
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Sat Nov 05 11:26:29 2005 +0100 (2005-11-05) |
parents | b180310a0d2c |
children | 0cae0c6436f5 |
files | tools/ioemu/hw/pc.c tools/ioemu/target-i386-dm/Makefile tools/ioemu/target-i386-dm/helper2.c xen/arch/x86/dm/i8259.c xen/arch/x86/vmx.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vlapic.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_virpit.h xen/include/asm-x86/vmx_vlapic.h xen/include/asm-x86/vmx_vmcs.h xen/include/public/io/vmx_vlapic.h xen/include/public/io/vmx_vpic.h |
line diff
1.1 --- a/tools/ioemu/hw/pc.c Sat Nov 05 11:23:02 2005 +0100 1.2 +++ b/tools/ioemu/hw/pc.c Sat Nov 05 11:26:29 2005 +0100 1.3 @@ -547,9 +547,6 @@ void pc_init(int ram_size, int vga_ram_s 1.4 pci_pcnet_init(pci_bus, &nd_table[i]); 1.5 } 1.6 pci_piix3_ide_init(pci_bus, bs_table); 1.7 -#ifdef APIC_SUPPORT 1.8 - IOAPICInit(); 1.9 -#endif 1.10 } else { 1.11 nb_nics1 = nb_nics; 1.12 if (nb_nics1 > NE2000_NB_MAX)
2.1 --- a/tools/ioemu/target-i386-dm/Makefile Sat Nov 05 11:23:02 2005 +0100 2.2 +++ b/tools/ioemu/target-i386-dm/Makefile Sat Nov 05 11:26:29 2005 +0100 2.3 @@ -187,7 +187,7 @@ endif 2.4 2.5 ######################################################### 2.6 2.7 -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DAPIC_SUPPORT 2.8 +DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 2.9 LIBS+=-lm -L../../libxc -lxenctrl 2.10 ifndef CONFIG_USER_ONLY 2.11 LIBS+=-lz 2.12 @@ -245,7 +245,6 @@ endif 2.13 # must use static linking to avoid leaving stuff in virtual address space 2.14 VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o 2.15 VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o 2.16 -VL_OBJS+=ioapic.o 2.17 #VL_OBJS+= block-cloop.o 2.18 2.19 SOUND_HW = sb16.o
3.1 --- a/tools/ioemu/target-i386-dm/helper2.c Sat Nov 05 11:23:02 2005 +0100 3.2 +++ b/tools/ioemu/target-i386-dm/helper2.c Sat Nov 05 11:26:29 2005 +0100 3.3 @@ -456,17 +456,10 @@ int main_loop(void) 3.4 #endif 3.5 3.6 main_loop_wait(0); 3.7 -#ifdef APIC_SUPPORT 3.8 - ioapic_update_EOI(); 3.9 -#endif 3.10 tun_receive_handler(&rfds); 3.11 if ( FD_ISSET(evtchn_fd, &rfds) ) { 3.12 cpu_handle_ioreq(env); 3.13 } 3.14 -#ifdef APIC_SUPPORT 3.15 - if (ioapic_has_intr()) 3.16 - do_ioapic(); 3.17 -#endif 3.18 if (env->send_event) { 3.19 struct ioctl_evtchn_notify notify; 3.20 notify.port = ioreq_local_port;
4.1 --- a/xen/arch/x86/dm/i8259.c Sat Nov 05 11:23:02 2005 +0100 4.2 +++ b/xen/arch/x86/dm/i8259.c Sat Nov 05 11:26:29 2005 +0100 4.3 @@ -525,3 +525,16 @@ int is_pit_irq(struct vcpu *v, int irq, 4.4 4.5 return (irq == pit_vec); 4.6 } 4.7 + 4.8 +int is_irq_enabled(struct vcpu *v, int irq) 4.9 +{ 4.10 + struct vmx_virpic *vpic=&v->domain->arch.vmx_platform.vmx_pic; 4.11 + 4.12 + if ( irq & 8 ) { 4.13 + return !( (1 << (irq&7)) & vpic->pics[1].imr); 4.14 + } 4.15 + else { 4.16 + return !( (1 << irq) & vpic->pics[0].imr); 4.17 + } 4.18 +} 4.19 +
5.1 --- a/xen/arch/x86/vmx.c Sat Nov 05 11:23:02 2005 +0100 5.2 +++ b/xen/arch/x86/vmx.c Sat Nov 05 11:26:29 2005 +0100 5.3 @@ -43,6 +43,8 @@ 5.4 #endif 5.5 #include <public/sched.h> 5.6 #include <public/io/ioreq.h> 5.7 +#include <public/io/vmx_vpic.h> 5.8 +#include <public/io/vmx_vlapic.h> 5.9 5.10 int hvm_enabled; 5.11 5.12 @@ -85,6 +87,8 @@ void vmx_final_setup_guest(struct vcpu * 5.13 5.14 void vmx_relinquish_resources(struct vcpu *v) 5.15 { 5.16 + struct vmx_virpit *vpit; 5.17 + 5.18 if ( !VMX_DOMAIN(v) ) 5.19 return; 5.20 5.21 @@ -96,7 +100,12 @@ void vmx_relinquish_resources(struct vcp 5.22 5.23 destroy_vmcs(&v->arch.arch_vmx); 5.24 free_monitor_pagetable(v); 5.25 - rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer); 5.26 + vpit = &v->domain->arch.vmx_platform.vmx_pit; 5.27 + if ( vpit->ticking && active_ac_timer(&(vpit->pit_timer)) ) 5.28 + rem_ac_timer(&vpit->pit_timer); 5.29 + if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) { 5.30 + rem_ac_timer(&v->arch.arch_vmx.hlt_timer); 5.31 + } 5.32 if ( vmx_apic_support(v->domain) ) { 5.33 rem_ac_timer( &(VLAPIC(v)->vlapic_timer) ); 5.34 xfree( VLAPIC(v) ); 5.35 @@ -1521,12 +1530,24 @@ static inline void vmx_do_msr_write(stru 5.36 (unsigned long)regs->edx); 5.37 } 5.38 5.39 -volatile unsigned long do_hlt_count; 5.40 /* 5.41 * Need to use this exit to reschedule 5.42 */ 5.43 void vmx_vmexit_do_hlt(void) 5.44 { 5.45 + struct vcpu *v=current; 5.46 + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); 5.47 + s_time_t next_pit=-1,next_wakeup; 5.48 + 5.49 + if ( !v->vcpu_id ) { 5.50 + next_pit = get_pit_scheduled(v,vpit); 5.51 + } 5.52 + next_wakeup = get_apictime_scheduled(v); 5.53 + if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 ) { 5.54 + next_wakeup = next_pit; 5.55 + } 5.56 + if ( next_wakeup != - 1 ) 5.57 + set_ac_timer(¤t->arch.arch_vmx.hlt_timer, next_wakeup); 5.58 do_block(); 5.59 } 5.60
6.1 --- a/xen/arch/x86/vmx_intercept.c Sat Nov 05 11:23:02 2005 +0100 6.2 +++ b/xen/arch/x86/vmx_intercept.c Sat Nov 05 11:26:29 2005 +0100 6.3 @@ -317,27 +317,51 @@ int intercept_pit_io(ioreq_t *p) 6.4 return 0; 6.5 } 6.6 6.7 -/* hooks function for the PIT initialization response iopacket */ 6.8 -static void pit_timer_fn(void *data) 6.9 +/* hooks function for the HLT instruction emulation wakeup */ 6.10 +void hlt_timer_fn(void *data) 6.11 { 6.12 - struct vmx_virpit *vpit = data; 6.13 - s_time_t next; 6.14 + struct vcpu *v = data; 6.15 + 6.16 + evtchn_set_pending(v, iopacket_port(v->domain)); 6.17 +} 6.18 + 6.19 +static __inline__ void missed_ticks(struct vmx_virpit*vpit) 6.20 +{ 6.21 int missed_ticks; 6.22 6.23 missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period; 6.24 - 6.25 - /* Set the pending intr bit, and send evtchn notification to myself. */ 6.26 - vpit->pending_intr_nr++; /* already set, then count the pending intr */ 6.27 - evtchn_set_pending(vpit->v, iopacket_port(vpit->v->domain)); 6.28 - 6.29 - /* pick up missed timer tick */ 6.30 if ( missed_ticks > 0 ) { 6.31 vpit->pending_intr_nr += missed_ticks; 6.32 vpit->scheduled += missed_ticks * vpit->period; 6.33 } 6.34 - next = vpit->scheduled + vpit->period; 6.35 - set_ac_timer(&vpit->pit_timer, next); 6.36 - vpit->scheduled = next; 6.37 +} 6.38 + 6.39 +/* hooks function for the PIT when the guest is active */ 6.40 +static void pit_timer_fn(void *data) 6.41 +{ 6.42 + struct vcpu *v = data; 6.43 + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); 6.44 + 6.45 + /* pick up missed timer tick */ 6.46 + missed_ticks(vpit); 6.47 + 6.48 + vpit->pending_intr_nr++; 6.49 + if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) { 6.50 + vpit->scheduled += vpit->period; 6.51 + set_ac_timer(&vpit->pit_timer, vpit->scheduled); 6.52 + } 6.53 +} 6.54 + 6.55 +void pickup_deactive_ticks(struct vmx_virpit *vpit) 6.56 +{ 6.57 + 6.58 + if ( !active_ac_timer(&(vpit->pit_timer)) ) { 6.59 + /* pick up missed timer tick */ 6.60 + missed_ticks(vpit); 6.61 + 6.62 + vpit->scheduled += vpit->period; 6.63 + set_ac_timer(&vpit->pit_timer, vpit->scheduled); 6.64 + } 6.65 } 6.66 6.67 /* Only some PIT operations such as load init counter need a hypervisor hook. 6.68 @@ -359,8 +383,10 @@ void vmx_hooks_assist(struct vcpu *v) 6.69 reinit = 1; 6.70 6.71 } 6.72 - else 6.73 - init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, v->processor); 6.74 + else { 6.75 + init_ac_timer(&vpit->pit_timer, pit_timer_fn, v, v->processor); 6.76 + vpit->ticking = 1; 6.77 + } 6.78 6.79 /* init count for this channel */ 6.80 vpit->init_val = (p->u.data & 0xFFFF) ; 6.81 @@ -397,8 +423,6 @@ void vmx_hooks_assist(struct vcpu *v) 6.82 break; 6.83 } 6.84 6.85 - vpit->v = v; 6.86 - 6.87 vpit->scheduled = NOW() + vpit->period; 6.88 set_ac_timer(&vpit->pit_timer, vpit->scheduled); 6.89
7.1 --- a/xen/arch/x86/vmx_io.c Sat Nov 05 11:23:02 2005 +0100 7.2 +++ b/xen/arch/x86/vmx_io.c Sat Nov 05 11:26:29 2005 +0100 7.3 @@ -931,6 +931,7 @@ asmlinkage void vmx_intr_assist(void) 7.4 7.5 void vmx_do_resume(struct vcpu *v) 7.6 { 7.7 + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); 7.8 vmx_stts(); 7.9 7.10 if (event_pending(v)) { 7.11 @@ -939,6 +940,9 @@ void vmx_do_resume(struct vcpu *v) 7.12 if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) 7.13 vmx_wait_io(); 7.14 } 7.15 + /* pick up the elapsed PIT ticks and re-enable pit_timer */ 7.16 + if ( vpit->ticking ) 7.17 + pickup_deactive_ticks(vpit); 7.18 7.19 /* We can't resume the guest if we're waiting on I/O */ 7.20 ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
8.1 --- a/xen/arch/x86/vmx_vlapic.c Sat Nov 05 11:23:02 2005 +0100 8.2 +++ b/xen/arch/x86/vmx_vlapic.c Sat Nov 05 11:26:29 2005 +0100 8.3 @@ -60,11 +60,20 @@ int vlapic_find_highest_irr(struct vlapi 8.4 return result; 8.5 } 8.6 8.7 -inline int vmx_apic_support(struct domain *d) 8.8 +int vmx_apic_support(struct domain *d) 8.9 { 8.10 return d->arch.vmx_platform.lapic_enable; 8.11 } 8.12 8.13 +s_time_t get_apictime_scheduled(struct vcpu *v) 8.14 +{ 8.15 + struct vlapic *vlapic = VLAPIC(v); 8.16 + 8.17 + if ( !vmx_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) ) 8.18 + return -1; 8.19 + return vlapic->vlapic_timer.expires; 8.20 +} 8.21 + 8.22 int vlapic_find_highest_isr(struct vlapic *vlapic) 8.23 { 8.24 int result;
9.1 --- a/xen/arch/x86/vmx_vmcs.c Sat Nov 05 11:23:02 2005 +0100 9.2 +++ b/xen/arch/x86/vmx_vmcs.c Sat Nov 05 11:26:29 2005 +0100 9.3 @@ -321,6 +321,7 @@ static void vmx_do_launch(struct vcpu *v 9.4 vlapic_init(v); 9.5 9.6 vmx_set_host_env(v); 9.7 + init_ac_timer(&v->arch.arch_vmx.hlt_timer, hlt_timer_fn, v, v->processor); 9.8 9.9 error |= __vmwrite(GUEST_LDTR_SELECTOR, 0); 9.10 error |= __vmwrite(GUEST_LDTR_BASE, 0);
10.1 --- a/xen/include/asm-x86/vmx.h Sat Nov 05 11:23:02 2005 +0100 10.2 +++ b/xen/include/asm-x86/vmx.h Sat Nov 05 11:26:29 2005 +0100 10.3 @@ -530,5 +530,6 @@ void store_cpu_user_regs(struct cpu_user 10.4 10.5 enum { VMX_COPY_IN = 0, VMX_COPY_OUT }; 10.6 int vmx_copy(void *buf, unsigned long laddr, int size, int dir); 10.7 +void pickup_deactive_ticks(struct vmx_virpit *vpit); 10.8 10.9 #endif /* __ASM_X86_VMX_H__ */
11.1 --- a/xen/include/asm-x86/vmx_virpit.h Sat Nov 05 11:23:02 2005 +0100 11.2 +++ b/xen/include/asm-x86/vmx_virpit.h Sat Nov 05 11:26:29 2005 +0100 11.3 @@ -8,6 +8,7 @@ 11.4 #include <xen/errno.h> 11.5 #include <xen/ac_timer.h> 11.6 #include <asm/vmx_vmcs.h> 11.7 +#include <public/io/vmx_vpic.h> 11.8 11.9 #define PIT_FREQ 1193181 11.10 11.11 @@ -18,14 +19,15 @@ 11.12 11.13 struct vmx_virpit { 11.14 /* for simulation of counter 0 in mode 2*/ 11.15 - u32 period; /* pit frequency in ns */ 11.16 u64 period_cycles; /* pit frequency in cpu cycles */ 11.17 + u64 inject_point; /* the time inject virt intr */ 11.18 s_time_t scheduled; /* scheduled timer interrupt */ 11.19 + struct ac_timer pit_timer; /* periodic timer for mode 2*/ 11.20 unsigned int channel; /* the pit channel, counter 0~2 */ 11.21 unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ 11.22 - u64 inject_point; /* the time inject virt intr */ 11.23 - struct ac_timer pit_timer; /* periodic timer for mode 2*/ 11.24 + u32 period; /* pit frequency in ns */ 11.25 int first_injected; /* flag to prevent shadow window */ 11.26 + int ticking; /* indicating it is ticking */ 11.27 11.28 /* virtual PIT state for handle related I/O */ 11.29 int read_state; 11.30 @@ -34,10 +36,20 @@ struct vmx_virpit { 11.31 11.32 unsigned int count; /* the 16 bit channel count */ 11.33 unsigned int init_val; /* the init value for the counter */ 11.34 - struct vcpu *v; 11.35 }; 11.36 11.37 /* to hook the ioreq packet to get the PIT initializaiton info */ 11.38 extern void vmx_hooks_assist(struct vcpu *v); 11.39 11.40 +static __inline__ s_time_t get_pit_scheduled( 11.41 + struct vcpu *v, 11.42 + struct vmx_virpit *vpit) 11.43 +{ 11.44 + if ( is_irq_enabled(v, 0) ) { 11.45 + return vpit->scheduled; 11.46 + } 11.47 + else 11.48 + return -1; 11.49 +} 11.50 + 11.51 #endif /* _VMX_VIRPIT_H_ */
12.1 --- a/xen/include/asm-x86/vmx_vlapic.h Sat Nov 05 11:23:02 2005 +0100 12.2 +++ b/xen/include/asm-x86/vmx_vlapic.h Sat Nov 05 11:26:29 2005 +0100 12.3 @@ -239,7 +239,8 @@ struct vlapic* apic_round_robin(struct d 12.4 uint8_t dest_mode, 12.5 uint8_t vector, 12.6 uint32_t bitmap); 12.7 - 12.8 +s_time_t get_apictime_scheduled(struct vcpu *v); 12.9 int vmx_apic_support(struct domain *d); 12.10 12.11 #endif /* VMX_VLAPIC_H */ 12.12 +
13.1 --- a/xen/include/asm-x86/vmx_vmcs.h Sat Nov 05 11:23:02 2005 +0100 13.2 +++ b/xen/include/asm-x86/vmx_vmcs.h Sat Nov 05 11:26:29 2005 +0100 13.3 @@ -99,6 +99,7 @@ struct arch_vmx_struct { 13.4 void *io_bitmap_a, *io_bitmap_b; 13.5 struct vlapic *vlapic; 13.6 u64 tsc_offset; 13.7 + struct ac_timer hlt_timer; /* hlt ins emulation wakeup timer */ 13.8 }; 13.9 13.10 #define vmx_schedule_tail(next) \ 13.11 @@ -116,6 +117,7 @@ struct vmcs_struct *alloc_vmcs(void); 13.12 int modify_vmcs(struct arch_vmx_struct *arch_vmx, 13.13 struct cpu_user_regs *regs); 13.14 void destroy_vmcs(struct arch_vmx_struct *arch_vmx); 13.15 +void hlt_timer_fn(void *data); 13.16 13.17 #define VMCS_USE_HOST_ENV 1 13.18 #define VMCS_USE_SEPARATE_ENV 0
14.1 --- a/xen/include/public/io/vmx_vlapic.h Sat Nov 05 11:23:02 2005 +0100 14.2 +++ b/xen/include/public/io/vmx_vlapic.h Sat Nov 05 11:26:29 2005 +0100 14.3 @@ -28,14 +28,6 @@ 14.4 #define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint64_t))) 14.5 #define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint32_t))) 14.6 14.7 -struct vapic_bus_message{ 14.8 - uint8_t deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */ 14.9 - uint8_t level:1; /* level or edge */ 14.10 - uint8_t trig_mod:1; /* assert or disassert */ 14.11 - uint8_t reserved:2; 14.12 - uint8_t vector; 14.13 -}; 14.14 - 14.15 typedef struct { 14.16 /* interrupt for PIC and ext type IOAPIC interrupt */ 14.17 uint64_t vl_ext_intr[VLAPIC_INT_COUNT]; 14.18 @@ -51,7 +43,6 @@ typedef struct { 14.19 uint32_t vl_arb_id; 14.20 uint32_t vl_state; 14.21 uint32_t apic_msg_count; 14.22 - struct vapic_bus_message vl_apic_msg[24]; 14.23 } vlapic_info; 14.24 14.25 #endif /* _VMX_VLAPIC_H_ */
15.1 --- a/xen/include/public/io/vmx_vpic.h Sat Nov 05 11:23:02 2005 +0100 15.2 +++ b/xen/include/public/io/vmx_vpic.h Sat Nov 05 11:26:29 2005 +0100 15.3 @@ -77,6 +77,7 @@ uint32_t pic_intack_read(struct vmx_virp 15.4 void register_pic_io_hook (void); 15.5 int cpu_get_pic_interrupt(struct vcpu *v, int *type); 15.6 int is_pit_irq(struct vcpu *v, int irq, int type); 15.7 +int is_irq_enabled(struct vcpu *v, int irq); 15.8 void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs); 15.9 void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs); 15.10