[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] Create I/O context for MMIO/PIO processing in an
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 3fa8b914e2b50789262934bcfb313c95df9c3c31 # Parent fa143f374f3deac2c63b4f9585bb7e89d2d9614b [HVM] Create I/O context for MMIO/PIO processing in an off-stack structure. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> Signed-off-by: Xin B Li <xin.b.li@xxxxxxxxx> --- xen/arch/x86/hvm/io.c | 66 ++++++++++++++++++++--------------------- xen/arch/x86/hvm/platform.c | 19 ++++++----- xen/arch/x86/hvm/svm/svm.c | 27 +++++++++------- xen/arch/x86/hvm/vmx/vmx.c | 27 +++++++++------- xen/include/asm-x86/hvm/io.h | 4 +- xen/include/asm-x86/hvm/vcpu.h | 18 ++++++----- 6 files changed, 87 insertions(+), 74 deletions(-) diff -r fa143f374f3d -r 3fa8b914e2b5 xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/arch/x86/hvm/io.c Fri Jul 14 13:59:15 2006 +0100 @@ -360,19 +360,19 @@ static inline void set_eflags_PF(int siz } static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p, - struct mmio_op *mmio_opp) + struct hvm_io_op *pio_opp) { unsigned long old_eax; int sign = p->df ? -1 : 1; - if ( p->pdata_valid || (mmio_opp->flags & OVERLAP) ) + if ( p->pdata_valid || (pio_opp->flags & OVERLAP) ) { - if ( mmio_opp->flags & REPZ ) + if ( pio_opp->flags & REPZ ) regs->ecx -= p->count; if ( p->dir == IOREQ_READ ) { regs->edi += sign * p->count * p->size; - if ( mmio_opp->flags & OVERLAP ) + if ( pio_opp->flags & OVERLAP ) { unsigned long addr = regs->edi; if (hvm_realmode(current)) @@ -409,8 +409,8 @@ static void hvm_pio_assist(struct cpu_us } } -static void hvm_mmio_assist(struct vcpu *v, struct cpu_user_regs *regs, - ioreq_t *p, struct mmio_op *mmio_opp) +static void hvm_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p, + struct hvm_io_op *mmio_opp) { int sign = p->df ? -1 : 1; int size = -1, index = -1; @@ -657,51 +657,51 @@ static void hvm_mmio_assist(struct vcpu break; case INSTR_XCHG: - if (src & REGISTER) { - index = operand_index(src); - set_reg_value(size, index, 0, regs, p->u.data); - } else { - index = operand_index(dst); - set_reg_value(size, index, 0, regs, p->u.data); - } - break; - } - - hvm_load_cpu_guest_regs(v, regs); + if (src & REGISTER) { + index = operand_index(src); + set_reg_value(size, index, 0, regs, p->u.data); + } else { + index = operand_index(dst); + set_reg_value(size, index, 0, regs, p->u.data); + } + break; + } } void hvm_io_assist(struct vcpu *v) { vcpu_iodata_t *vio; ioreq_t *p; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - struct mmio_op *mmio_opp; - struct cpu_user_regs *inst_decoder_regs; - - mmio_opp = &v->arch.hvm_vcpu.mmio_op; - inst_decoder_regs = mmio_opp->inst_decoder_regs; + struct cpu_user_regs *regs; + struct hvm_io_op *io_opp; + + io_opp = &v->arch.hvm_vcpu.io_op; + regs = &io_opp->io_context; vio = get_vio(v->domain, v->vcpu_id); - if (vio == 0) { - HVM_DBG_LOG(DBG_LEVEL_1, - "bad shared page: %lx", (unsigned long) vio); - printf("bad shared page: %lx\n", (unsigned long) vio); + if ( vio == 0 ) { + printf("bad shared page: %lx\n", (unsigned long)vio); domain_crash_synchronous(); } p = &vio->vp_ioreq; /* clear IO wait HVM flag */ - if (test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags)) { - if (p->state == STATE_IORESP_READY) { + if ( test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) ) { + if ( p->state == STATE_IORESP_READY ) { p->state = STATE_INVALID; clear_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags); - if (p->type == IOREQ_TYPE_PIO) - hvm_pio_assist(regs, p, mmio_opp); - else - hvm_mmio_assist(v, regs, p, mmio_opp); + if ( p->type == IOREQ_TYPE_PIO ) + hvm_pio_assist(regs, p, io_opp); + else { + hvm_mmio_assist(regs, p, io_opp); + hvm_load_cpu_guest_regs(v, regs); + } + + /* Copy register changes back into current guest state. */ + memcpy(guest_cpu_user_regs(), regs, HVM_CONTEXT_STACK_BYTES); } /* else an interrupt send event raced us */ } diff -r fa143f374f3d -r 3fa8b914e2b5 xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/arch/x86/hvm/platform.c Fri Jul 14 13:59:15 2006 +0100 @@ -729,7 +729,7 @@ void send_mmio_req( ioreq_t *p; struct cpu_user_regs *regs; - regs = current->arch.hvm_vcpu.mmio_op.inst_decoder_regs; + regs = ¤t->arch.hvm_vcpu.io_op.io_context; vio = get_vio(v->domain, v->vcpu_id); if (vio == NULL) { @@ -777,7 +777,7 @@ void send_mmio_req( } static void mmio_operands(int type, unsigned long gpa, struct instruction *inst, - struct mmio_op *mmio_opp, struct cpu_user_regs *regs) + struct hvm_io_op *mmio_opp, struct cpu_user_regs *regs) { unsigned long value = 0; int index, size_reg; @@ -815,16 +815,19 @@ void handle_mmio(unsigned long va, unsig void handle_mmio(unsigned long va, unsigned long gpa) { unsigned long inst_addr; - struct mmio_op *mmio_opp; + struct hvm_io_op *mmio_opp; struct cpu_user_regs *regs; struct instruction mmio_inst; unsigned char inst[MAX_INST_LEN]; int i, realmode, ret, inst_len; struct vcpu *v = current; - mmio_opp = &v->arch.hvm_vcpu.mmio_op; - - regs = mmio_opp->inst_decoder_regs; + mmio_opp = &v->arch.hvm_vcpu.io_op; + regs = &mmio_opp->io_context; + + /* Copy current guest state into io instruction state structure. */ + memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); + hvm_store_cpu_guest_regs(v, regs, NULL); if ((inst_len = hvm_instruction_length(v)) <= 0) { @@ -1009,7 +1012,7 @@ void handle_mmio(unsigned long va, unsig unsigned long operand = mmio_inst.operand[0]; value = get_reg_value(operand_size(operand), operand_index(operand), 0, - mmio_opp->inst_decoder_regs); + regs); /* send the request and wait for the value */ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, mmio_inst.op_size, value, IOREQ_WRITE, 0); @@ -1019,7 +1022,7 @@ void handle_mmio(unsigned long va, unsig unsigned long operand = mmio_inst.operand[1]; value = get_reg_value(operand_size(operand), operand_index(operand), 0, - mmio_opp->inst_decoder_regs); + regs); /* send the request and wait for the value */ send_mmio_req(IOREQ_TYPE_XCHG, gpa, 1, mmio_inst.op_size, value, IOREQ_WRITE, 0); diff -r fa143f374f3d -r 3fa8b914e2b5 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Jul 14 13:59:15 2006 +0100 @@ -1374,18 +1374,24 @@ static inline int svm_get_io_address( } -static void svm_io_instruction(struct vcpu *v, struct cpu_user_regs *regs) -{ - struct mmio_op *mmio_opp; +static void svm_io_instruction(struct vcpu *v) +{ + struct cpu_user_regs *regs; + struct hvm_io_op *pio_opp; unsigned int port; unsigned int size, dir; ioio_info_t info; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; ASSERT(vmcb); - mmio_opp = ¤t->arch.hvm_vcpu.mmio_op; - mmio_opp->instr = INSTR_PIO; - mmio_opp->flags = 0; + pio_opp = ¤t->arch.hvm_vcpu.io_op; + pio_opp->instr = INSTR_PIO; + pio_opp->flags = 0; + + regs = &pio_opp->io_context; + + /* Copy current guest state into io instruction state structure. */ + memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); info.bytes = vmcb->exitinfo1; @@ -1421,7 +1427,7 @@ static void svm_io_instruction(struct vc /* "rep" prefix */ if (info.fields.rep) { - mmio_opp->flags |= REPZ; + pio_opp->flags |= REPZ; } else { @@ -1436,7 +1442,7 @@ static void svm_io_instruction(struct vc { unsigned long value = 0; - mmio_opp->flags |= OVERLAP; + pio_opp->flags |= OVERLAP; if (dir == IOREQ_WRITE) hvm_copy(&value, addr, size, HVM_COPY_IN); @@ -2785,9 +2791,6 @@ asmlinkage void svm_vmexit_handler(struc (unsigned long)regs.ecx, (unsigned long)regs.edx, (unsigned long)regs.esi, (unsigned long)regs.edi); - v->arch.hvm_vcpu.mmio_op.inst_decoder_regs = ®s; - -//printk("PF1\n"); if (!(error = svm_do_page_fault(va, ®s))) { /* Inject #PG using Interruption-Information Fields */ @@ -2936,7 +2939,7 @@ asmlinkage void svm_vmexit_handler(struc break; case VMEXIT_IOIO: - svm_io_instruction(v, ®s); + svm_io_instruction(v); break; case VMEXIT_MSR: diff -r fa143f374f3d -r 3fa8b914e2b5 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Jul 14 13:59:15 2006 +0100 @@ -1056,17 +1056,23 @@ extern void send_pio_req(struct cpu_user unsigned long count, int size, long value, int dir, int pvalid); -static void vmx_io_instruction(struct cpu_user_regs *regs, - unsigned long exit_qualification, unsigned long inst_len) -{ - struct mmio_op *mmio_opp; +static void vmx_io_instruction(unsigned long exit_qualification, + unsigned long inst_len) +{ + struct cpu_user_regs *regs; + struct hvm_io_op *pio_opp; unsigned long eip, cs, eflags; unsigned long port, size, dir; int vm86; - mmio_opp = ¤t->arch.hvm_vcpu.mmio_op; - mmio_opp->instr = INSTR_PIO; - mmio_opp->flags = 0; + pio_opp = ¤t->arch.hvm_vcpu.io_op; + pio_opp->instr = INSTR_PIO; + pio_opp->flags = 0; + + regs = &pio_opp->io_context; + + /* Copy current guest state into io instruction state structure. */ + memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); __vmread(GUEST_RIP, &eip); __vmread(GUEST_CS_SELECTOR, &cs); @@ -1100,7 +1106,7 @@ static void vmx_io_instruction(struct cp addr = dir == IOREQ_WRITE ? regs->esi : regs->edi; if (test_bit(5, &exit_qualification)) { /* "rep" prefix */ - mmio_opp->flags |= REPZ; + pio_opp->flags |= REPZ; count = vm86 ? regs->ecx & 0xFFFF : regs->ecx; } @@ -1111,7 +1117,7 @@ static void vmx_io_instruction(struct cp if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) { unsigned long value = 0; - mmio_opp->flags |= OVERLAP; + pio_opp->flags |= OVERLAP; if (dir == IOREQ_WRITE) hvm_copy(&value, addr, size, HVM_COPY_IN); send_pio_req(regs, port, 1, size, value, dir, 0); @@ -2206,7 +2212,6 @@ asmlinkage void vmx_vmexit_handler(struc (unsigned long)regs.eax, (unsigned long)regs.ebx, (unsigned long)regs.ecx, (unsigned long)regs.edx, (unsigned long)regs.esi, (unsigned long)regs.edi); - v->arch.hvm_vcpu.mmio_op.inst_decoder_regs = ®s; if (!(error = vmx_do_page_fault(va, ®s))) { /* @@ -2299,7 +2304,7 @@ asmlinkage void vmx_vmexit_handler(struc case EXIT_REASON_IO_INSTRUCTION: __vmread(EXIT_QUALIFICATION, &exit_qualification); __get_instruction_length(inst_len); - vmx_io_instruction(®s, exit_qualification, inst_len); + vmx_io_instruction(exit_qualification, inst_len); TRACE_VMEXIT(4,exit_qualification); break; case EXIT_REASON_MSR_READ: diff -r fa143f374f3d -r 3fa8b914e2b5 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/include/asm-x86/hvm/io.h Fri Jul 14 13:59:15 2006 +0100 @@ -80,12 +80,12 @@ struct instruction { #define MAX_INST_LEN 15 /* Maximum instruction length = 15 bytes */ -struct mmio_op { +struct hvm_io_op { int flags; int instr; /* instruction */ unsigned long operand[2]; /* operands */ unsigned long immediate; /* immediate portion */ - struct cpu_user_regs *inst_decoder_regs; /* current context */ + struct cpu_user_regs io_context; /* current context */ }; #define MAX_IO_HANDLER 8 diff -r fa143f374f3d -r 3fa8b914e2b5 xen/include/asm-x86/hvm/vcpu.h --- a/xen/include/asm-x86/hvm/vcpu.h Fri Jul 14 13:53:59 2006 +0100 +++ b/xen/include/asm-x86/hvm/vcpu.h Fri Jul 14 13:59:15 2006 +0100 @@ -29,17 +29,17 @@ #define HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI 1 struct hvm_vcpu { - unsigned long ioflags; - struct mmio_op mmio_op; - struct vlapic *vlapic; - s64 cache_tsc_offset; - u64 guest_time; + unsigned long ioflags; + struct hvm_io_op io_op; + struct vlapic *vlapic; + s64 cache_tsc_offset; + u64 guest_time; /* For AP startup */ - unsigned long init_sipi_sipi_state; + unsigned long init_sipi_sipi_state; /* Flags */ - int flag_dr_dirty; + int flag_dr_dirty; union { struct arch_vmx_struct vmx; @@ -47,7 +47,9 @@ struct hvm_vcpu { } u; }; -#define ARCH_HVM_IO_WAIT 1 /* Waiting for I/O completion */ +#define ARCH_HVM_IO_WAIT 1 /* Waiting for I/O completion */ + +#define HVM_CONTEXT_STACK_BYTES (offsetof(struct cpu_user_regs, error_code)) #endif /* __ASM_X86_HVM_VCPU_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |