Infrastructure for interrupt handling.
PATCH 8/10 Infrastructure for interrupt handling.
Infrastructure for interrupt handling.
- support interruptibility
- handle interrupt window exiting control appropriately
- Add ioapic device models imported from Bochs under LGPL
- generalize the interrupt architecture to support both PIC/APIC
This patch is necessary to fix several bugs on 32 bit VMX and prepares the ground for adding a local APIC device model in the hypervisor.
Signed-off-by Yunhong Jiang <[email protected]>
Signed-off-by Eddie Dong <[email protected]>
Signed-off-by Arun Sharma <[email protected]>
tools/ioemu/exec-all.h +2 -2
@@ -573,7 +573,7 @@ }#endif -//#define DEBUG_UNUSED_IOPORT -//#define DEBUG_IOPORT +#define DEBUG_UNUSED_IOPORT +#define DEBUG_IOPORT #define TARGET_VMX
tools/ioemu/hw/i8259.c +29 -0
@@ -22,12 +22,16 @@* THE SOFTWARE. */ #include "vl.h" +#include "xc.h" +#include <io/ioreq.h> /* debug PIC */ //#define DEBUG_PIC //#define DEBUG_IRQ_LATENCY #define DEBUG_IRQ_COUNT + +extern void pit_reset_vmx_vectors (); typedef struct PicState { uint8_t last_irr; /* edge detection */
@@ -121,6 +125,26 @@ } } +/* pic[1] is connected to pin2 of pic[0] */ +#define CASCADE_IRQ 2 + +static void shared_page_update () +{ +extern shared_iopage_t *shared_page; +uint8_t * pmask = (uint8_t *)&(shared_page->sp_global.pic_mask[0 ]); +int index; + + index = pics[0 ].irq_base/8 ; + pmask[index] = pics[0 ].imr; + index = pics[1 ].irq_base/8 ; + +if ( pics[0 ].imr & (1 <<CASCADE_IRQ ) ) { + pmask[index] =0xff ; + }else { + pmask[index] = pics[1 ].imr; + } +} +/* raise irq to CPU if necessary. must be called every time the active irq may change */ static void pic_update_irq (void )
@@ -150,14 +174,18 @@#endif cpu_interrupt (cpu_single_env,CPU_INTERRUPT_HARD ); } +shared_page_update (); }#ifdef DEBUG_IRQ_LATENCY int64_t irq_time[16 ];#endif +extern void ioapic_legacy_irq (int irq,int level); +void pic_set_irq (int irq,int level) { +ioapic_legacy_irq (irq, level);#if defined(DEBUG_PIC ) || defined(DEBUG_IRQ_COUNT )if (level != irq_level[irq]) {#if defined(DEBUG_PIC )
@@ -255,6 +283,7 @@ tmp = s->elcr_mask;memset (s,0 ,sizeof (PicState)); s->elcr_mask = tmp; +shared_page_update (); }static void pic_ioport_write (void *opaque,uint32_t addr,uint32_t val)
tools/ioemu/target-i386-dm/helper2.c +12 -7
@@ -320,7 +320,7 @@// Send a message on the event channel. Add the vector to the shared mem // page. - intr = &(shared_page->vcpu_iodata[0 ].vp_intr[0 ]); + intr = &(shared_page->sp_global.pic_intr[0 ]);atomic_set_bit (vector, intr);if (loglevel &CPU_LOG_INT )fprintf (logfile,"injecting vector: %x\n" , vector);
@@ -345,11 +345,11 @@FD_ZERO (&rfds);while (1 ) { -if (vm_running) { -if (shutdown_requested) { -break ; +if (vm_running) { +if (shutdown_requested) { +break ; + } } - }/* Wait up to one seconds. */ tv.tv_sec =0 ;
@@ -370,14 +370,19 @@#endif main_loop_wait (0 ); - +#ifdef APIC_SUPPORT +ioapic_update_EOI (); +#endif cpu_timer_handler (env);if (env->interrupt_request &CPU_INTERRUPT_HARD ) { env->interrupt_request &= ~CPU_INTERRUPT_HARD ; vector =cpu_get_pic_interrupt (env);do_interrupt (env, vector); } - +#ifdef APIC_SUPPORT +if (ioapic_has_intr ()) +do_ioapic (); +#endif if (env->send_event) {int ret; ret =xc_evtchn_send (xc_handle, ioreq_port);
xen/include/asm-x86/vmx.h +7 -2
@@ -339,14 +339,19 @@ return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG); } +static inline shared_iopage_t *get_sp (struct domain *d) +{ +return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va; +} +static inline vcpu_iodata_t *get_vio (struct domain *d,unsigned long cpu) { -return &((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->vcpu_iodata[cpu]; +return &get_sp (d)->vcpu_iodata[cpu]; }static inline int iopacket_port (struct domain *d) { -return ((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->sp_global.eport; +return get_sp (d)->sp_global.eport; }#endif /* __ASM_X86_VMX_H__ */
xen/arch/x86/vmx_vmcs.c +2 -0
@@ -153,6 +153,8 @@ p =map_domain_page (mpfn); d->domain->arch.vmx_platform.shared_page_va = (unsigned long )p; +VMX_DBG_LOG (DBG_LEVEL_1 ,"eport: %x\n" ,iopacket_port (d->domain)); +clear_bit (iopacket_port (d->domain), &d->domain->shared_info->evtchn_mask[0 ]);
xen/include/asm-x86/vmx_virpit.h +1 -1
@@ -20,7 +20,7 @@int vector;/* the pit irq vector */ unsigned int period;/* the frequency. e.g. 10ms*/ unsigned int channel;/* the pit channel, counter 0~2 */ -unsigned long *intr_bitmap; +u64 *intr_bitmap;unsigned int pending_intr_nr;/* the couner for pending timer interrupts */ unsigned long long inject_point;/* the time inject virt intr */ struct ac_timer pit_timer;/* periodic timer for mode 2*/
tools/ioemu/target-i386-dm/Makefile +2 -1
@@ -188,7 +188,7 @@ ######################################################### -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DAPIC_SUPPORT LIBS+=-lm -L../../libxc -lxc ifndef CONFIG_USER_ONLY LIBS+=-lz
@@ -246,6 +246,7 @@ # must use static linking to avoid leaving stuff in virtual address space VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o +VL_OBJS+=ioapic.o #VL_OBJS+= block-cloop.o SOUND_HW = sb16.o
tools/ioemu/hw/pc.c +3 -0
@@ -543,6 +543,9 @@pci_ne2000_init (pci_bus, &nd_table[i]); }pci_piix3_ide_init (pci_bus, bs_table); +#ifdef APIC_SUPPORT +IOAPICInit (); +#endif }else { nb_nics1 = nb_nics;if (nb_nics1 >NE2000_NB_MAX )
xen/arch/x86/vmx_io.c +156 -73
260 lines not on this page · raw message
xen/arch/x86/vmx_intercept.c +2 -1
@@ -213,7 +213,8 @@ {vcpu_iodata_t * vio =get_vio (d->domain, d->vcpu_id);ioreq_t *p = &vio->vp_ioreq; -unsigned long *intr = &(vio->vp_intr[0 ]); +shared_iopage_t *sp =get_sp (d->domain); +u64 *intr = &(sp->sp_global.pic_intr[0 ]);struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);int rw_mode;
tools/ioemu/hw/pci.c +15 -1
@@ -53,6 +53,7 @@static int pci_irq_index;static uint32_t pci_irq_levels[4 ][PCI_IRQ_WORDS ];static PCIBus *first_bus; +extern FILE *logfile;static PCIBus *pci_register_bus (void ) {
@@ -569,13 +570,26 @@ pci_conf[0xae ] =0x00 ; } +#define PIIX_CONFIG_XBCS 0x4f +void piix3_write_config (PCIDevice *d, +uint32_t address,uint32_t val,int len) +{ +if ((PIIX3State *)d != piix3_state){ +fprintf (logfile,"piix3_write_config: error PCIDevice\n" ); +return ; + } + +pci_default_write_config (d, address, val, len); +} + +void piix3_init (PCIBus *bus) {PIIX3State *d;uint8_t *pci_conf; d = (PIIX3State *)pci_register_device (bus,"PIIX3" ,sizeof (PIIX3State), --1 ,NULL ,NULL ); +-1 ,NULL , piix3_write_config);register_savevm ("PIIX3" ,0 ,1 , generic_pci_save, generic_pci_load, d); piix3_state = d;
xen/include/public/io/ioreq.h +3 -6
@@ -49,14 +49,11 @@#define MAX_VECTOR 256#define BITS_PER_BYTE 8 -#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(unsigned long))) +#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64))) -/* We only track the master PIC state here */ typedef struct { -uint16_t irr;/* interrupt request register */ -uint16_t imr;/* interrupt mask register */ -uint16_t isr;/* interrupt service register */ - +u64 pic_intr[INTR_LEN ]; +u64 pic_mask[INTR_LEN ];int eport;/* Event channel port */ }global_iodata_t ;
tools/ioemu/hw/ioapic.c new file +704 -0
704 lines not on this page · raw message
tools/ioemu/hw/ioapic.h new file +128 -0
128 lines not on this page · raw message
xen/include/public/io/vmx_vlapic.h new file +57 -0
57 lines not on this page · raw message