From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Vivier Subject: [PATCH 5/5] svm.c uses x86_decode_prefix() instead of io_address() and io_get_override(). Date: Wed, 01 Aug 2007 11:22:47 +0200 Message-ID: <46B050E7.7080908@bull.net> References: <46B04CCA.2010503@bull.net> <46B04DD6.7010702@bull.net> <46B04EB9.5010103@bull.net> <46B04F56.60607@bull.net> <46B0501C.6060409@bull.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1629793143==" To: kvm-devel Return-path: In-Reply-To: <46B0501C.6060409-6ktuUTfB/bM@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --===============1629793143== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigA14283568AF30D50DF739127" This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigA14283568AF30D50DF739127 Content-Type: multipart/mixed; boundary="------------030505030906020305040602" This is a multi-part message in MIME format. --------------030505030906020305040602 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable svm.c uses x86_decode_prefix() instead of io_address() and io_get_overrid= e(). *** WARNING: the SVM part has not been tested because I don't have any AM= D system. *** Signed-off-by: Laurent Vivier --=20 ------------- Laurent.Vivier-6ktuUTfB/bM@public.gmane.org -------------- "Software is hard" - Donald Knuth --------------030505030906020305040602 Content-Type: text/plain; name="svm-decode_prefix" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="svm-decode_prefix" Index: kvm/drivers/kvm/svm.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- kvm.orig/drivers/kvm/svm.c 2007-08-01 10:10:24.000000000 +0200 +++ kvm/drivers/kvm/svm.c 2007-08-01 10:37:30.000000000 +0200 @@ -98,20 +98,6 @@ return svm_features & feat; } =20 -static unsigned get_addr_size(struct vcpu_svm *svm) -{ - struct vmcb_save_area *sa =3D &svm->vmcb->save; - u16 cs_attrib; - - if (!(sa->cr0 & X86_CR0_PE) || (sa->rflags & X86_EFLAGS_VM)) - return 2; - - cs_attrib =3D sa->cs.attrib; - - return (cs_attrib & SVM_SELECTOR_L_MASK) ? 8 : - (cs_attrib & SVM_SELECTOR_DB_MASK) ? 4 : 2; -} - static inline u8 pop_irq(struct kvm_vcpu *vcpu) { int word_index =3D __ffs(vcpu->irq_summary); @@ -996,112 +982,6 @@ return 0; } =20 -static int io_get_override(struct vcpu_svm *svm, - struct vmcb_seg **seg, - int *addr_override) -{ - u8 inst[MAX_INST_SIZE]; - unsigned ins_length; - gva_t rip; - int i; - - rip =3D svm->vmcb->save.rip; - ins_length =3D svm->next_rip - rip; - rip +=3D svm->vmcb->save.cs.base; - - if (ins_length > MAX_INST_SIZE) - printk(KERN_DEBUG - "%s: inst length err, cs base 0x%llx rip 0x%llx " - "next rip 0x%llx ins_length %u\n", - __FUNCTION__, - svm->vmcb->save.cs.base, - svm->vmcb->save.rip, - svm->vmcb->control.exit_info_2, - ins_length); - - if (emulator_read_std(rip, inst, ins_length, &svm->vcpu) - !=3D X86EMUL_CONTINUE) - /* #PF */ - return 0; - - *addr_override =3D 0; - *seg =3D NULL; - for (i =3D 0; i < ins_length; i++) - switch (inst[i]) { - case 0xf0: - case 0xf2: - case 0xf3: - case 0x66: - continue; - case 0x67: - *addr_override =3D 1; - continue; - case 0x2e: - *seg =3D &svm->vmcb->save.cs; - continue; - case 0x36: - *seg =3D &svm->vmcb->save.ss; - continue; - case 0x3e: - *seg =3D &svm->vmcb->save.ds; - continue; - case 0x26: - *seg =3D &svm->vmcb->save.es; - continue; - case 0x64: - *seg =3D &svm->vmcb->save.fs; - continue; - case 0x65: - *seg =3D &svm->vmcb->save.gs; - continue; - default: - return 1; - } - printk(KERN_DEBUG "%s: unexpected\n", __FUNCTION__); - return 0; -} - -static unsigned long io_address(struct vcpu_svm *svm, int ins, gva_t *ad= dress) -{ - unsigned long addr_mask; - unsigned long *reg; - struct vmcb_seg *seg; - int addr_override; - struct vmcb_save_area *save_area =3D &svm->vmcb->save; - u16 cs_attrib =3D save_area->cs.attrib; - unsigned addr_size =3D get_addr_size(svm); - - if (!io_get_override(svm, &seg, &addr_override)) - return 0; - - if (addr_override) - addr_size =3D (addr_size =3D=3D 2) ? 4: (addr_size >> 1); - - if (ins) { - reg =3D &svm->vcpu.regs[VCPU_REGS_RDI]; - seg =3D &svm->vmcb->save.es; - } else { - reg =3D &svm->vcpu.regs[VCPU_REGS_RSI]; - seg =3D (seg) ? seg : &svm->vmcb->save.ds; - } - - addr_mask =3D ~0ULL >> (64 - (addr_size * 8)); - - if ((cs_attrib & SVM_SELECTOR_L_MASK) && - !(svm->vmcb->save.rflags & X86_EFLAGS_VM)) { - *address =3D (*reg & addr_mask); - return addr_mask; - } - - if (!(seg->attrib & SVM_SELECTOR_P_SHIFT)) { - svm_inject_gp(&svm->vcpu, 0); - return 0; - } - - *address =3D (*reg & addr_mask) + seg->base; - return addr_mask; -} - static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run= ) { u32 io_info =3D svm->vmcb->control.exit_info_1; //address size bug? @@ -1109,6 +989,7 @@ unsigned port; unsigned long count; gva_t address =3D 0; + struct vmcb_save_area *sa =3D &svm->vmcb->save; =20 ++svm->vcpu.stat.io_exits; =20 @@ -1120,21 +1001,96 @@ string =3D (io_info & SVM_IOIO_STR_MASK) !=3D 0; rep =3D (io_info & SVM_IOIO_REP_MASK) !=3D 0; count =3D 1; - down =3D (svm->vmcb->save.rflags & X86_EFLAGS_DF) !=3D 0; + down =3D (sa->rflags & X86_EFLAGS_DF) !=3D 0; =20 if (string) { - unsigned addr_mask; + int mode; + u8 inst[MAX_INST_SIZE]; + unsigned ins_length; + gva_t rip; + struct x86_prefix prefix; + u16 cs_ar =3D sa->cs.attrib; + unsigned long addr_mask; + + mode =3D (!(sa->cr0 & X86_CR0_PE) || + (sa->rflags & X86_EFLAGS_VM)) ? + X86EMUL_MODE_REAL : (cs_ar & SVM_SELECTOR_L_MASK) + ? X86EMUL_MODE_PROT64 : (cs_ar & SVM_SELECTOR_DB_MASK) + ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; + + rip =3D svm->vmcb->save.rip; + ins_length =3D svm->vmcb->save.rip - rip; + if (mode !=3D X86EMUL_MODE_PROT64) + rip +=3D svm->vmcb->save.cs.base; + + if (ins_length > MAX_INST_SIZE) + printk(KERN_DEBUG + "%s: inst length err, cs base 0x%llx rip 0x%llx " + "next rip 0x%llx ins_length %u\n", + __FUNCTION__, + svm->vmcb->save.cs.base, + svm->vmcb->save.rip, + svm->vmcb->control.exit_info_2, + ins_length); =20 - addr_mask =3D io_address(svm, in, &address); - if (!addr_mask) { - printk(KERN_DEBUG "%s: get io address failed\n", - __FUNCTION__); + if (emulator_read_std(rip, inst, ins_length, &svm->vcpu) + !=3D X86EMUL_CONTINUE) + return 1; + + prefix.override_base =3D -1; + if (x86_decode_prefix(mode, (u8*)&inst, &prefix) =3D=3D -1) return 1; - } =20 + addr_mask =3D (~0ULL >> (64 - (prefix.ad_bytes <<3))); if (rep) count =3D svm->vcpu.regs[VCPU_REGS_RCX] & addr_mask; + + if (in) + address =3D svm->vcpu.regs[VCPU_REGS_RDI]; + else + address =3D svm->vcpu.regs[VCPU_REGS_RSI]; + + address &=3D addr_mask; + + if (mode !=3D X86EMUL_MODE_PROT64) { + struct vmcb_seg *seg; + + if (in) + seg =3D &svm->vmcb->save.es; + else switch(prefix.override_base) { + case -1: + case X86EMUL_BASE_DS: + seg =3D &svm->vmcb->save.ds; + break; + case X86EMUL_BASE_CS: + seg =3D &svm->vmcb->save.cs; + break; + case X86EMUL_BASE_ES: + seg =3D &svm->vmcb->save.es; + break; + case X86EMUL_BASE_GS: + seg =3D &svm->vmcb->save.gs; + break; + case X86EMUL_BASE_SS: + seg =3D &svm->vmcb->save.ss; + break; + default: + printk(KERN_DEBUG "%s: unexpected\n", + __FUNCTION__); + return 1; + } + + if (seg->attrib & SVM_SELECTOR_P_SHIFT) { + svm_inject_gp(&svm->vcpu, 0); + printk(KERN_DEBUG "%s: get io address failed\n", + __FUNCTION__); + return 1; + } + + address +=3D seg->base; + } } + return kvm_setup_pio(&svm->vcpu, kvm_run, in, size, count, string, down, address, rep, port); } Index: kvm/drivers/kvm/.svm.c.swp =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Binary files kvm.orig/drivers/kvm/.svm.c.swp 2007-08-01 10:12:34.00000000= 0 +0200 and /dev/null 1970-01-01 00:00:00.000000000 +0000 differ --------------030505030906020305040602-- --------------enigA14283568AF30D50DF739127 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.7 (GNU/Linux) iD8DBQFGsFDn9Kffa9pFVzwRAjlGAKCPoMU9G/4+C7zcDdpwIAOjyeIGPACfdTqq Po0whUY0opXnXtUMDBcRKPw= =Xd2q -----END PGP SIGNATURE----- --------------enigA14283568AF30D50DF739127-- --===============1629793143== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --===============1629793143== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --===============1629793143==--