[PATCH] uio/uio_pci_generic: fix error return code in probe()
From: Wei Yongjun yongjun_...@trendmicro.com.cn Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- drivers/uio/uio_pci_generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index 077ae12..d0b508b 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -91,7 +91,8 @@ static int probe(struct pci_dev *pdev, gdev-info.handler = irqhandler; gdev-pdev = pdev; - if (uio_register_device(pdev-dev, gdev-info)) + err = uio_register_device(pdev-dev, gdev-info); + if (err) goto err_register; pci_set_drvdata(pdev, gdev); -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: add missing misc_deregister() on error in kvm_init()
From: Wei Yongjun yongjun_...@trendmicro.com.cn Add the missing misc_deregister() before return from kvm_init() in the debugfs init error handling case. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- virt/kvm/kvm_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f18013f..3eb4d16 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3012,6 +3012,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, out_undebugfs: unregister_syscore_ops(kvm_syscore_ops); + misc_deregister(kvm_dev); out_unreg: kvm_async_pf_deinit(); out_free: -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH -next] kvm/ppc/mpic: fix missing unlock in set_base_addr()
From: Wei Yongjun yongjun_...@trendmicro.com.cn Add the missing unlock before return from function set_base_addr() when disables the mapping. Introduced by commit 5df554ad5b7522ea62b0ff9d5be35183494efc21 (kvm/ppc/mpic: in-kernel MPIC emulation) Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- arch/powerpc/kvm/mpic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index f3148f8..0047a70 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1475,8 +1475,8 @@ static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr) map_mmio(opp); - mutex_unlock(opp-kvm-slots_lock); out: + mutex_unlock(opp-kvm-slots_lock); return 0; } -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH -next] kvm/ppc/mpic: fix missing unlock in set_base_addr()
From: Wei Yongjun yongjun_...@trendmicro.com.cn Add the missing unlock before return from function set_base_addr() when disables the mapping. Introduced by commit 5df554ad5b7522ea62b0ff9d5be35183494efc21 (kvm/ppc/mpic: in-kernel MPIC emulation) Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- arch/powerpc/kvm/mpic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index f3148f8..0047a70 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1475,8 +1475,8 @@ static int set_base_addr(struct openpic *opp, struct kvm_device_attr *attr) map_mmio(opp); - mutex_unlock(opp-kvm-slots_lock); out: + mutex_unlock(opp-kvm-slots_lock); return 0; } -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86: fix error return code in kvm_arch_vcpu_init()
From: Wei Yongjun yongjun_...@trendmicro.com.cn Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- arch/x86/kvm/x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e172132..c45d656 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6706,8 +6706,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) } vcpu-arch.mcg_cap = KVM_MAX_MCE_BANKS; - if (!zalloc_cpumask_var(vcpu-arch.wbinvd_dirty_mask, GFP_KERNEL)) + if (!zalloc_cpumask_var(vcpu-arch.wbinvd_dirty_mask, GFP_KERNEL)) { + r = -ENOMEM; goto fail_free_mce_banks; + } r = fx_init(vcpu); if (r) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] vfio: make local function vfio_pci_intx_unmask_handler() static
From: Wei Yongjun yongjun_...@trendmicro.com.cn vfio_pci_intx_unmask_handler() was not declared. It should be static. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- drivers/vfio/pci/vfio_pci_intrs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index a965091..865175e 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -287,7 +287,8 @@ void vfio_pci_intx_mask(struct vfio_pci_device *vdev) * a signal is necessary, which can then be handled via a work queue * or directly depending on the caller. */ -int vfio_pci_intx_unmask_handler(struct vfio_pci_device *vdev, void *unused) +static int vfio_pci_intx_unmask_handler(struct vfio_pci_device *vdev, + void *unused) { struct pci_dev *pdev = vdev-pdev; unsigned long flags; -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH -next] vhost-blk: remove unused variable
From: Wei Yongjun yongjun_...@trendmicro.com.cn The variable vq is initialized but never used otherwise, so remove the unused variable. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- drivers/vhost/blk.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/vhost/blk.c b/drivers/vhost/blk.c index 658c5f9..d9b245b 100644 --- a/drivers/vhost/blk.c +++ b/drivers/vhost/blk.c @@ -419,8 +419,6 @@ static void vhost_blk_handle_guest_kick(struct vhost_work *work) /* Host kick us for I/O completion */ static void vhost_blk_handle_host_kick(struct vhost_work *work) { - - struct vhost_virtqueue *vq; struct vhost_blk_req *req; struct llist_node *llnode; struct vhost_blk *blk; @@ -429,7 +427,6 @@ static void vhost_blk_handle_host_kick(struct vhost_work *work) int ret; blk = container_of(work, struct vhost_blk, work); - vq = blk-vq; llnode = llist_del_all(blk-llhead); added = false; -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH -next] tcm_vhost: remove unused variable in vhost_scsi_allocate_cmd()
From: Wei Yongjun yongjun_...@trendmicro.com.cn The variable se_sess is initialized but never used otherwise, so remove the unused variable. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- drivers/vhost/tcm_vhost.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 23c138f..551fff0 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -415,14 +415,12 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( { struct tcm_vhost_cmd *tv_cmd; struct tcm_vhost_nexus *tv_nexus; - struct se_session *se_sess; tv_nexus = tv_tpg-tpg_nexus; if (!tv_nexus) { pr_err(Unable to locate active struct tcm_vhost_nexus\n); return ERR_PTR(-EIO); } - se_sess = tv_nexus-tvn_se_sess; tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); if (!tv_cmd) { -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH -next] kvm tools: remove duplicated include from builtin-setup.c
From: Wei Yongjun yongjun_...@trendmicro.com.cn Remove duplicated include. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- tools/kvm/builtin-setup.c | 4 1 file changed, 4 deletions(-) diff --git a/tools/kvm/builtin-setup.c b/tools/kvm/builtin-setup.c index 1b865b7..c5b0566 100644 --- a/tools/kvm/builtin-setup.c +++ b/tools/kvm/builtin-setup.c @@ -13,11 +13,7 @@ #include string.h #include unistd.h #include stdio.h -#include sys/types.h #include sys/mman.h -#include sys/stat.h -#include string.h -#include unistd.h #include fcntl.h extern char _binary_guest_init_start; -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] vhost: remove duplicated include from tcm_vhost.c
From: Wei Yongjun yongjun_...@trendmicro.com.cn From: Wei Yongjun yongjun_...@trendmicro.com.cn Remove duplicated include. Signed-off-by: Wei Yongjun yongjun_...@trendmicro.com.cn --- drivers/vhost/tcm_vhost.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index fb36654..587ca7e 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -45,7 +45,6 @@ #include target/target_core_fabric_configfs.h #include target/target_core_configfs.h #include target/configfs_macros.h -#include linux/vhost.h #include linux/virtio_net.h /* TODO vhost.h currently depends on this */ #include linux/virtio_scsi.h -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] kvm: remove useless function define kvm_inject_pit_timer_irqs()
格式好像有问题,你用的什么邮件客户端?你设置了80个字符自动换行? 把邮件保存了,在用git am能够打上去么? 改好了先重新发送一个给我。 发出来应该是这样的: -- diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index 46d08ca..9f3cea3 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -51,7 +51,6 @@ struct kvm_pit { #define KVM_MAX_PIT_INTR_INTERVAL HZ / 100 #define KVM_PIT_CHANNEL_MASK 0x3 -void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start); struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags); void kvm_free_pit(struct kvm *kvm); - 于 2011年03月03日 13:18, Duan Jiong 写道: From 19d8130e2fabd8a36fc8183749efaf1c0fdcd225 Mon Sep 17 00:00:00 2001 From: Duan Jiong djduanji...@gmail.com Date: Wed, 2 Mar 2011 17:18:57 +0800 Just remove useless function define kvm_inject_pit_timer_irqs() from file arch/x86/kvm/i8254.h Signed-off-by:Duan Jiongdjduanji...@gmail.com --- arch/x86/kvm/i8254.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index 46d08ca..9f3cea3 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -51,7 +51,6 @@ struct kvm_pit { #define KVM_MAX_PIT_INTR_INTERVAL HZ / 100 #define KVM_PIT_CHANNEL_MASK 0x3 -void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start); struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags); void kvm_free_pit(struct kvm *kvm); -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] kvm: remove useless function define kvm_inject_pit_timer_irqs()
I am sorry for mail to wrong address, please ignore this mail, thanks. --snip-- ... From 19d8130e2fabd8a36fc8183749efaf1c0fdcd225 Mon Sep 17 00:00:00 2001 From: Duan Jiong djduanji...@gmail.com Date: Wed, 2 Mar 2011 17:18:57 +0800 Just remove useless function define kvm_inject_pit_timer_irqs() from file arch/x86/kvm/i8254.h Signed-off-by:Duan Jiongdjduanji...@gmail.com --- arch/x86/kvm/i8254.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index 46d08ca..9f3cea3 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -51,7 +51,6 @@ struct kvm_pit { #define KVM_MAX_PIT_INTR_INTERVAL HZ / 100 #define KVM_PIT_CHANNEL_MASK 0x3 -void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start); struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags); void kvm_free_pit(struct kvm *kvm); -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] [qemu-kvm-next-tree] fix compile error of hw/device-assignment.c
Fix the following compile error in next tree: CCx86_64-softmmu/device-assignment.o hw/device-assignment.c: In function ‘assigned_device_pci_cap_init’: hw/device-assignment.c:1463: error: ‘PCI_PM_CTRL_NO_SOFT_RST’ undeclared (first use in this function) hw/device-assignment.c:1463: error: (Each undeclared identifier is reported only once hw/device-assignment.c:1463: error: for each function it appears in.) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- hw/device-assignment.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 50c6408..8446cd4 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1460,7 +1460,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) /* assign_device will bring the device up to D0, so we don't need * to worry about doing that ourselves here. */ pci_set_word(pci_dev-config + pos + PCI_PM_CTRL, - PCI_PM_CTRL_NO_SOFT_RST); + PCI_PM_CTRL_NO_SOFT_RESET); pci_set_byte(pci_dev-config + pos + PCI_PM_PPB_EXTENSIONS, 0); pci_set_byte(pci_dev-config + pos + PCI_PM_DATA_REGISTER, 0); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/8] KVM: x86 emulator: simplify instruction decode flags for opcodes C0-DF
Use the new byte/word dual opcode decode. Signed-off-by: Avi Kivity a...@redhat.com --- arch/x86/kvm/emulate.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 935f98e..2610fc5 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2466,17 +2466,16 @@ static struct opcode opcode_table[256] = { /* 0xB8 - 0xBF */ X8(D(DstReg | SrcImm | Mov)), /* 0xC0 - 0xC7 */ - D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), + D2bv(DstMem | SrcImm | ModRM), 0xC1 takes imm8 as the source operand. So D2bv can not be used here. I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), D(ImplicitOps | Stack), D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), - D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), + D2bv(DstMem | SrcImm | ModRM | Mov), /* 0xC8 - 0xCF */ N, N, N, D(ImplicitOps | Stack), D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps), /* 0xD0 - 0xD7 */ - D(ByteOp | DstMem | SrcOne | ModRM), D(DstMem | SrcOne | ModRM), - D(ByteOp | DstMem | ModRM), D(DstMem | ModRM), + D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM), N, N, N, N, /* 0xD8 - 0xDF */ N, N, N, N, N, N, N, N, -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 6/8] KVM: x86 emulator: simplify instruction decode flags for opcodes C0-DF
Use the new byte/word dual opcode decode. Signed-off-by: Avi Kivity a...@redhat.com --- arch/x86/kvm/emulate.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 935f98e..2610fc5 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2466,17 +2466,16 @@ static struct opcode opcode_table[256] = { /* 0xB8 - 0xBF */ X8(D(DstReg | SrcImm | Mov)), /* 0xC0 - 0xC7 */ -D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), +D2bv(DstMem | SrcImm | ModRM), 0xC1 takes imm8 as the source operand. So D2bv can not be used here. Maybe we can used D2bv(DstMem | SrcImmByte | ModRM). I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), D(ImplicitOps | Stack), D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), -D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), +D2bv(DstMem | SrcImm | ModRM | Mov), /* 0xC8 - 0xCF */ N, N, N, D(ImplicitOps | Stack), D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps), /* 0xD0 - 0xD7 */ -D(ByteOp | DstMem | SrcOne | ModRM), D(DstMem | SrcOne | ModRM), -D(ByteOp | DstMem | ModRM), D(DstMem | ModRM), +D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM), N, N, N, N, /* 0xD8 - 0xDF */ N, N, N, N, N, N, N, N, -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add CALL FAR instruction emulation (opcode 9a)
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 26f69c2..e5f7f5c 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2487,7 +2487,7 @@ static struct opcode opcode_table[256] = { X8(D(SrcAcc | DstReg)), /* 0x98 - 0x9F */ D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd), - D(SrcImmFAddr | No64), N, + I(SrcImmFAddr | No64, em_call_far), N, D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N, /* 0xA0 - 0xA7 */ D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs), -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Add realmode test for CALL FAR IMM instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index a833829..2e12680 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -437,6 +437,9 @@ void test_call(void) ret\n\t 2:\t); MK_INSN(call_far1, lcallw *(%ebx)\n\t); + MK_INSN(call_far2, .byte 0x9a\n\t + .word retf\n\t + .word 0x00\n\t); MK_INSN(ret_imm,sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b); exec_in_big_real_mode(insn_call1); @@ -453,6 +456,9 @@ void test_call(void) exec_in_big_real_mode(insn_call_far1); report(call far 1, 0, 1); + exec_in_big_real_mode(insn_call_far2); + report(call far 2, 0, 1); + exec_in_big_real_mode(insn_ret_imm); report(ret imm 1, 0, 1); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Add realmode test for CALL FAR IMM instruction
On 08/25/2010 09:16 AM, Wei Yongjun wrote: Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index a833829..2e12680 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -437,6 +437,9 @@ void test_call(void) ret\n\t 2:\t); MK_INSN(call_far1, lcallw *(%ebx)\n\t); +MK_INSN(call_far2, .byte 0x9a\n\t +.word retf\n\t +.word 0x00\n\t); Why .byte encoding? won't lcallw $0, $retf (or the other way round) work? Oh, it works, I will fix this. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] Add realmode test for CALL FAR IMM instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index a833829..d171a56 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -437,6 +437,7 @@ void test_call(void) ret\n\t 2:\t); MK_INSN(call_far1, lcallw *(%ebx)\n\t); + MK_INSN(call_far2, lcallw $0, $retf\n\t); MK_INSN(ret_imm,sub $10, %sp; jmp 2f; 1: retw $10; 2: callw 1b); exec_in_big_real_mode(insn_call1); @@ -453,6 +454,9 @@ void test_call(void) exec_in_big_real_mode(insn_call_far1); report(call far 1, 0, 1); + exec_in_big_real_mode(insn_call_far2); + report(call far 2, 0, 1); + exec_in_big_real_mode(insn_ret_imm); report(ret imm 1, 0, 1); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Add realmode test for LDS/LES/LFS/LGS/LSS instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c | 59 1 files changed, 59 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index b69e474..8c771fc 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1184,6 +1184,64 @@ void test_cwd_cdq() outregs.eax == 0x1000 outregs.edx == 0); } +static struct { +void *address; +unsigned short sel; +} __attribute__((packed)) desc = { + (void *)0x1234, + 0x10, +}; + +void test_lds_lss() +{ + inregs = (struct regs){ .ebx = (unsigned long)desc }; + + MK_INSN(lds, push %ds\n\t +lds (%ebx), %eax\n\t +mov %ds, %ebx\n\t +pop %ds\n\t); + exec_in_big_real_mode(insn_lds); + report(lds, R_AX | R_BX, + outregs.eax == (unsigned long)desc.address + outregs.ebx == desc.sel); + + MK_INSN(les, push %es\n\t +les (%ebx), %eax\n\t +mov %es, %ebx\n\t +pop %es\n\t); + exec_in_big_real_mode(insn_les); + report(les, R_AX | R_BX, + outregs.eax == (unsigned long)desc.address + outregs.ebx == desc.sel); + + MK_INSN(lfs, push %fs\n\t +lfs (%ebx), %eax\n\t +mov %fs, %ebx\n\t +pop %fs\n\t); + exec_in_big_real_mode(insn_lfs); + report(lfs, R_AX | R_BX, + outregs.eax == (unsigned long)desc.address + outregs.ebx == desc.sel); + + MK_INSN(lgs, push %gs\n\t +lgs (%ebx), %eax\n\t +mov %gs, %ebx\n\t +pop %gs\n\t); + exec_in_big_real_mode(insn_lgs); + report(lgs, R_AX | R_BX, + outregs.eax == (unsigned long)desc.address + outregs.ebx == desc.sel); + + MK_INSN(lss, push %ss\n\t +lss (%ebx), %eax\n\t +mov %ss, %ebx\n\t +pop %ss\n\t); + exec_in_big_real_mode(insn_lss); + report(lss, R_AX | R_BX, + outregs.eax == (unsigned long)desc.address + outregs.ebx == desc.sel); +} + void realmode_start(void) { test_null(); @@ -1215,6 +1273,7 @@ void realmode_start(void) test_cbw(); test_cwd_cdq(); test_das(); + test_lds_lss(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] KVM: x86 emulator: add LDS/LES/LFS/LGS/LSS instruction emulation
Add LDS/LES/LFS/LGS/LSS instruction emulation. (opcode 0xc4, 0xc5, 0x0f 0xb2, 0x0f 0xb4~0xb5) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v2 - v3: no changes, just porting to today's git tree --- arch/x86/kvm/emulate.c | 50 --- 1 files changed, 46 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 3b35e13..7d99cbe 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1515,6 +1515,23 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, return rc; } +static int emulate_load_segment(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, int seg) +{ + struct decode_cache *c = ctxt-decode; + unsigned short sel; + int rc; + + memcpy(sel, c-src.valptr + c-op_bytes, 2); + + rc = load_segment_descriptor(ctxt, ops, sel, seg); + if (rc != X86EMUL_CONTINUE) + return rc; + + c-dst.val = c-src.val; + return rc; +} + static inline void setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, struct desc_struct *cs, @@ -2459,7 +2476,7 @@ static struct opcode opcode_table[256] = { D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), D(ImplicitOps | Stack), - N, N, + D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), /* 0xC8 - 0xCF */ N, N, N, D(ImplicitOps | Stack), @@ -2530,9 +2547,9 @@ static struct opcode twobyte_table[256] = { D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), /* 0xB0 - 0xB7 */ D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), - N, D(DstMem | SrcReg | ModRM | BitOp | Lock), - N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), - D(DstReg | SrcMem16 | ModRM | Mov), + D(DstReg | SrcMemFAddr | ModRM), D(DstMem | SrcReg | ModRM | BitOp | Lock), + D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM), + D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), @@ -3215,6 +3232,16 @@ special_insn: c-dst.addr.reg = c-eip; c-dst.bytes = c-op_bytes; goto pop_instruction; + case 0xc4: /* les */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xc5: /* lds */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ mov: c-dst.val = c-src.val; @@ -3660,10 +3687,25 @@ twobyte_insn: c-dst.addr.reg = (unsigned long *)c-regs[VCPU_REGS_RAX]; } break; + case 0xb2: /* lss */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb3: btr: /* btr */ emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; + case 0xb4: /* lfs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xb5: /* lgs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb6 ... 0xb7: /* movzx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (u8) c-src.val -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: simplify BSF/BSR instruction emulation
Since emulate_2op() changed to use register for destination, we can now simplify BSF/BSR instruction to use it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 30 -- 1 files changed, 8 insertions(+), 22 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7d99cbe..77da7b6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3727,30 +3727,16 @@ twobyte_insn: btc: /* btc */ emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; - case 0xbc: {/* bsf */ - u8 zf; - __asm__ (bsf %2, %0; setz %1 -: =r(c-dst.val), =q(zf) -: r(c-src.val)); - ctxt-eflags = ~X86_EFLAGS_ZF; - if (zf) { - ctxt-eflags |= X86_EFLAGS_ZF; - c-dst.type = OP_NONE; /* Disable writeback. */ - } + case 0xbc: /* bsf */ + emulate_2op_SrcV_nobyte(bsf, c-src, c-dst, ctxt-eflags); + if (ctxt-eflags X86_EFLAGS_ZF) + c-dst.type = OP_NONE; /* Disable writeback. */ break; - } - case 0xbd: {/* bsr */ - u8 zf; - __asm__ (bsr %2, %0; setz %1 -: =r(c-dst.val), =q(zf) -: r(c-src.val)); - ctxt-eflags = ~X86_EFLAGS_ZF; - if (zf) { - ctxt-eflags |= X86_EFLAGS_ZF; - c-dst.type = OP_NONE; /* Disable writeback. */ - } + case 0xbd: /* bsr */ + emulate_2op_SrcV_nobyte(bsr, c-src, c-dst, ctxt-eflags); + if (ctxt-eflags X86_EFLAGS_ZF) + c-dst.type = OP_NONE; /* Disable writeback. */ break; - } case 0xbe ... 0xbf: /* movsx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (s8) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: MMU: fix missing percpu counter destroy
commit ad05c88266b4cce1c820928ce8a0fb7690912ba1 (KVM: create aggregate kvm_total_used_mmu_pages value) introduce percpu counter kvm_total_used_mmu_pages but never destroy it, this may cause oops when rmmod modprobe. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/mmu.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index f52a965..ef485db 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3190,6 +3190,7 @@ static void mmu_destroy_caches(void) void kvm_mmu_module_exit(void) { mmu_destroy_caches(); + percpu_counter_destroy(kvm_total_used_mmu_pages); unregister_shrinker(mmu_shrinker); } @@ -3212,7 +3213,9 @@ int kvm_mmu_module_init(void) if (!mmu_page_header_cache) goto nomem; - percpu_counter_init(kvm_total_used_mmu_pages, 0); + if (percpu_counter_init(kvm_total_used_mmu_pages, 0)) + goto nomem; + register_shrinker(mmu_shrinker); return 0; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [BUG?] can not writeback more then 8 bytes memory
On 08/20/2010 12:12 PM, Wei Yongjun wrote: Hi all: I have the following patch to SIDT emulation instruction, but it does not work because we can not writeback more then 8 bytes memory, the SIDT under PROTO64 is 10 bytes. I change the code to write twice, first time write limit, then write address, and it does not work too. If I change the c-dst.bytes to only writeback 8 bytes, it will writeback 8 bytes. Is this a bug of KVM or it is the IO limit? It's complicated... if you write to real memory, then you can do c-dst.* = ...; writeback(); c-dst.* = ...; writeback(); However that will not work for mmio, since writeback() only schedules mmio writes which are retired later on. As a temporary fix we can extend writeback() to support 2+N byte writes (and fail them on mmio). See also the sse-mmio branch on kvm.git on how to support 8 byte mmio. Longer term I'd like a queue based approach so we can have any number of reads and writes for an instruction, and have multiple writes possible for mmio. It would look something like this: - every read or write is assigned a position in the queue starting from 0 - the queue is maintained across invocations of x86_emulate_insn() - if an operation position is already in the queue, we read the value from the queue, and ignore writes (e.g. a replay after exit to userspace) - if an operation position is not already in the queue, we add it. If we cannot satisfy it, we exit to userspace - need to check read-after-write for collision in the queue. There's some beginning of that already (see struct read_cache). For now we can live without SIDT to mmio, that means you can do the simple fix to writeback() above. But you will only be able to test is with realmode.flat, not with emulator.flat since that requires mmio. If test with realmode.flat, fix to writeback() does not need, because the size we need to writeback is 2 + 4 in realmode.flat. I tested used the following patch. diff --git a/x86/realmode.c b/x86/realmode.c index 8c771fc..26651a6 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1242,6 +1242,25 @@ void test_lds_lss() outregs.ebx == desc.sel); } + +static struct { + u16 limit; + unsigned long base; +} __attribute__((packed)) idt_descr = { + 0x1234, + 0x5678, +}; + +void test_sidt() +{ + MK_INSN(sidt, sidt (%eax)\n\t); + + inregs = (struct regs){ .eax = (unsigned long)idt_descr }; + + exec_in_big_real_mode(insn_sidt); + report(sidt, 0, idt_descr.limit == 1023 idt_descr.base == 0); +} + void realmode_start(void) { test_null(); @@ -1274,6 +1293,7 @@ void realmode_start(void) test_cwd_cdq(); test_das(); test_lds_lss(); + test_sidt(); exit(0); } -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] Add realmode test for jcxz instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v2 - v3: rebased --- x86/realmode.c | 42 ++ 1 files changed, 42 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index 8c771fc..a833829 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1242,6 +1242,47 @@ void test_lds_lss() outregs.ebx == desc.sel); } +void test_jcxz(void) +{ + MK_INSN(jcxz1, jcxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jcxz2, mov $0x100, %ecx\n\t + jcxz 1f\n\t + mov $0x1234, %eax\n\t + mov $0, %ecx\n\t + 1:\n\t); + MK_INSN(jcxz3, mov $0x1, %ecx\n\t + jcxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jecxz1, jecxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jecxz2, mov $0x1, %ecx\n\t + jecxz 1f\n\t + mov $0x1234, %eax\n\t + mov $0, %ecx\n\t + 1:\n\t); + + inregs = (struct regs){ 0 }; + + exec_in_big_real_mode(insn_jcxz1); + report(jcxz short 1, 0, 1); + + exec_in_big_real_mode(insn_jcxz2); + report(jcxz short 2, R_AX, outregs.eax == 0x1234); + + exec_in_big_real_mode(insn_jcxz3); + report(jcxz short 3, R_CX, outregs.ecx == 0x1); + + exec_in_big_real_mode(insn_jecxz1); + report(jecxz short 1, 0, 1); + + exec_in_big_real_mode(insn_jecxz2); + report(jecxz short 2, R_AX, outregs.eax == 0x1234); +} + void realmode_start(void) { test_null(); @@ -1274,6 +1315,7 @@ void realmode_start(void) test_cwd_cdq(); test_das(); test_lds_lss(); + test_jcxz(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[BUG?] can not writeback more then 8 bytes memory
Hi all: I have the following patch to SIDT emulation instruction, but it does not work because we can not writeback more then 8 bytes memory, the SIDT under PROTO64 is 10 bytes. I change the code to write twice, first time write limit, then write address, and it does not work too. If I change the c-dst.bytes to only writeback 8 bytes, it will writeback 8 bytes. Is this a bug of KVM or it is the IO limit? diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index dc3a648..43a6819 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2213,7 +2213,8 @@ static struct opcode group5[] = { }; static struct group_dual group7 = { { - N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv), + N, D(DstMem | SrcNone | ModRM | Op3264), + D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv), D(SrcNone | ModRM | DstMem | Mov), N, D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv | NoAccess), @@ -3282,6 +3283,7 @@ twobyte_insn: switch (c-modrm_reg) { u16 size; unsigned long address; + struct desc_ptr dt; case 0: /* vmcall */ if (c-modrm_mod != 3 || c-modrm_rm != 1) @@ -3296,6 +3298,11 @@ twobyte_insn: /* Disable writeback. */ c-dst.type = OP_NONE; break; + case 1: /* sidt */ + ops-get_idt(dt, ctxt-vcpu); + c-dst.bytes = c-op_bytes + 2; + memcpy(c-dst.valptr, dt, c-dst.bytes); + break; case 2: /* lgdt */ rc = read_descriptor(ctxt, ops, c-src.addr.mem, size, address, c-op_bytes); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add JrCXZ instruction emulation
Add JrCXZ instruction emulation (opcode 0xe3) Used by FreeBSD boot loader. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index cbf6209..6ccc584 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2331,7 +2331,7 @@ static struct opcode opcode_table[256] = { /* 0xD8 - 0xDF */ N, N, N, N, N, N, N, N, /* 0xE0 - 0xE7 */ - X3(D(SrcImmByte)), N, + X4(D(SrcImmByte)), D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), D(ByteOp | SrcAcc | DstImmUByte), D(SrcAcc | DstImmUByte), /* 0xE8 - 0xEF */ @@ -3092,6 +3092,10 @@ special_insn: (c-b == 0xe2 || test_cc(c-b ^ 0x5, ctxt-eflags))) jmp_rel(c, c-src.val); break; + case 0xe3: /* jcxz/jecxz/jrcxz */ + if (address_mask(c, c-regs[VCPU_REGS_RCX]) == 0) + jmp_rel(c, c-src.val); + break; case 0xe4: /* inb */ case 0xe5: /* in */ goto do_io_in; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Add realmode test for jcxz instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com diff --git a/x86/realmode.c b/x86/realmode.c index ce8fb18..0caf388 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1262,6 +1262,32 @@ void test_cbw(void) print_serial(cwde test 1: PASS\n); } +void test_jcxz(void) +{ + struct regs inregs = { 0 }, outregs; + + MK_INSN(jcxz, jcxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jecxz, jecxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + + exec_in_big_real_mode(inregs, outregs, + insn_jcxz, insn_jcxz_end - insn_jcxz); + if(!regs_equal(inregs, outregs, 0)) + print_serial(JCXZ short Test 1: FAIL\n); + else + print_serial(JCXZ short Test 1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_jecxz, insn_jecxz_end - insn_jecxz); + if(!regs_equal(inregs, outregs, 0)) + print_serial(JECXZ short Test 1: FAIL\n); + else + print_serial(JECXZ short Test 1: PASS\n); +} + void realmode_start(void) { test_null(); @@ -1291,6 +1317,7 @@ void realmode_start(void) test_idiv(); test_loopcc(); test_cbw(); + test_jcxz(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] KVM: x86 emulator: fix REPZ/REPNZ termination condition
On 08/19/2010 07:55 AM, Wei Yongjun wrote: Hi Avi Kivity: EFLAGS.ZF needs to be checked after each iteration, not before. Signed-off-by: Avi Kivity a...@redhat.com --- arch/x86/kvm/emulate.c | 38 ++ 1 files changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 729853a..d15a746 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2782,28 +2782,10 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ctxt-restart = true; /* All REP prefixes have the same first termination condition */ if (address_mask(c, c-regs[VCPU_REGS_RCX]) == 0) { - string_done: ctxt-restart = false; ctxt-eip = c-eip; goto done; } - /* The second termination condition only applies for REPE -* and REPNE. Test if the repeat string operation prefix is -* REPE/REPZ or REPNE/REPNZ and if it's the case it tests the -* corresponding termination condition according to: -* - if REPE/REPZ and ZF = 0 then done -* - if REPNE/REPNZ and ZF = 1 then done -*/ - if ((c-b == 0xa6) || (c-b == 0xa7) || - (c-b == 0xae) || (c-b == 0xaf)) { - if ((c-rep_prefix == REPE_PREFIX) - ((ctxt-eflags EFLG_ZF) == 0)) - goto string_done; - if ((c-rep_prefix == REPNE_PREFIX) - ((ctxt-eflags EFLG_ZF) == EFLG_ZF)) - goto string_done; - } - c-eip = ctxt-eip; It seems that you cannot remove the above line, the assign for eip is need. remove it will break FreeDOS livecd. Not sure why need this. I'll try it out. Are you running FreeDOS with emulate_invalid_guest_state=0 or 1? I try it with emulate_invalid_guest_state=1. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] KVM: x86 emulator: fix REPZ/REPNZ termination condition
On 08/19/2010 07:55 AM, Wei Yongjun wrote: Hi Avi Kivity: EFLAGS.ZF needs to be checked after each iteration, not before. Signed-off-by: Avi Kivity a...@redhat.com --- arch/x86/kvm/emulate.c | 38 ++ 1 files changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 729853a..d15a746 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2782,28 +2782,10 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ctxt-restart = true; /* All REP prefixes have the same first termination condition */ if (address_mask(c, c-regs[VCPU_REGS_RCX]) == 0) { - string_done: ctxt-restart = false; ctxt-eip = c-eip; goto done; } - /* The second termination condition only applies for REPE -* and REPNE. Test if the repeat string operation prefix is -* REPE/REPZ or REPNE/REPNZ and if it's the case it tests the -* corresponding termination condition according to: -* - if REPE/REPZ and ZF = 0 then done -* - if REPNE/REPNZ and ZF = 1 then done -*/ - if ((c-b == 0xa6) || (c-b == 0xa7) || - (c-b == 0xae) || (c-b == 0xaf)) { - if ((c-rep_prefix == REPE_PREFIX) - ((ctxt-eflags EFLG_ZF) == 0)) - goto string_done; - if ((c-rep_prefix == REPNE_PREFIX) - ((ctxt-eflags EFLG_ZF) == EFLG_ZF)) - goto string_done; - } - c-eip = ctxt-eip; It seems that you cannot remove the above line, the assign for eip is need. remove it will break FreeDOS livecd. Not sure why need this. I'll try it out. Are you running FreeDOS with emulate_invalid_guest_state=0 or 1? It broken the boot from cdrom, even emulate_invalid_guest_state=0 #qemu-system-x86_64 --boot d --cdrom fdbasews.iso This will return can not boot from CDROM. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] Add realmode test for jcxz instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c | 62 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index ce8fb18..75d77bd 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1262,6 +1262,67 @@ void test_cbw(void) print_serial(cwde test 1: PASS\n); } +void test_jcxz(void) +{ + struct regs inregs = { 0 }, outregs; + + MK_INSN(jcxz1, jcxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jcxz2, mov $0x100, %ecx\n\t + jcxz 1f\n\t + mov $0x1234, %eax\n\t + mov $0, %ecx\n\t + 1:\n\t); + MK_INSN(jcxz3, mov $0x1, %ecx\n\t + jcxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jecxz1, jecxz 1f\n\t + mov $0x1234, %eax\n\t + 1:\n\t); + MK_INSN(jecxz2, mov $0x1, %ecx\n\t + jecxz 1f\n\t + mov $0x1234, %eax\n\t + mov $0, %ecx\n\t + 1:\n\t); + + exec_in_big_real_mode(inregs, outregs, + insn_jcxz1, insn_jcxz1_end - insn_jcxz1); + if(!regs_equal(inregs, outregs, 0)) + print_serial(JCXZ short Test 1: FAIL\n); + else + print_serial(JCXZ short Test 1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_jcxz2, insn_jcxz2_end - insn_jcxz2); + if(!regs_equal(inregs, outregs, R_AX) || outregs.eax != 0x1234) + print_serial(JCXZ short Test 2: FAIL\n); + else + print_serial(JCXZ short Test 2: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_jcxz3, insn_jcxz3_end - insn_jcxz3); + if(!regs_equal(inregs, outregs, R_CX) || outregs.ecx != 0x1) + print_serial(JCXZ short Test 3: FAIL\n); + else + print_serial(JCXZ short Test 3: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_jecxz1, insn_jecxz1_end - insn_jecxz1); + if(!regs_equal(inregs, outregs, 0)) + print_serial(JECXZ short Test 1: FAIL\n); + else + print_serial(JECXZ short Test 1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_jecxz2, insn_jecxz2_end - insn_jecxz2); + if(!regs_equal(inregs, outregs, R_AX) || outregs.eax != 0x1234) + print_serial(JECXZ short Test 2: FAIL\n); + else + print_serial(JECXZ short Test 2: PASS\n); +} + void realmode_start(void) { test_null(); @@ -1291,6 +1352,7 @@ void realmode_start(void) test_idiv(); test_loopcc(); test_cbw(); + test_jcxz(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] KVM: x86 emulator: add LDS/LES/LFS/LGS/LSS instruction emulation
Add LDS/LES/LFS/LGS/LSS instruction emulation. (opcode 0xc4, 0xc5, 0x0f 0xb2, 0x0f 0xb4~0xb5) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v1 - v2: mask LES/LDS as No64. --- arch/x86/kvm/emulate.c | 51 --- 1 files changed, 47 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1d36c38..7c2ae18 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1503,6 +1503,23 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, return rc; } +static int emulate_load_segment(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, int seg) +{ + struct decode_cache *c = ctxt-decode; + unsigned short sel; + int rc; + + memcpy(sel, c-src.valptr + c-op_bytes, 2); + + rc = load_segment_descriptor(ctxt, ops, sel, seg); + if (rc != X86EMUL_CONTINUE) + return rc; + + c-dst.val = c-src.val; + return rc; +} + static inline void setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, struct desc_struct *cs, @@ -2308,7 +2325,8 @@ static struct opcode opcode_table[256] = { X8(D(DstReg | SrcImm | Mov)), /* 0xC0 - 0xC7 */ D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), - N, D(ImplicitOps | Stack), N, N, + N, D(ImplicitOps | Stack), + D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), /* 0xC8 - 0xCF */ N, N, N, D(ImplicitOps | Stack), @@ -2378,9 +2396,9 @@ static struct opcode twobyte_table[256] = { D(ModRM), N, /* 0xB0 - 0xB7 */ D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), - N, D(DstMem | SrcReg | ModRM | BitOp | Lock), - N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), - D(DstReg | SrcMem16 | ModRM | Mov), + D(DstReg | SrcMemFAddr | ModRM), D(DstMem | SrcReg | ModRM | BitOp | Lock), + D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM), + D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), @@ -3055,6 +3073,16 @@ special_insn: c-dst.addr.reg = c-eip; c-dst.bytes = c-op_bytes; goto pop_instruction; + case 0xc4: /* les */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xc5: /* lds */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ mov: c-dst.val = c-src.val; @@ -3483,10 +3511,25 @@ twobyte_insn: c-dst.addr.reg = (unsigned long *)c-regs[VCPU_REGS_RAX]; } break; + case 0xb2: /* lss */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb3: btr: /* btr */ emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; + case 0xb4: /* lfs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xb5: /* lgs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb6 ... 0xb7: /* movzx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (u8) c-src.val -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add LOOP/LOOPcc instruction emulation
Add LOOP/LOOPcc instruction emulation (opcode 0xe0~0xe2). Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ac13831..46b7da8 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2320,7 +2320,7 @@ static struct opcode opcode_table[256] = { /* 0xD8 - 0xDF */ N, N, N, N, N, N, N, N, /* 0xE0 - 0xE7 */ - N, N, N, N, + X3(D(SrcImmByte)), N, D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), D(ByteOp | SrcAcc | DstImmUByte), D(SrcAcc | DstImmUByte), /* 0xE8 - 0xEF */ @@ -3086,6 +3086,12 @@ special_insn: c-src.val = c-regs[VCPU_REGS_RCX]; emulate_grp2(ctxt); break; + case 0xe0 ... 0xe2: /* loop/loopz/loopnz */ + register_address_increment(c, c-regs[VCPU_REGS_RCX], -1); + if (address_mask(c, c-regs[VCPU_REGS_RCX]) != 0 + (c-b == 0xe2 || test_cc(c-b ^ 0x5, ctxt-eflags))) + jmp_rel(c, c-src.val); + break; case 0xe4: /* inb */ case 0xe5: /* in */ goto do_io_in; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: Add realmode test for loopcc instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c | 43 +++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index 35f6a16..bedd175 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1194,6 +1194,48 @@ void test_idiv() print_serial(idiv Test 3: PASS\n); } +void test_loopcc(void) +{ + struct regs inregs = { 0 }, outregs; + + MK_INSN(loop, mov $10, %ecx\n\t + 1: inc %eax\n\t + loop 1b\n\t); + + MK_INSN(loope, mov $10, %ecx\n\t + mov $1, %eax\n\t + 1: dec %eax\n\t + loope 1b\n\t); + + MK_INSN(loopne, mov $10, %ecx\n\t + mov $5, %eax\n\t + 1: dec %eax\n\t + loopne 1b\n\t); + + exec_in_big_real_mode(inregs, outregs, + insn_loop, insn_loop_end - insn_loop); + if(!regs_equal(inregs, outregs, R_AX) || outregs.eax != 10) + print_serial(LOOPcc short Test 1: FAIL\n); + else + print_serial(LOOPcc short Test 1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_loope, insn_loope_end - insn_loope); + if(!regs_equal(inregs, outregs, R_AX | R_CX) || + outregs.eax != -1 || outregs.ecx != 8) + print_serial(LOOPcc short Test 2: FAIL\n); + else + print_serial(LOOPcc short Test 2: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_loopne, insn_loopne_end - insn_loopne); + if(!regs_equal(inregs, outregs, R_AX | R_CX) || + outregs.eax != 0 || outregs.ecx != 5) + print_serial(LOOPcc short Test 3: FAIL\n); + else + print_serial(LOOPcc short Test 3: PASS\n); +} + void realmode_start(void) { test_null(); @@ -1221,6 +1263,7 @@ void realmode_start(void) test_mul(); test_div(); test_idiv(); + test_loopcc(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add CBW/CWDE/CDQE instruction emulation
Add CBW/CWDE/CDQE instruction emulation.(opcode 0x98) Used by FreeBSD's boot loader. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 46b7da8..1d36c38 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2290,7 +2290,7 @@ static struct opcode opcode_table[256] = { /* 0x90 - 0x97 */ X8(D(SrcAcc | DstReg)), /* 0x98 - 0x9F */ - N, N, D(SrcImmFAddr | No64), N, + D(DstAcc | SrcNone), N, D(SrcImmFAddr | No64), N, D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N, /* 0xA0 - 0xA7 */ D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs), @@ -3011,6 +3011,13 @@ special_insn: if (c-dst.addr.reg == c-regs[VCPU_REGS_RAX]) break; goto xchg; + case 0x98: /* cbw/cwde/cdqe */ + switch (c-op_bytes) { + case 2: c-dst.val = (s8)c-dst.val; break; + case 4: c-dst.val = (s16)c-dst.val; break; + case 8: c-dst.val = (s32)c-dst.val; break; + } + break; case 0x9c: /* pushf */ c-src.val = (unsigned long) ctxt-eflags; emulate_push(ctxt, ops); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: Add real mode test for cbw/cwde instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/realmode.c | 27 +++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index bedd175..ce8fb18 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -1236,6 +1236,32 @@ void test_loopcc(void) print_serial(LOOPcc short Test 3: PASS\n); } +void test_cbw(void) +{ + struct regs inregs = { 0 }, outregs; + + MK_INSN(cbw, mov $0xFE, %eax \n\t +cbw\n\t); + MK_INSN(cwde, mov $0xFFFE, %eax \n\t + cwde\n\t); + + exec_in_big_real_mode(inregs, outregs, + insn_cbw, + insn_cbw_end - insn_cbw); + if (outregs.eax != 0xFFFE) + print_serial(cbw test1: FAIL\n); + else + print_serial(cbw test 1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_cwde, + insn_cwde_end - insn_cwde); + if (outregs.eax != 0xFFFE) + print_serial(cwde test1: FAIL\n); + else + print_serial(cwde test 1: PASS\n); +} + void realmode_start(void) { test_null(); @@ -1264,6 +1290,7 @@ void realmode_start(void) test_div(); test_idiv(); test_loopcc(); + test_cbw(); exit(0); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add LDS/LES/LFS/LGS/LSS instruction emulation
Add LDS/LES/LFS/LGS/LSS instruction emulation. (opcode 0xc4, 0xc5, 0x0f 0xb2, 0x0f 0xb4~0xb5) Used by FreeDOS livecd. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 51 --- 1 files changed, 47 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1d36c38..7c2ae18 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1503,6 +1503,23 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, return rc; } +static int emulate_load_segment(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, int seg) +{ + struct decode_cache *c = ctxt-decode; + unsigned short sel; + int rc; + + memcpy(sel, c-src.valptr + c-op_bytes, 2); + + rc = load_segment_descriptor(ctxt, ops, sel, seg); + if (rc != X86EMUL_CONTINUE) + return rc; + + c-dst.val = c-src.val; + return rc; +} + static inline void setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, struct desc_struct *cs, @@ -2308,7 +2325,8 @@ static struct opcode opcode_table[256] = { X8(D(DstReg | SrcImm | Mov)), /* 0xC0 - 0xC7 */ D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), - N, D(ImplicitOps | Stack), N, N, + N, D(ImplicitOps | Stack), + D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM), D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), /* 0xC8 - 0xCF */ N, N, N, D(ImplicitOps | Stack), @@ -2378,9 +2396,9 @@ static struct opcode twobyte_table[256] = { D(ModRM), N, /* 0xB0 - 0xB7 */ D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), - N, D(DstMem | SrcReg | ModRM | BitOp | Lock), - N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), - D(DstReg | SrcMem16 | ModRM | Mov), + D(DstReg | SrcMemFAddr | ModRM), D(DstMem | SrcReg | ModRM | BitOp | Lock), + D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM), + D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), @@ -3055,6 +3073,16 @@ special_insn: c-dst.addr.reg = c-eip; c-dst.bytes = c-op_bytes; goto pop_instruction; + case 0xc4: /* les */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xc5: /* lds */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ mov: c-dst.val = c-src.val; @@ -3483,10 +3511,25 @@ twobyte_insn: c-dst.addr.reg = (unsigned long *)c-regs[VCPU_REGS_RAX]; } break; + case 0xb2: /* lss */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb3: btr: /* btr */ emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; + case 0xb4: /* lfs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; + case 0xb5: /* lgs */ + rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS); + if (rc != X86EMUL_CONTINUE) + goto done; + break; case 0xb6 ... 0xb7: /* movzx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (u8) c-src.val -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] KVM: x86 emulator: fix REPZ/REPNZ termination condition
Hi Avi Kivity: EFLAGS.ZF needs to be checked after each iteration, not before. Signed-off-by: Avi Kivity a...@redhat.com --- arch/x86/kvm/emulate.c | 38 ++ 1 files changed, 18 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 729853a..d15a746 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2782,28 +2782,10 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ctxt-restart = true; /* All REP prefixes have the same first termination condition */ if (address_mask(c, c-regs[VCPU_REGS_RCX]) == 0) { - string_done: ctxt-restart = false; ctxt-eip = c-eip; goto done; } - /* The second termination condition only applies for REPE - * and REPNE. Test if the repeat string operation prefix is - * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the - * corresponding termination condition according to: - * - if REPE/REPZ and ZF = 0 then done - * - if REPNE/REPNZ and ZF = 1 then done - */ - if ((c-b == 0xa6) || (c-b == 0xa7) || - (c-b == 0xae) || (c-b == 0xaf)) { - if ((c-rep_prefix == REPE_PREFIX) - ((ctxt-eflags EFLG_ZF) == 0)) - goto string_done; - if ((c-rep_prefix == REPNE_PREFIX) - ((ctxt-eflags EFLG_ZF) == EFLG_ZF)) - goto string_done; - } - c-eip = ctxt-eip; It seems that you cannot remove the above line, the assign for eip is need. remove it will break FreeDOS livecd. Not sure why need this. } if ((c-src.type == OP_MEM) !(c-d NoAccess)) { @@ -3230,13 +3212,29 @@ writeback: if (c-rep_prefix (c-d String)) { struct read_cache *rc = ctxt-decode.io_read; register_address_increment(c, c-regs[VCPU_REGS_RCX], -1); + /* The second termination condition only applies for REPE + * and REPNE. Test if the repeat string operation prefix is + * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the + * corresponding termination condition according to: + * - if REPE/REPZ and ZF = 0 then done + * - if REPNE/REPNZ and ZF = 1 then done + */ + if (((c-b == 0xa6) || (c-b == 0xa7) || + (c-b == 0xae) || (c-b == 0xaf)) + (((c-rep_prefix == REPE_PREFIX) + ((ctxt-eflags EFLG_ZF) == 0)) + || ((c-rep_prefix == REPNE_PREFIX) + ((ctxt-eflags EFLG_ZF) == EFLG_ZF + ctxt-restart = false; /* * Re-enter guest when pio read ahead buffer is empty or, * if it is not used, after each 1024 iteration. */ - if ((rc-end == 0 !(c-regs[VCPU_REGS_RCX] 0x3ff)) || - (rc-end != 0 rc-end == rc-pos)) + else if ((rc-end == 0 !(c-regs[VCPU_REGS_RCX] 0x3ff)) || + (rc-end != 0 rc-end == rc-pos)) { ctxt-restart = false; + c-eip = ctxt-eip; + } } /* * reset read cache here in case string instruction is restared -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2 v4] KVM: x86 emulator: put register operand write back to a function
Introduce function write_register_operand() to write back the register operand. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 55 --- 1 files changed, 23 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c476a67..d690daf 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1020,6 +1020,25 @@ exception: return X86EMUL_PROPAGATE_FAULT; } +static void write_register_operand(struct operand *op) +{ + /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ + switch (op-bytes) { + case 1: + *(u8 *)op-addr.reg = (u8)op-val; + break; + case 2: + *(u16 *)op-addr.reg = (u16)op-val; + break; + case 4: + *op-addr.reg = (u32)op-val; + break; /* 64b: zero-extend */ + case 8: + *op-addr.reg = op-val; + break; + } +} + static inline int writeback(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1029,23 +1048,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, switch (c-dst.type) { case OP_REG: - /* The 4-byte case *is* correct: -* in 64-bit mode we zero-extend. -*/ - switch (c-dst.bytes) { - case 1: - *(u8 *)c-dst.addr.reg = (u8)c-dst.val; - break; - case 2: - *(u16 *)c-dst.addr.reg = (u16)c-dst.val; - break; - case 4: - *c-dst.addr.reg = (u32)c-dst.val; - break; /* 64b: zero-ext */ - case 8: - *c-dst.addr.reg = c-dst.val; - break; - } + write_register_operand(c-dst); break; case OP_MEM: if (c-lock_prefix) @@ -2971,25 +2974,13 @@ special_insn: case 0x86 ... 0x87: /* xchg */ xchg: /* Write back the register source. */ - switch (c-dst.bytes) { - case 1: - *(u8 *) c-src.addr.reg = (u8) c-dst.val; - break; - case 2: - *(u16 *) c-src.addr.reg = (u16) c-dst.val; - break; - case 4: - *c-src.addr.reg = (u32) c-dst.val; - break; /* 64b reg: zero-extend */ - case 8: - *c-src.addr.reg = c-dst.val; - break; - } + c-src.val = c-dst.val; + write_register_operand(c-src); /* * Write back the memory destination with implicit LOCK * prefix. */ - c-dst.val = c-src.val; + c-dst.val = c-src.orig_val; c-lock_prefix = 1; break; case 0x88 ... 0x8b: /* mov */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2 v4] KVM: x86 emulator: add XADD instruction emulation
Add XADD instruction emulation (opcode 0x0f 0xc0~0xc1) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d690daf..41ca98b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2386,7 +2386,8 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ - N, N, N, D(DstMem | SrcReg | ModRM | Mov), + D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), + N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), N, N, N, N, N, N, N, N, /* 0xD0 - 0xDF */ @@ -3532,6 +3533,12 @@ twobyte_insn: c-dst.val = (c-d ByteOp) ? (s8) c-src.val : (s16) c-src.val; break; + case 0xc0 ... 0xc1: /* xadd */ + emulate_2op_SrcV(add, c-src, c-dst, ctxt-eflags); + /* Write back the register source. */ + c-src.val = c-dst.orig_val; + write_register_operand(c-src); + break; case 0xc3: /* movnti */ c-dst.bytes = c-op_bytes; c-dst.val = (c-op_bytes == 4) ? (u32) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND] KVM: PPC: fix leakage of error page in kvmppc_patch_dcbz()
Add kvm_release_page_clean() after is_error_page() to avoid leakage of error page. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/powerpc/kvm/book3s.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index eee97b5..7656b6d 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -455,8 +455,10 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) int i; hpage = gfn_to_page(vcpu-kvm, pte-raddr PAGE_SHIFT); - if (is_error_page(hpage)) + if (is_error_page(hpage)) { + kvm_release_page_clean(hpage); return; + } hpage_offset = pte-raddr ~PAGE_MASK; hpage_offset = ~0xFFFULL; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] KVM: x86 emulator: put register operand write back to a function
On 08/12/2010 04:38 PM, Wei Yongjun wrote: Introduce function write_register_operand() to write back the register operand. +static void write_register_operand(struct operand *op, unsigned long val, + unsigned int bytes) +{ +/* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ +switch (bytes) { +case 1: +*(u8 *)op-addr.reg = (u8)val; +break; +case 2: +*(u16 *)op-addr.reg = (u16)val; +break; +case 4: +*op-addr.reg = (u32)val; +break; /* 64b: zero-extend */ +case 8: +*op-addr.reg = val; +break; +} +} It's cleaner to take val and bytes from struct operand, and do the assignment from the callers, no? take val and bytes from struct operand may have other issue, when we writeback the source register, we need do the assignment from the caller, and then change the val back before write src val to dst val. Such as xadd: c-src.val = c-dst.val; write_register_operand(c-src); c-src.val = c-src.orig_val; goto add; -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] KVM: x86 emulator: put register operand write back to a function
Introduce function write_register_operand() to write back the register operand. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 53 +++ 1 files changed, 22 insertions(+), 31 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c476a67..8bf80a9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1020,6 +1020,26 @@ exception: return X86EMUL_PROPAGATE_FAULT; } +static void write_register_operand(struct operand *op, unsigned long val, + unsigned int bytes) +{ + /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ + switch (bytes) { + case 1: + *(u8 *)op-addr.reg = (u8)val; + break; + case 2: + *(u16 *)op-addr.reg = (u16)val; + break; + case 4: + *op-addr.reg = (u32)val; + break; /* 64b: zero-extend */ + case 8: + *op-addr.reg = val; + break; + } +} + static inline int writeback(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1029,23 +1049,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, switch (c-dst.type) { case OP_REG: - /* The 4-byte case *is* correct: -* in 64-bit mode we zero-extend. -*/ - switch (c-dst.bytes) { - case 1: - *(u8 *)c-dst.addr.reg = (u8)c-dst.val; - break; - case 2: - *(u16 *)c-dst.addr.reg = (u16)c-dst.val; - break; - case 4: - *c-dst.addr.reg = (u32)c-dst.val; - break; /* 64b: zero-ext */ - case 8: - *c-dst.addr.reg = c-dst.val; - break; - } + write_register_operand(c-dst, c-dst.val, c-dst.bytes); break; case OP_MEM: if (c-lock_prefix) @@ -2971,20 +2975,7 @@ special_insn: case 0x86 ... 0x87: /* xchg */ xchg: /* Write back the register source. */ - switch (c-dst.bytes) { - case 1: - *(u8 *) c-src.addr.reg = (u8) c-dst.val; - break; - case 2: - *(u16 *) c-src.addr.reg = (u16) c-dst.val; - break; - case 4: - *c-src.addr.reg = (u32) c-dst.val; - break; /* 64b reg: zero-extend */ - case 8: - *c-src.addr.reg = c-dst.val; - break; - } + write_register_operand(c-src, c-dst.val, c-dst.bytes); /* * Write back the memory destination with implicit LOCK * prefix. -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] KVM: x86 emulator: add XADD instruction emulation
Add XADD instruction emulation (opcode 0x0f 0xc0~0xc1) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8bf80a9..7c47e37 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2387,7 +2387,8 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ - N, N, N, D(DstMem | SrcReg | ModRM | Mov), + D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM), + N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), N, N, N, N, N, N, N, N, /* 0xD0 - 0xDF */ @@ -3532,6 +3533,12 @@ twobyte_insn: c-dst.val = (c-d ByteOp) ? (s8) c-src.val : (s16) c-src.val; break; + case 0xc0 ... 0xc1: /* xadd */ + /* Write back the register source. */ + write_register_operand(c-src, c-dst.val, c-dst.bytes); + /* Write back the memory destination with implicit LOCK prefix. */ + c-lock_prefix = 1; + goto add; case 0xc3: /* movnti */ c-dst.bytes = c-op_bytes; c-dst.val = (c-op_bytes == 4) ? (u32) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: Add test for xadd instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- x86/emulator.c | 51 +++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/x86/emulator.c b/x86/emulator.c index 348d548..c4579ab 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -360,6 +360,56 @@ void test_xchg(void *mem) rax == 0x123456789abcdef *memq == 0xfedcba9876543210); } +void test_xadd(void *mem) +{ + unsigned long *memq = mem; + unsigned long rax; + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xadd %%al, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xadd reg, r/m (1), + rax == 0xfedcba98765432ef *memq == 0x123456789abcdff); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xadd %%ax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xadd reg, r/m (2), + rax == 0xfedcba987654cdef *memq == 0x123456789ab); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xadd %%eax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xadd reg, r/m (3), + rax == 0x89abcdef *memq == 0x1234567); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xadd %%rax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xadd reg, r/m (4), + rax == 0x123456789abcdef *memq == 0x); +} + void test_btc(void *mem) { unsigned int *a = mem; @@ -548,6 +598,7 @@ int main() test_pop(mem); test_xchg(mem); + test_xadd(mem); test_cr8(); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2 v2] KVM: x86 emulator: add XADD instruction emulation
Add XADD instruction emulation (opcode 0x0f 0xc0~0xc1) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v1 - v2: remove implicit LOCK prefix --- arch/x86/kvm/emulate.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8bf80a9..279547a 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2387,7 +2387,8 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ - N, N, N, D(DstMem | SrcReg | ModRM | Mov), + D(ByteOp | DstMem | SrcReg | ModRM), D(DstMem | SrcReg | ModRM), + N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), N, N, N, N, N, N, N, N, /* 0xD0 - 0xDF */ @@ -3532,6 +3533,10 @@ twobyte_insn: c-dst.val = (c-d ByteOp) ? (s8) c-src.val : (s16) c-src.val; break; + case 0xc0 ... 0xc1: /* xadd */ + /* Write back the register source. */ + write_register_operand(c-src, c-dst.val, c-dst.bytes); + goto add; case 0xc3: /* movnti */ c-dst.bytes = c-op_bytes; c-dst.val = (c-op_bytes == 4) ? (u32) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2 v3] KVM: x86 emulator: add XADD instruction emulation
Add XADD instruction emulation (opcode 0x0f 0xc0~0xc1) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v2 - v3: add Lock prefix to decode --- arch/x86/kvm/emulate.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8bf80a9..e091718 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2387,7 +2387,8 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ - N, N, N, D(DstMem | SrcReg | ModRM | Mov), + D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), + N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), N, N, N, N, N, N, N, N, /* 0xD0 - 0xDF */ @@ -3532,6 +3533,10 @@ twobyte_insn: c-dst.val = (c-d ByteOp) ? (s8) c-src.val : (s16) c-src.val; break; + case 0xc0 ... 0xc1: /* xadd */ + /* Write back the register source. */ + write_register_operand(c-src, c-dst.val, c-dst.bytes); + goto add; case 0xc3: /* movnti */ c-dst.bytes = c-op_bytes; c-dst.val = (c-op_bytes == 4) ? (u32) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add bsf/bsr instruction emulation
Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 28 ++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index fb4ac8c..831aa6e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2342,8 +2342,8 @@ static struct opcode twobyte_table[256] = { /* 0xB8 - 0xBF */ N, N, G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), - N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), - D(DstReg | SrcMem16 | ModRM | Mov), + D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), + D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ N, N, N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), @@ -3464,6 +3464,30 @@ twobyte_insn: btc: /* btc */ emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; + case 0xbc: {/* bsf */ + int zf; + __asm__ (bsf %2, %0; setz %b1 +: =r(c-dst.val), =q(zf) +: r(c-src.val), 1 (0)); + ctxt-eflags = ~X86_EFLAGS_ZF; + if (zf) { + ctxt-eflags |= X86_EFLAGS_ZF; + c-dst.type = OP_NONE; /* Disable writeback. */ + } + break; + } + case 0xbd: {/* bsr */ + int zf; + __asm__ (bsr %2, %0; setz %b1 +: =r(c-dst.val), =q(zf) +: r(c-src.val), 1 (0)); + ctxt-eflags = ~X86_EFLAGS_ZF; + if (zf) { + ctxt-eflags |= X86_EFLAGS_ZF; + c-dst.type = OP_NONE; /* Disable writeback. */ + } + break; + } case 0xbe ... 0xbf: /* movsx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (s8) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: add test for bsf/bsr instruction
This patch add test for bsf/bsr instruction. Signed-off-by: Wei Yongjunyj...@cn.fujitsu.com --- x86/emulator.c | 64 1 files changed, 64 insertions(+), 0 deletions(-) diff --git a/x86/emulator.c b/x86/emulator.c index aef5d90..348d548 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -462,6 +462,69 @@ void test_setcc(void *mem) report(setnle r/m8, *memb == 0); } +void test_bsfbsr(void *mem) +{ + unsigned long *memq = mem, rax; + + asm volatile(movw $0xC000, (%[memq])\n\t +bsfw (%[memq]), %%ax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsfw r/m, reg, rax == 14); + + asm volatile(movl $0xC000, (%[memq])\n\t +bsfl (%[memq]), %%eax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsfl r/m, reg, rax == 30); + + asm volatile(movq $0xC000, %%rax\n\t +movq %%rax, (%[memq])\n\t +bsfq (%[memq]), %%rax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsfq r/m, reg, rax == 46); + + asm volatile(movq $0, %%rax\n\t +movq %%rax, (%[memq])\n\t +bsfq (%[memq]), %%rax\n\t +jnz 1f\n\t +movl $1, %[rax]\n\t +1:\n\t +:[rax]=m(rax) +:[memq]r(memq)); + report(bsfq r/m, reg, rax == 1); + + asm volatile(movw $0xC000, (%[memq])\n\t +bsrw (%[memq]), %%ax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsrw r/m, reg, rax == 15); + + asm volatile(movl $0xC000, (%[memq])\n\t +bsrl (%[memq]), %%eax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsrl r/m, reg, rax == 31); + + asm volatile(movq $0xC000, %%rax\n\t +movq %%rax, (%[memq])\n\t +bsrq (%[memq]), %%rax\n\t +::[memq]r(memq)); + asm (mov %%rax, %[rax]: [rax]=m(rax)); + report(bsrq r/m, reg, rax == 47); + + asm volatile(movq $0, %%rax\n\t +movq %%rax, (%[memq])\n\t +bsrq (%[memq]), %%rax\n\t +jnz 1f\n\t +movl $1, %[rax]\n\t +1:\n\t +:[rax]=m(rax) +:[memq]r(memq)); + report(bsrq r/m, reg, rax == 1); +} + int main() { void *mem; @@ -495,6 +558,7 @@ int main() test_incdecnotneg(mem); test_btc(mem); test_setcc(mem); + test_bsfbsr(mem); printf(\nSUMMARY: %d tests, %d failures\n, tests, fails); return fails ? 1 : 0; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] KVM: x86 emulator: add bsf/bsr instruction emulation
Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v1 - v2: use 'u8 zf' instead of int. --- arch/x86/kvm/emulate.c | 28 ++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 66139ad..7cbcb66 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2381,8 +2381,8 @@ static struct opcode twobyte_table[256] = { /* 0xB8 - 0xBF */ N, N, G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), - N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), - D(DstReg | SrcMem16 | ModRM | Mov), + D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), + D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ N, N, N, D(DstMem | SrcReg | ModRM | Mov), N, N, N, GD(0, group9), @@ -3500,6 +3500,30 @@ twobyte_insn: btc: /* btc */ emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; + case 0xbc: {/* bsf */ + u8 zf; + __asm__ (bsf %2, %0; setz %1 +: =r(c-dst.val), =q(zf) +: r(c-src.val)); + ctxt-eflags = ~X86_EFLAGS_ZF; + if (zf) { + ctxt-eflags |= X86_EFLAGS_ZF; + c-dst.type = OP_NONE; /* Disable writeback. */ + } + break; + } + case 0xbd: {/* bsr */ + u8 zf; + __asm__ (bsr %2, %0; setz %1 +: =r(c-dst.val), =q(zf) +: r(c-src.val)); + ctxt-eflags = ~X86_EFLAGS_ZF; + if (zf) { + ctxt-eflags |= X86_EFLAGS_ZF; + c-dst.type = OP_NONE; /* Disable writeback. */ + } + break; + } case 0xbe ... 0xbf: /* movsx */ c-dst.bytes = c-op_bytes; c-dst.val = (c-d ByteOp) ? (s8) c-src.val : -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3 v2] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation
If bit offset operands is a negative number, BitOp instruction will return wrong value. This patch fix it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 24 ++-- 1 files changed, 18 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0e360c6..f48890d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -724,6 +724,22 @@ done: return rc; } +static void fetch_bit_operand(struct decode_cache *c) +{ + long sv, mask; + + if (c-dst.type == OP_MEM) { + mask = ~(c-dst.bytes * 8 - 1); + + if (c-src.bytes == 2) + sv = (s16)c-src.val (s16)mask; + else if (c-src.bytes == 4) + sv = (s32)c-src.val (s32)mask; + + c-dst.addr.mem += (sv 3); + } +} + static int read_emulated(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, unsigned long addr, void *dest, unsigned size) @@ -2646,12 +2662,8 @@ done_prefixes: c-dst.bytes = 8; else c-dst.bytes = (c-d ByteOp) ? 1 : c-op_bytes; - if (c-dst.type == OP_MEM (c-d BitOp)) { - unsigned long mask = ~(c-dst.bytes * 8 - 1); - - c-dst.addr.mem = c-dst.addr.mem + - (c-src.val mask) / 8; - } + if (c-d BitOp) + fetch_bit_operand(c); c-dst.orig_val = c-dst.val; break; case DstAcc: -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source
adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f48890d..161d361 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { long sv, mask; - if (c-dst.type == OP_MEM) { + if (c-dst.type == OP_MEM c-src.type == OP_REG) { mask = ~(c-dst.bytes * 8 - 1); if (c-src.bytes == 2) -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3 v2] KVM: x86 emulator: mask group 8 instruction as BitOp
Mask group 8 instruction as BitOp, so we can share the code for adjust the source operand. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 11 --- 1 files changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 161d361..db19bcf 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -738,6 +738,9 @@ static void fetch_bit_operand(struct decode_cache *c) c-dst.addr.mem += (sv 3); } + + /* only subword offset */ + c-src.val = (c-dst.bytes 3) - 1; } static int read_emulated(struct x86_emulate_ctxt *ctxt, @@ -2338,7 +2341,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ @@ -3412,8 +3415,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bts, c-src, c-dst, ctxt-eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3441,8 +3442,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3464,8 +3463,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] KVM: x86 emulator: fix negative bit offset BitOp instruction emulation
If bit offset operands is a negative number, BitOp instruction will return wrong value. This patch fix it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 32 ++-- 1 files changed, 26 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0e360c6..470c7eb 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -724,6 +724,30 @@ done: return rc; } +static void fetch_bit_operand(struct decode_cache *c) +{ + unsigned long mask, byte_offset; + + if (c-dst.type == OP_MEM) { + if (c-src.bytes == 2) + c-src.val = (s16)c-src.val; + else if (c-src.bytes == 4) + c-src.val = (s32)c-src.val; + + mask = ~(c-dst.bytes * 8 - 1); + + if ((long)c-src.val 0) { + /* negative bit offset */ + byte_offset = c-dst.bytes + + ((-c-src.val - 1) mask) / 8; + c-dst.addr.mem -= byte_offset; + } else { + /* positive bit offset */ + c-dst.addr.mem += (c-src.val mask) / 8; + } + } +} + static int read_emulated(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, unsigned long addr, void *dest, unsigned size) @@ -2646,12 +2670,8 @@ done_prefixes: c-dst.bytes = 8; else c-dst.bytes = (c-d ByteOp) ? 1 : c-op_bytes; - if (c-dst.type == OP_MEM (c-d BitOp)) { - unsigned long mask = ~(c-dst.bytes * 8 - 1); - - c-dst.addr.mem = c-dst.addr.mem + - (c-src.val mask) / 8; - } + if (c-d BitOp) + fetch_bit_operand(c); c-dst.orig_val = c-dst.val; break; case DstAcc: -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/3] KVM: x86 emulator: do not adjust the address for immediate source
adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 470c7eb..e7e3d2d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { unsigned long mask, byte_offset; - if (c-dst.type == OP_MEM) { + if (c-dst.type == OP_MEM c-src.type == OP_REG) { if (c-src.bytes == 2) c-src.val = (s16)c-src.val; else if (c-src.bytes == 4) -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] KVM: x86 emulator: mask group 8 instruction as BitOp
Mask group 8 instruction as BitOp, so we can share the code for adjust the source operand. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 11 --- 1 files changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e7e3d2d..dc6a74e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -746,6 +746,9 @@ static void fetch_bit_operand(struct decode_cache *c) c-dst.addr.mem += (c-src.val mask) / 8; } } + + /* only subword offset */ + c-src.val = (c-dst.bytes 3) - 1; } static int read_emulated(struct x86_emulate_ctxt *ctxt, @@ -2346,7 +2349,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ @@ -3420,8 +3423,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bts, c-src, c-dst, ctxt-eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3449,8 +3450,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3472,8 +3471,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3 v2] KVM: x86 emulator: do not adjust the address for immediate source
adjust the dst address for a register source but not adjust the address for an immediate source. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v1 - v2 just fix the missing left bracket of mail title --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 470c7eb..e7e3d2d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -728,7 +728,7 @@ static void fetch_bit_operand(struct decode_cache *c) { unsigned long mask, byte_offset; - if (c-dst.type == OP_MEM) { + if (c-dst.type == OP_MEM c-src.type == OP_REG) { if (c-src.bytes == 2) c-src.val = (s16)c-src.val; else if (c-src.bytes == 4) -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: remove useless label from x86_emulate_insn()
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index dc6a74e..a755b85 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2760,16 +2760,12 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) c-eip = ctxt-eip; } - if (c-src.type == OP_MEM) { - if (c-d NoAccess) - goto no_fetch; + if ((c-src.type == OP_MEM) !(c-d NoAccess)) { rc = read_emulated(ctxt, ops, c-src.addr.mem, c-src.valptr, c-src.bytes); if (rc != X86EMUL_CONTINUE) goto done; c-src.orig_val = c-src.val; - no_fetch: - ; } if (c-src2.type == OP_MEM) { -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: add setcc instruction emulation
Add setcc instruction emulation (opcode 0x0f 0x90~0x9f) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a755b85..e057e57 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2330,7 +2330,7 @@ static struct opcode twobyte_table[256] = { /* 0x80 - 0x8F */ X16(D(SrcImm)), /* 0x90 - 0x9F */ - N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, + X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), /* 0xA0 - 0xA7 */ D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, D(DstMem | SrcReg | ModRM | BitOp), @@ -3390,6 +3390,9 @@ twobyte_insn: if (test_cc(c-b, ctxt-eflags)) jmp_rel(c, c-src.val); break; + case 0x90 ... 0x9f: /* setcc r/m8 */ + c-dst.val = test_cc(c-b, ctxt-eflags); + break; case 0xa0:/* push fs */ emulate_push_sreg(ctxt, ops, VCPU_SREG_FS); break; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: Add test for setcc instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com diff --git a/x86/emulator.c b/x86/emulator.c index e278812..5c8093e 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -375,6 +375,44 @@ void test_btc(void *mem) report(btcl reg, r/m, a[0] == 1 a[1] == 2 a[2] == 0x8004); } +void test_setcc(void *mem) +{ + unsigned char *memb = mem; + + asm (seto %0:=m(*memb)); + report(seto r/m8, *memb == 0); + asm (setno %0:=m(*memb)); + report(setno r/m8, *memb == 1); + asm (setc %0:=m(*memb)); + report(setc r/m8, *memb == 0); + asm (setnc %0:=m(*memb)); + report(setnc r/m8, *memb == 1); + asm (sete %0:=m(*memb)); + report(setz r/m8, *memb == 0); + asm (setne %0:=m(*memb)); + report(setnz r/m8, *memb == 1); + asm (seta %0:=m(*memb)); + report(seta r/m8, *memb == 1); + asm (setna %0:=m(*memb)); + report(setna r/m8, *memb == 0); + asm (sets %0:=m(*memb)); + report(sets r/m8, *memb == 0); + asm (setns %0:=m(*memb)); + report(setns r/m8, *memb == 1); + asm (setp %0:=m(*memb)); + report(setp r/m8, *memb == 0); + asm (setnp %0:=m(*memb)); + report(setnp r/m8, *memb == 1); + asm (setl %0:=m(*memb)); + report(setl r/m8, *memb == 0); + asm (setnl %0:=m(*memb)); + report(setnl r/m8, *memb == 1); + asm (setle %0:=m(*memb)); + report(setle r/m8, *memb == 0); + asm (setnle %0:=m(*memb)); + report(setnle r/m8, *memb == 1); +} + int main() { void *mem; @@ -407,6 +445,7 @@ int main() test_stringio(); test_incdecnotneg(mem); test_btc(mem); + test_setcc(mem); printf(\nSUMMARY: %d tests, %d failures\n, tests, fails); return fails ? 1 : 0; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3] KVM: x86 emulator: fix BitOp instruction emulation
If bit offset operands is a negative number, BitOp instruction will return wrong value. This patch fix it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 45 ++--- 1 files changed, 30 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d197b46..8763708 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -724,6 +724,33 @@ done: return rc; } +static void fetch_bit_operand(struct decode_cache *c) +{ + unsigned long mask, byte_offset; + + if (c-dst.type != OP_MEM || c-src.type != OP_REG) { + /* Only subword offset */ + c-src.val = (c-dst.bytes 3) - 1; + return; + } + + if (c-src.bytes == 2) + c-src.val = (s16)c-src.val; + else if (c-src.bytes == 4) + c-src.val = (s32)c-src.val; + + mask = ~(c-dst.bytes * 8 - 1); + + if ((long)c-src.val 0) { + c-dst.addr.mem = c-dst.addr.mem + (c-src.val mask) / 8; + c-src.val = (c-dst.bytes 3) - 1; + } else { + byte_offset = c-dst.bytes + ((-c-src.val - 1) mask) / 8; + c-dst.addr.mem -= byte_offset; + c-src.val += byte_offset 3; + } +} + static int read_emulated(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, unsigned long addr, void *dest, unsigned size) @@ -2261,7 +2288,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ @@ -2587,12 +2614,8 @@ done_prefixes: c-dst.bytes = 8; else c-dst.bytes = (c-d ByteOp) ? 1 : c-op_bytes; - if (c-dst.type == OP_MEM (c-d BitOp)) { - unsigned long mask = ~(c-dst.bytes * 8 - 1); - - c-dst.addr.mem = c-dst.addr.mem + - (c-src.val mask) / 8; - } + if (c-d BitOp) + fetch_bit_operand(c); c-dst.orig_val = c-dst.val; break; case DstAcc: @@ -3303,8 +3326,6 @@ twobyte_insn: case 0xa3: bt: /* bt */ c-dst.type = OP_NONE; - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bt, c-src, c-dst, ctxt-eflags); break; case 0xa4: /* shld imm8, r, r/m */ @@ -3321,8 +3342,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bts, c-src, c-dst, ctxt-eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3350,8 +3369,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3373,8 +3390,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: add test for btc instruction
This patch add test for btc instruction. Signed-off-by: Wei Yongjunyj...@cn.fujitsu.com --- x86/emulator.c | 16 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/x86/emulator.c b/x86/emulator.c index eefb764..e278812 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -360,6 +360,21 @@ void test_xchg(void *mem) rax == 0x123456789abcdef *memq == 0xfedcba9876543210); } +void test_btc(void *mem) +{ + unsigned int *a = mem; + + memset(mem, 0, 3 * sizeof(unsigned int)); + + asm (btcl $32, %0 :: m(a[0]) : memory); + asm (btcl $1, %0 :: m(a[1]) : memory); + asm (btcl %1, %0 :: m(a[0]), r(66) : memory); + report(btcl imm8, r/m, a[0] == 1 a[1] == 2 a[2] == 4); + + asm (btcl %1, %0 :: m(a[3]), r(-1) : memory); + report(btcl reg, r/m, a[0] == 1 a[1] == 2 a[2] == 0x8004); +} + int main() { void *mem; @@ -391,6 +406,7 @@ int main() test_ljmp(mem); test_stringio(); test_incdecnotneg(mem); + test_btc(mem); printf(\nSUMMARY: %d tests, %d failures\n, tests, fails); return fails ? 1 : 0; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: simplify two-byte opcode check
Two-byte opcode always start with 0x0F and the decode flags of opcode 0xF0 is always 0, so remove dup check. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 12 +--- 1 files changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8763708..a465823 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2405,13 +2405,11 @@ done_prefixes: /* Opcode byte(s). */ opcode = opcode_table[c-b]; - if (opcode.flags == 0) { - /* Two-byte opcode? */ - if (c-b == 0x0f) { - c-twobyte = 1; - c-b = insn_fetch(u8, 1, c-eip); - opcode = twobyte_table[c-b]; - } + /* Two-byte opcode? */ + if (c-b == 0x0f) { + c-twobyte = 1; + c-b = insn_fetch(u8, 1, c-eip); + opcode = twobyte_table[c-b]; } c-d = opcode.flags; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] KVM: x86 emulator: change OUT instruction to use dst instead of src
Change OUT instruction to use dst instead of src, so we can reuse those code for all out instructions. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 15 --- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f952fd0..95815b9 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2261,12 +2261,12 @@ static struct opcode opcode_table[256] = { /* 0xE0 - 0xE7 */ N, N, N, N, D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), - D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), + D(ByteOp | SrcAcc | DstImmUByte), D(SrcAcc | DstImmUByte), /* 0xE8 - 0xEF */ D(SrcImm | Stack), D(SrcImm | ImplicitOps), D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc), - D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc), + D(ByteOp | SrcAcc | ImplicitOps), D(SrcAcc | ImplicitOps), /* 0xF0 - 0xF7 */ N, N, N, N, D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3), @@ -3107,15 +3107,16 @@ special_insn: break; case 0xee: /* out dx,al */ case 0xef: /* out dx,(e/r)ax */ - c-src.val = c-regs[VCPU_REGS_RDX]; + c-dst.val = c-regs[VCPU_REGS_RDX]; do_io_out: - c-dst.bytes = min(c-dst.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-src.val, c-dst.bytes)) { + c-src.bytes = min(c-src.bytes, 4u); + if (!emulator_io_permited(ctxt, ops, c-dst.val, + c-src.bytes)) { emulate_gp(ctxt, 0); goto done; } - ops-pio_out_emulated(c-dst.bytes, c-src.val, c-dst.val, 1, - ctxt-vcpu); + ops-pio_out_emulated(c-src.bytes, c-dst.val, + c-src.val, 1, ctxt-vcpu); c-dst.type = OP_NONE; /* Disable writeback. */ break; case 0xf4: /* hlt */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] KVM: x86 emulator: remove dup code of in/out instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 24 1 files changed, 4 insertions(+), 20 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 95815b9..0e360c6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2870,28 +2870,12 @@ special_insn: break; case 0x6c: /* insb */ case 0x6d: /* insw/insd */ - c-dst.bytes = min(c-dst.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-regs[VCPU_REGS_RDX], - c-dst.bytes)) { - emulate_gp(ctxt, 0); - goto done; - } - if (!pio_in_emulated(ctxt, ops, c-dst.bytes, -c-regs[VCPU_REGS_RDX], c-dst.val)) - goto done; /* IO is needed, skip writeback */ - break; + c-src.val = c-regs[VCPU_REGS_RDX]; + goto do_io_in; case 0x6e: /* outsb */ case 0x6f: /* outsw/outsd */ - c-src.bytes = min(c-src.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-regs[VCPU_REGS_RDX], - c-src.bytes)) { - emulate_gp(ctxt, 0); - goto done; - } - ops-pio_out_emulated(c-src.bytes, c-regs[VCPU_REGS_RDX], - c-src.val, 1, ctxt-vcpu); - - c-dst.type = OP_NONE; /* nothing to writeback */ + c-dst.val = c-regs[VCPU_REGS_RDX]; + goto do_io_out; break; case 0x70 ... 0x7f: /* jcc (short) */ if (test_cc(c-b, ctxt-eflags)) -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] KVM: x86 emulator: introduce DstImmUByte for dst operand decode
Introduce DstImmUByte for dst operand decode, which will be used for out instruction. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a2a079f..f952fd0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -54,6 +54,7 @@ #define DstAcc (41) /* Destination Accumulator */ #define DstDI (51) /* Destination is in ES:(E)DI */ #define DstMem64(61) /* 64bit memory operand */ +#define DstImmUByte (71) /* 8-bit unsigned immediate operand */ #define DstMask (71) /* Source operand type. */ #define SrcNone (04) /* No source operand. */ @@ -2632,6 +2633,12 @@ done_prefixes: decode_register_operand(c-dst, c, c-twobyte (c-b == 0xb6 || c-b == 0xb7)); break; + case DstImmUByte: + c-dst.type = OP_IMM; + c-dst.addr.mem = c-eip; + c-dst.bytes = 1; + c-dst.val = insn_fetch(u8, 1, c-eip); + break; case DstMem: case DstMem64: c-dst = memop; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] KVM: x86 emulator: use SrcAcc to simplify stos decoding
Use SrcAcc to simplify stos decoding. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f03ff26..4624b11 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2175,7 +2175,8 @@ static struct opcode opcode_table[256] = { D(ByteOp | SrcSI | DstDI | Mov | String), D(SrcSI | DstDI | Mov | String), D(ByteOp | SrcSI | DstDI | String), D(SrcSI | DstDI | String), /* 0xA8 - 0xAF */ - D(DstAcc | SrcImmByte | ByteOp), D(DstAcc | SrcImm), D(ByteOp | DstDI | Mov | String), D(DstDI | Mov | String), + D(DstAcc | SrcImmByte | ByteOp), D(DstAcc | SrcImm), + D(ByteOp | SrcAcc | DstDI | Mov | String), D(SrcAcc | DstDI | Mov | String), D(ByteOp | SrcSI | DstAcc | Mov | String), D(SrcSI | DstAcc | Mov | String), D(ByteOp | DstDI | String), D(DstDI | String), /* 0xB0 - 0xB7 */ @@ -2937,8 +2938,6 @@ special_insn: case 0xa8 ... 0xa9: /* test ax, imm */ goto test; case 0xaa ... 0xab: /* stos */ - c-dst.val = c-regs[VCPU_REGS_RAX]; - break; case 0xac ... 0xad: /* lods */ goto mov; case 0xae ... 0xaf: /* scas */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] KVM: x86 emulator: disable writeback when decode dest operand
This patch change to disable writeback when decode dest operand if the dest type is ImplicitOps or not specified. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 23 ++- 1 files changed, 6 insertions(+), 17 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4624b11..31c33f4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2569,9 +2569,6 @@ done_prefixes: /* Decode and fetch the destination operand: register or memory. */ switch (c-d DstMask) { - case ImplicitOps: - /* Special instructions do their own operand decoding. */ - return 0; case DstReg: decode_register_operand(c-dst, c, c-twobyte (c-b == 0xb6 || c-b == 0xb7)); @@ -2606,6 +2603,11 @@ done_prefixes: c-regs[VCPU_REGS_RDI]); c-dst.val = 0; break; + case ImplicitOps: + /* Special instructions do their own operand decoding. */ + default: + c-dst.type = OP_NONE; /* Disable writeback. */ + return 0; } done: @@ -3040,7 +3042,6 @@ special_insn: case 0xf5: /* cmc */ /* complement carry flag from eflags reg */ ctxt-eflags ^= EFLG_CF; - c-dst.type = OP_NONE; /* Disable writeback. */ break; case 0xf6 ... 0xf7: /* Grp3 */ if (!emulate_grp3(ctxt, ops)) @@ -3048,16 +3049,13 @@ special_insn: break; case 0xf8: /* clc */ ctxt-eflags = ~EFLG_CF; - c-dst.type = OP_NONE; /* Disable writeback. */ break; case 0xfa: /* cli */ if (emulator_bad_iopl(ctxt, ops)) { emulate_gp(ctxt, 0); goto done; - } else { + } else ctxt-eflags = ~X86_EFLAGS_IF; - c-dst.type = OP_NONE; /* Disable writeback. */ - } break; case 0xfb: /* sti */ if (emulator_bad_iopl(ctxt, ops)) { @@ -3066,16 +3064,13 @@ special_insn: } else { ctxt-interruptibility = KVM_X86_SHADOW_INT_STI; ctxt-eflags |= X86_EFLAGS_IF; - c-dst.type = OP_NONE; /* Disable writeback. */ } break; case 0xfc: /* cld */ ctxt-eflags = ~EFLG_DF; - c-dst.type = OP_NONE; /* Disable writeback. */ break; case 0xfd: /* std */ ctxt-eflags |= EFLG_DF; - c-dst.type = OP_NONE; /* Disable writeback. */ break; case 0xfe: /* Grp4 */ grp45: @@ -3212,16 +3207,13 @@ twobyte_insn: break; case 0x06: emulate_clts(ctxt-vcpu); - c-dst.type = OP_NONE; break; case 0x09: /* wbinvd */ kvm_emulate_wbinvd(ctxt-vcpu); - c-dst.type = OP_NONE; break; case 0x08: /* invd */ case 0x0d: /* GrpP (prefetch) */ case 0x18: /* Grp16 (prefetch/nop) */ - c-dst.type = OP_NONE; break; case 0x20: /* mov cr, reg */ switch (c-modrm_reg) { @@ -3274,7 +3266,6 @@ twobyte_insn: goto done; } rc = X86EMUL_CONTINUE; - c-dst.type = OP_NONE; break; case 0x32: /* rdmsr */ @@ -3286,7 +3277,6 @@ twobyte_insn: c-regs[VCPU_REGS_RDX] = msr_data 32; } rc = X86EMUL_CONTINUE; - c-dst.type = OP_NONE; break; case 0x34: /* sysenter */ rc = emulate_sysenter(ctxt, ops); @@ -3310,7 +3300,6 @@ twobyte_insn: case 0x80 ... 0x8f: /* jnz rel, etc*/ if (test_cc(c-b, ctxt-eflags)) jmp_rel(c, c-src.val); - c-dst.type = OP_NONE; break; case 0xa0:/* push fs */ emulate_push_sreg(ctxt, ops, VCPU_SREG_FS); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] KVM: x86 emulator: using SrcOne for instruction d0/d1 decoding
Using SrcOne for instruction d0/d1 decoding. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 31c33f4..1ce3c4f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2191,7 +2191,7 @@ static struct opcode opcode_table[256] = { N, N, N, D(ImplicitOps | Stack), D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps), /* 0xD0 - 0xD7 */ - D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM), + D(ByteOp | DstMem | SrcOne | ModRM), D(DstMem | SrcOne | ModRM), D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM), N, N, N, N, /* 0xD8 - 0xDF */ @@ -2971,7 +2971,6 @@ special_insn: goto done; break; case 0xd0 ... 0xd1: /* Grp2 */ - c-src.val = 1; emulate_grp2(ctxt); break; case 0xd2 ... 0xd3: /* Grp2 */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] KVM: x86 emulator: remove dup code of in/out instruction
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 50 --- 1 files changed, 21 insertions(+), 29 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 1ce3c4f..d197b46 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -54,6 +54,7 @@ #define DstAcc (41) /* Destination Accumulator */ #define DstDI (51) /* Destination is in ES:(E)DI */ #define DstMem64(61) /* 64bit memory operand */ +#define DstImmUByte (71) /* 8-bit unsigned immediate operand */ #define DstMask (71) /* Source operand type. */ #define SrcNone (04) /* No source operand. */ @@ -2199,12 +2200,12 @@ static struct opcode opcode_table[256] = { /* 0xE0 - 0xE7 */ N, N, N, N, D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), - D(ByteOp | SrcImmUByte | DstAcc), D(SrcImmUByte | DstAcc), + D(ByteOp | SrcAcc | DstImmUByte), D(SrcAcc | DstImmUByte), /* 0xE8 - 0xEF */ D(SrcImm | Stack), D(SrcImm | ImplicitOps), D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc), - D(SrcNone | ByteOp | DstAcc), D(SrcNone | DstAcc), + D(ByteOp | SrcAcc | ImplicitOps), D(SrcAcc | ImplicitOps), /* 0xF0 - 0xF7 */ N, N, N, N, D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3), @@ -2573,6 +2574,12 @@ done_prefixes: decode_register_operand(c-dst, c, c-twobyte (c-b == 0xb6 || c-b == 0xb7)); break; + case DstImmUByte: + c-dst.type = OP_IMM; + c-dst.addr.mem = c-eip; + c-dst.bytes = 1; + c-dst.val = insn_fetch(u8, 1, c-eip); + break; case DstMem: case DstMem64: c-dst = memop; @@ -2803,29 +2810,12 @@ special_insn: break; case 0x6c: /* insb */ case 0x6d: /* insw/insd */ - c-dst.bytes = min(c-dst.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-regs[VCPU_REGS_RDX], - c-dst.bytes)) { - emulate_gp(ctxt, 0); - goto done; - } - if (!pio_in_emulated(ctxt, ops, c-dst.bytes, -c-regs[VCPU_REGS_RDX], c-dst.val)) - goto done; /* IO is needed, skip writeback */ - break; + c-src.val = c-regs[VCPU_REGS_RDX]; + goto do_io_in; case 0x6e: /* outsb */ case 0x6f: /* outsw/outsd */ - c-src.bytes = min(c-src.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-regs[VCPU_REGS_RDX], - c-src.bytes)) { - emulate_gp(ctxt, 0); - goto done; - } - ops-pio_out_emulated(c-src.bytes, c-regs[VCPU_REGS_RDX], - c-src.val, 1, ctxt-vcpu); - - c-dst.type = OP_NONE; /* nothing to writeback */ - break; + c-dst.val = c-regs[VCPU_REGS_RDX]; + goto do_io_out; case 0x70 ... 0x7f: /* jcc (short) */ if (test_cc(c-b, ctxt-eflags)) jmp_rel(c, c-src.val); @@ -3024,16 +3014,18 @@ special_insn: break; case 0xee: /* out dx,al */ case 0xef: /* out dx,(e/r)ax */ - c-src.val = c-regs[VCPU_REGS_RDX]; + c-dst.val = c-regs[VCPU_REGS_RDX]; do_io_out: - c-dst.bytes = min(c-dst.bytes, 4u); - if (!emulator_io_permited(ctxt, ops, c-src.val, c-dst.bytes)) { + c-src.bytes = min(c-src.bytes, 4u); + if (!emulator_io_permited(ctxt, ops, c-dst.val, + c-src.bytes)) { emulate_gp(ctxt, 0); goto done; } - ops-pio_out_emulated(c-dst.bytes, c-src.val, c-dst.val, 1, - ctxt-vcpu); - c-dst.type = OP_NONE; /* Disable writeback. */ + ops-pio_out_emulated(c-src.bytes, c-dst.val, + c-src.val, 1, ctxt-vcpu); + + c-dst.type = OP_NONE; /* nothing to writeback */ break; case 0xf4: /* hlt */ ctxt-vcpu-arch.halt_request = 1; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: fix group 8 instruction decoding
Group 8 instruction, BT[S|R|C] should be mask as BitOp. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d197b46..eba5a67 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2261,7 +2261,7 @@ static struct opcode twobyte_table[256] = { D(DstReg | SrcMem16 | ModRM | Mov), /* 0xB8 - 0xBF */ N, N, - G(0, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), + G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), /* 0xC0 - 0xCF */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: cleanup for BitOp instruction emulation
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 12 1 files changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index eba5a67..c05a5d7 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2545,6 +2545,10 @@ done_prefixes: break; } + /* Only subword offset for BitOp: bt/bts/btr/btc. */ + if (c-d BitOp) + c-src.val = (c-op_bytes 3) - 1; + /* * Decode and fetch the second source operand: register, memory * or immediate. @@ -3303,8 +3307,6 @@ twobyte_insn: case 0xa3: bt: /* bt */ c-dst.type = OP_NONE; - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bt, c-src, c-dst, ctxt-eflags); break; case 0xa4: /* shld imm8, r, r/m */ @@ -3321,8 +3323,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bts, c-src, c-dst, ctxt-eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3350,8 +3350,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3373,8 +3371,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] KVM: x86 emulator: cleanup for BitOp instruction emulation
On 08/04/2010 11:01 AM, Wei Yongjun wrote: Signed-off-by: Wei Yongjunyj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 12 1 files changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index eba5a67..c05a5d7 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2545,6 +2545,10 @@ done_prefixes: break; } +/* Only subword offset for BitOp: bt/bts/btr/btc. */ +if (c-d BitOp) +c-src.val= (c-op_bytes 3) - 1; + You are doing this before the destination operand is decoded, which means you are not adjusting a memory operand anymore if c-src.val (c-op_bytes * 8). Oh, I forgot this, I will fix it, thanks. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] KVM: x86 emulator: cleanup for BitOp instruction emulation
Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 12 1 files changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index eba5a67..74008ed 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2617,6 +2617,10 @@ done_prefixes: return 0; } + /* Only subword offset for BitOp: bt/bts/btr/btc. */ + if (c-d BitOp) + c-src.val = (c-dst.bytes 3) - 1; + done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } @@ -3303,8 +3307,6 @@ twobyte_insn: case 0xa3: bt: /* bt */ c-dst.type = OP_NONE; - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bt, c-src, c-dst, ctxt-eflags); break; case 0xa4: /* shld imm8, r, r/m */ @@ -3321,8 +3323,6 @@ twobyte_insn: break; case 0xab: bts: /* bts */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(bts, c-src, c-dst, ctxt-eflags); break; case 0xac: /* shrd imm8, r, r/m */ @@ -3350,8 +3350,6 @@ twobyte_insn: break; case 0xb3: btr: /* btr */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btr, c-src, c-dst, ctxt-eflags); break; case 0xb6 ... 0xb7: /* movzx */ @@ -3373,8 +3371,6 @@ twobyte_insn: break; case 0xbb: btc: /* btc */ - /* only subword offset */ - c-src.val = (c-dst.bytes 3) - 1; emulate_2op_SrcV_nobyte(btc, c-src, c-dst, ctxt-eflags); break; case 0xbe ... 0xbf: /* movsx */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] x86 emulator: Add IRET instruction
On Mon, Jul 26, 2010 at 2:59 AM, Paolo Bonzini pbonz...@redhat.com wrote: On 07/25/2010 09:20 PM, Mohammed Gamal wrote: + if (c-op_bytes == 4) + temp_eflags = ((temp_eflags 0x257fd5) | (ctxt-eflags 0x1a)); Should this do also if (c-op_bytes == 2) temp_eflags = ((temp_eflags 0x7fd5) | (ctxt-eflags ~0xL)); ? I don't think this is needed. The temp_eflags value is assigned directly to eflags if we're operand size is 16 bits. At least that's what the Intel manual says! Intel manual says: EFLAGS[15:0] ← Pop(); Or better, extract a new function computing the mask from emulate_popf, which would do something similar to what I wrote above. Paolo -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] KVM: x86 emulator: fix xchg instruction emulation
If the destination is a memory operand and the memory cannot map to a valid page, the xchg instruction emulation and locked instruction will not work on io regions and stuck in endless loop. We should emulate exchange as write to fix it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com Acked-by: Gleb Natapov g...@redhat.com --- arch/x86/kvm/x86.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 86c8102..84bfb51 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3562,6 +3562,10 @@ static int emulator_cmpxchg_emulated(unsigned long addr, goto emul_write; page = gfn_to_page(vcpu-kvm, gpa PAGE_SHIFT); + if (is_error_page(page)) { + kvm_release_page_clean(page); + goto emul_write; + } kaddr = kmap_atomic(page, KM_USER0); kaddr += offset_in_page(gpa); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] test: add test for xchg instruction
This patch add test for xchg instruction. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- kvm/test/x86/emulator.c | 52 +++ 1 files changed, 52 insertions(+), 0 deletions(-) diff --git a/kvm/test/x86/emulator.c b/kvm/test/x86/emulator.c index 6db1305..2af3d96 100644 --- a/kvm/test/x86/emulator.c +++ b/kvm/test/x86/emulator.c @@ -270,6 +270,56 @@ void test_lmsw(void) asm(lmsw %0 : : r(msw)); } +void test_xchg(void *mem) +{ + unsigned long *memq = mem; + unsigned long rax; + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xchg %%al, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xchg reg, r/m (1), + rax == 0xfedcba98765432ef *memq == 0x123456789abcd10); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xchg %%ax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xchg reg, r/m (2), + rax == 0xfedcba987654cdef *memq == 0x123456789ab3210); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xchg %%eax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xchg reg, r/m (3), + rax == 0x89abcdef *memq == 0x123456776543210); + + asm volatile(mov $0x123456789abcdef, %%rax\n\t +mov %%rax, (%[memq])\n\t +mov $0xfedcba9876543210, %%rax\n\t +xchg %%rax, (%[memq])\n\t +mov %%rax, %[rax]\n\t +: [rax]=r(rax) +: [memq]r(memq) +: memory); + report(xchg reg, r/m (4), + rax == 0x123456789abcdef *memq == 0xfedcba9876543210); +} + int main() { void *mem; @@ -292,6 +342,8 @@ int main() test_push(mem); test_pop(mem); + test_xchg(mem); + test_cr8(); test_smsw(); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qemu-kvm: compile error in xen_backend.c
today's qemu-kvm tree + latest xen source Sorry, after I redo configure, the error is gone. Thanks. CC xen_backend.o /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c: In function 'xen_be_get_xendev': /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c:219: error: too few arguments to function 'xc_gnttab_open' cc1: warnings being treated as errors /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c: In function 'xen_be_del_xendev': /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c:272: error: passing argument 1 of 'xc_gnttab_close' makes pointer from integer without a cast /usr/include/xenctrl.h:1055: note: expected 'struct xc_interface *' but argument is of type 'int' /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c:272: error: too few arguments to function 'xc_gnttab_close' /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c: In function 'xen_be_init': /pub/scm/weiyj/source/kvm/qemu-kvm/hw/xen_backend.c:630: error: too few arguments to function 'xc_interface_open' make: *** [xen_backend.o] Error 1 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: PPC: fix leakage of page release in kvmppc_patch_dcbz()
Add kvm_release_page_clean() after is_error_page() to avoid leakage of error page. No test. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/powerpc/kvm/book3s.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index a3cef30..5baa3ab 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -415,8 +415,10 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) int i; hpage = gfn_to_page(vcpu-kvm, pte-raddr PAGE_SHIFT); - if (is_error_page(hpage)) + if (is_error_page(hpage)) { + kvm_release_page_clean(hpage); return; + } hpage_offset = pte-raddr ~PAGE_MASK; hpage_offset = ~0xFFFULL; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: fix xchg instruction emulation
If the destination is a memory operand and the memory cannot map to a valid page, the xchg instruction emulation will fail. If so, we should emulate exchange as write to fix it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/x86.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d94811e..ac63f6f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3560,6 +3560,8 @@ static int emulator_cmpxchg_emulated(unsigned long addr, goto emul_write; page = gfn_to_page(vcpu-kvm, gpa PAGE_SHIFT); + if (is_error_page(page)) + goto emul_write; kaddr = kmap_atomic(page, KM_USER0); kaddr += offset_in_page(gpa); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/6] KVM: x86 emulator: fix 'mov AL,moffs' instruction decoding
On 07/06/2010 11:53 AM, Wei Yongjun wrote: 'mov AL,moffs' do not need decode dest operand and 'mov moffs,AL' do not need decode source operand. @@ -177,8 +177,8 @@ static u32 opcode_table[256] = { 0, 0, SrcImmFAddr | No64, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, /* 0xA0 - 0xA7 */ -ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, -ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, +ByteOp | SrcMem | Mov | MemAbs, SrcMem | Mov | MemAbs, +ByteOp | DstMem | Mov | MemAbs, DstMem | Mov | MemAbs, ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String, ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String, /* 0xA8 - 0xAF */ Autotest rejected this patch (Windows XP fails to install). I think the reason is that without DstReg, op-type is not initialized and writeback fails. I dropped this patch. Suggest re-implementing with DstAcc and (new) SrcAcc. sorry about that, I will send a patch to do this. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] KVM: x86 emulator: re-implementing 'mov AL,moffs' instruction decoding
This patch change to use DstAcc for decoding 'mov AL, moffs' and introduced SrcAcc for decoding 'mov moffs, AL'. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c | 32 +++- 1 files changed, 23 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 99fa1c7..255473f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -70,6 +70,7 @@ #define SrcSI (0xa4) /* Source is in the DS:RSI */ #define SrcImmFAddr (0xb4) /* Source is immediate far address */ #define SrcMemFAddr (0xc4) /* Source is far address in memory */ +#define SrcAcc (0xd4) /* Source Accumulator */ #define SrcMask (0xf4) /* Generic ModRM decode. */ #define ModRM (18) @@ -177,8 +178,8 @@ static u32 opcode_table[256] = { 0, 0, SrcImmFAddr | No64, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, /* 0xA0 - 0xA7 */ - ByteOp | SrcMem | Mov | MemAbs, SrcMem | Mov | MemAbs, - ByteOp | DstMem | Mov | MemAbs, DstMem | Mov | MemAbs, + ByteOp | DstAcc | SrcMem | Mov | MemAbs, DstAcc | SrcMem | Mov | MemAbs, + ByteOp | DstMem | SrcAcc | Mov | MemAbs, DstMem | SrcAcc | Mov | MemAbs, ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String, ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String, /* 0xA8 - 0xAF */ @@ -1186,6 +1187,25 @@ done_prefixes: else c-src.val = insn_fetch(u8, 1, c-eip); break; + case SrcAcc: + c-src.type = OP_REG; + c-src.bytes = (c-d ByteOp) ? 1 : c-op_bytes; + c-src.ptr = c-regs[VCPU_REGS_RAX]; + switch (c-src.bytes) { + case 1: + c-src.val = *(u8 *)c-src.ptr; + break; + case 2: + c-src.val = *(u16 *)c-src.ptr; + break; + case 4: + c-src.val = *(u32 *)c-src.ptr; + break; + case 8: + c-src.val = *(u64 *)c-src.ptr; + break; + } + break; case SrcOne: c-src.bytes = 1; c-src.val = 1; @@ -2854,13 +2874,7 @@ special_insn: if (rc != X86EMUL_CONTINUE) goto done; break; - case 0xa0 ... 0xa1: /* mov */ - c-dst.ptr = (unsigned long *)c-regs[VCPU_REGS_RAX]; - c-dst.val = c-src.val; - break; - case 0xa2 ... 0xa3: /* mov */ - c-dst.val = (unsigned long)c-regs[VCPU_REGS_RAX]; - break; + case 0xa0 ... 0xa3: /* mov */ case 0xa4 ... 0xa5: /* movs */ goto mov; case 0xa6 ... 0xa7: /* cmps */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/6] KVM: x86 emulator: fix 'mov sreg,rm16' instruction decoding
Memory reads for 'mov sreg,rm16' should be 16 bits only. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e8bdddc..d842a7d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -170,7 +170,7 @@ static u32 opcode_table[256] = { ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ModRM | DstReg, - ImplicitOps | SrcMem | ModRM, Group | Group1A, + ImplicitOps | SrcMem16 | ModRM, Group | Group1A, /* 0x90 - 0x97 */ DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, /* 0x98 - 0x9F */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] KVM: x86 emulator: fix the comment of out instruction
Fix the comment of out instruction, using the same style as the other instructions. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d842a7d..ad8d7cd 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2949,8 +2949,8 @@ special_insn: c-dst.val)) goto done; /* IO is needed */ break; - case 0xee: /* out al,dx */ - case 0xef: /* out (e/r)ax,dx */ + case 0xee: /* out dx,al */ + case 0xef: /* out dx,(e/r)ax */ c-src.val = c-regs[VCPU_REGS_RDX]; do_io_out: c-dst.bytes = min(c-dst.bytes, 4u); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] KVM: x86 emulator: fix 'and AL,imm8' instruction decoding
'and AL,imm8' should be mask as ByteOp, otherwise the dest operand length will no correct and we may fill the full EAX when writeback. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ad8d7cd..59568ad 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -123,7 +123,7 @@ static u32 opcode_table[256] = { /* 0x20 - 0x27 */ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, - DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, + ByteOp | DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0, /* 0x28 - 0x2F */ ByteOp | DstMem | SrcReg | ModRM | Lock, DstMem | SrcReg | ModRM | Lock, ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] KVM: x86 emulator: fix 'mov rm,sreg' instruction decoding
The source operand of 'mov rm,sreg' is segment register, not general-purpose register, so remove SrcReg from decoding. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 59568ad..8337567 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -169,7 +169,7 @@ static u32 opcode_table[256] = { /* 0x88 - 0x8F */ ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, - DstMem | SrcReg | ModRM | Mov, ModRM | DstReg, + DstMem | SrcNone | ModRM | Mov, ModRM | DstReg, ImplicitOps | SrcMem16 | ModRM, Group | Group1A, /* 0x90 - 0x97 */ DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] KVM: x86 emulator: fix 'mov AL,moffs' instruction decoding
'mov AL,moffs' do not need decode dest operand and 'mov moffs,AL' do not need decode source operand. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8337567..d4526f2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -177,8 +177,8 @@ static u32 opcode_table[256] = { 0, 0, SrcImmFAddr | No64, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, /* 0xA0 - 0xA7 */ - ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, - ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, + ByteOp | SrcMem | Mov | MemAbs, SrcMem | Mov | MemAbs, + ByteOp | DstMem | Mov | MemAbs, DstMem | Mov | MemAbs, ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String, ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String, /* 0xA8 - 0xAF */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] test: add test for pusha and popa instructions
On 06/15/2010 05:10 AM, Wei Yongjun wrote: This patch add test for pusha and popa instructions. Did you test the test? These tests require 'emulate_invalid_guest_state=1' and to run on Intel to actually test anything. You can check with ftrace whether kvm actually emulated pusha/popa. Yes, I did test this case, and checked kvm actually emulated pusha/popa by add printk to kernel source. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: fix group3 instruction decoding
Group 3 instruction with ModRM reg field as 001 is defined as test instruction under AMD arch, and emulate_grp3() is ready for emulate it, so fix the decoding. static inline int emulate_grp3(...) { ... switch (c-modrm_reg) { case 0 ... 1: /* test */ emulate_2op_SrcV(test, c-src, c-dst, ctxt-eflags); ... } Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/emulate.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index c990db0..abb8cec 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -336,11 +336,11 @@ static u32 group_table[] = { [Group1A*8] = DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, [Group3_Byte*8] = - ByteOp | SrcImm | DstMem | ModRM, 0, + ByteOp | SrcImm | DstMem | ModRM, ByteOp | SrcImm | DstMem | ModRM, ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, 0, 0, 0, 0, [Group3*8] = - DstMem | SrcImm | ModRM, 0, + DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM, DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0, 0, 0, [Group4*8] = -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] KVM: x86 emulator: fix group3 instruction decoding
On 06/17/2010 12:33 PM, Wei Yongjun wrote: Group 3 instruction with ModRM reg field as 001 is defined as test instruction under AMD arch, and emulate_grp3() is ready for emulate it, so fix the decoding. Strange but true. Did you encounter any situation which actually needed this, or did you find this by code inspection? Just found it by source review, looks strange, so... -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86 emulator: fix pusha instruction emulation
emulate pusha instruction only writeback the last EDI register, but the other registers which need to be writeback is ignored. This patch fixed it. --- arch/x86/kvm/emulate.c | 133 ++-- 1 files changed, 73 insertions(+), 60 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a4c2dcd..c990db0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1553,6 +1553,64 @@ exception: return X86EMUL_PROPAGATE_FAULT; } +static inline int writeback(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + int rc; + struct decode_cache *c = ctxt-decode; + u32 err; + + switch (c-dst.type) { + case OP_REG: + /* The 4-byte case *is* correct: +* in 64-bit mode we zero-extend. +*/ + switch (c-dst.bytes) { + case 1: + *(u8 *)c-dst.ptr = (u8)c-dst.val; + break; + case 2: + *(u16 *)c-dst.ptr = (u16)c-dst.val; + break; + case 4: + *c-dst.ptr = (u32)c-dst.val; + break; /* 64b: zero-ext */ + case 8: + *c-dst.ptr = c-dst.val; + break; + } + break; + case OP_MEM: + if (c-lock_prefix) + rc = ops-cmpxchg_emulated( + (unsigned long)c-dst.ptr, + c-dst.orig_val, + c-dst.val, + c-dst.bytes, + err, + ctxt-vcpu); + else + rc = ops-write_emulated( + (unsigned long)c-dst.ptr, + c-dst.val, + c-dst.bytes, + err, + ctxt-vcpu); + if (rc == X86EMUL_PROPAGATE_FAULT) + emulate_pf(ctxt, + (unsigned long)c-dst.ptr, err); + if (rc != X86EMUL_CONTINUE) + return rc; + break; + case OP_NONE: + /* no writeback */ + break; + default: + break; + } + return X86EMUL_CONTINUE; +} + static inline void emulate_push(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1651,11 +1709,12 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, return rc; } -static void emulate_pusha(struct x86_emulate_ctxt *ctxt, +static int emulate_pusha(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = ctxt-decode; unsigned long old_esp = c-regs[VCPU_REGS_RSP]; + int rc = X86EMUL_CONTINUE; int reg = VCPU_REGS_RAX; while (reg = VCPU_REGS_RDI) { @@ -1663,8 +1722,18 @@ static void emulate_pusha(struct x86_emulate_ctxt *ctxt, (c-src.val = old_esp) : (c-src.val = c-regs[reg]); emulate_push(ctxt, ops); + + rc = writeback(ctxt, ops); + if (rc != X86EMUL_CONTINUE) + return rc; + ++reg; } + + /* Disable writeback. */ + c-dst.type = OP_NONE; + + return rc; } static int emulate_popa(struct x86_emulate_ctxt *ctxt, @@ -1817,64 +1886,6 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, return rc; } -static inline int writeback(struct x86_emulate_ctxt *ctxt, - struct x86_emulate_ops *ops) -{ - int rc; - struct decode_cache *c = ctxt-decode; - u32 err; - - switch (c-dst.type) { - case OP_REG: - /* The 4-byte case *is* correct: -* in 64-bit mode we zero-extend. -*/ - switch (c-dst.bytes) { - case 1: - *(u8 *)c-dst.ptr = (u8)c-dst.val; - break; - case 2: - *(u16 *)c-dst.ptr = (u16)c-dst.val; - break; - case 4: - *c-dst.ptr = (u32)c-dst.val; - break; /* 64b: zero-ext */ - case 8: - *c-dst.ptr = c-dst.val; - break; - } - break; - case OP_MEM: - if (c-lock_prefix) - rc = ops-cmpxchg_emulated( - (unsigned long)c-dst.ptr, - c-dst.orig_val, -
[PATCHv2] KVM: x86 emulator: fix pusha instruction emulation
emulate pusha instruction only writeback the last EDI register, but the other registers which need to be writeback is ignored. This patch fixed it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- v1 - v2 add missing signed off by --- arch/x86/kvm/emulate.c | 133 ++-- 1 files changed, 73 insertions(+), 60 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a4c2dcd..c990db0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1553,6 +1553,64 @@ exception: return X86EMUL_PROPAGATE_FAULT; } +static inline int writeback(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + int rc; + struct decode_cache *c = ctxt-decode; + u32 err; + + switch (c-dst.type) { + case OP_REG: + /* The 4-byte case *is* correct: +* in 64-bit mode we zero-extend. +*/ + switch (c-dst.bytes) { + case 1: + *(u8 *)c-dst.ptr = (u8)c-dst.val; + break; + case 2: + *(u16 *)c-dst.ptr = (u16)c-dst.val; + break; + case 4: + *c-dst.ptr = (u32)c-dst.val; + break; /* 64b: zero-ext */ + case 8: + *c-dst.ptr = c-dst.val; + break; + } + break; + case OP_MEM: + if (c-lock_prefix) + rc = ops-cmpxchg_emulated( + (unsigned long)c-dst.ptr, + c-dst.orig_val, + c-dst.val, + c-dst.bytes, + err, + ctxt-vcpu); + else + rc = ops-write_emulated( + (unsigned long)c-dst.ptr, + c-dst.val, + c-dst.bytes, + err, + ctxt-vcpu); + if (rc == X86EMUL_PROPAGATE_FAULT) + emulate_pf(ctxt, + (unsigned long)c-dst.ptr, err); + if (rc != X86EMUL_CONTINUE) + return rc; + break; + case OP_NONE: + /* no writeback */ + break; + default: + break; + } + return X86EMUL_CONTINUE; +} + static inline void emulate_push(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -1651,11 +1709,12 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, return rc; } -static void emulate_pusha(struct x86_emulate_ctxt *ctxt, +static int emulate_pusha(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = ctxt-decode; unsigned long old_esp = c-regs[VCPU_REGS_RSP]; + int rc = X86EMUL_CONTINUE; int reg = VCPU_REGS_RAX; while (reg = VCPU_REGS_RDI) { @@ -1663,8 +1722,18 @@ static void emulate_pusha(struct x86_emulate_ctxt *ctxt, (c-src.val = old_esp) : (c-src.val = c-regs[reg]); emulate_push(ctxt, ops); + + rc = writeback(ctxt, ops); + if (rc != X86EMUL_CONTINUE) + return rc; + ++reg; } + + /* Disable writeback. */ + c-dst.type = OP_NONE; + + return rc; } static int emulate_popa(struct x86_emulate_ctxt *ctxt, @@ -1817,64 +1886,6 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, return rc; } -static inline int writeback(struct x86_emulate_ctxt *ctxt, - struct x86_emulate_ops *ops) -{ - int rc; - struct decode_cache *c = ctxt-decode; - u32 err; - - switch (c-dst.type) { - case OP_REG: - /* The 4-byte case *is* correct: -* in 64-bit mode we zero-extend. -*/ - switch (c-dst.bytes) { - case 1: - *(u8 *)c-dst.ptr = (u8)c-dst.val; - break; - case 2: - *(u16 *)c-dst.ptr = (u16)c-dst.val; - break; - case 4: - *c-dst.ptr = (u32)c-dst.val; - break; /* 64b: zero-ext */ - case 8: - *c-dst.ptr = c-dst.val; - break; - } - break; - case OP_MEM: - if (c-lock_prefix) - rc = ops-cmpxchg_emulated
[PATCH] test: add test for pusha and popa instructions
This patch add test for pusha and popa instructions. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- kvm/test/x86/realmode.c | 46 ++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/kvm/test/x86/realmode.c b/kvm/test/x86/realmode.c index 70a1e05..bd79348 100644 --- a/kvm/test/x86/realmode.c +++ b/kvm/test/x86/realmode.c @@ -820,12 +820,58 @@ void test_null(void) print_serial(null test: PASS\n); } +void test_pusha_popa() +{ + struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs; + + MK_INSN(pusha, pusha\n\t + pop %edi\n\t + pop %esi\n\t + pop %ebp\n\t + pop %eax\n\t + pop %ebx\n\t + pop %edx\n\t + pop %ecx\n\t + pop %esp\n\t + xchg %esp, %eax\n\t + ); + + MK_INSN(popa, push %eax\n\t + push %ecx\n\t + push %edx\n\t + push %ebx\n\t + push %esp\n\t + push %ebp\n\t + push %esi\n\t + push %edi\n\t + popa\n\t + ); + + exec_in_big_real_mode(inregs, outregs, + insn_pusha, + insn_pusha_end - insn_pusha); + + if (!regs_equal(inregs, outregs, 0)) + print_serial(Pusha/Popa Test1: FAIL\n); + else + print_serial(Pusha/Popa Test1: PASS\n); + + exec_in_big_real_mode(inregs, outregs, + insn_popa, + insn_popa_end - insn_popa); + if (!regs_equal(inregs, outregs, 0)) + print_serial(Pusha/Popa Test2: FAIL\n); + else + print_serial(Pusha/Popa Test2: PASS\n); +} + void realmode_start(void) { test_null(); test_shld(); test_push_pop(); + test_pusha_popa(); test_mov_imm(); test_cmp_imm(); test_add_imm(); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: MMU: cleanup for function unaccount_shadowed()
Since gfn is not changed in the for loop, we do not need to call gfn_to_memslot_unaliased() under the loop, and it is safe to move it out. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/mmu.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index d217f9c..0494f64 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -430,9 +430,9 @@ static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) int i; gfn = unalias_gfn(kvm, gfn); + slot = gfn_to_memslot_unaliased(kvm, gfn); for (i = PT_DIRECTORY_LEVEL; i PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { - slot = gfn_to_memslot_unaliased(kvm, gfn); write_count = slot_largepage_idx(gfn, slot, i); *write_count -= 1; WARN_ON(*write_count 0); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: ia64: fix the error code of ioctl KVM_IA64_VCPU_GET_STACK failure
The ioctl KVM_IA64_VCPU_GET_STACK does not set the error code if copy_to_user() fail, and 0 will be return, we should use -EFAULT instead of 0 in this case, so this patch fixed it. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/ia64/kvm/kvm-ia64.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 26e0e08..bc07c81 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1535,8 +1535,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp, goto out; if (copy_to_user(user_stack, stack, -sizeof(struct kvm_ia64_vcpu_stack))) +sizeof(struct kvm_ia64_vcpu_stack))) { + r = -EFAULT; goto out; + } break; } -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: x86: fix the error of ioctl KVM_IRQ_LINE if no irq chip
If no irq chip in kernel, ioctl KVM_IRQ_LINE will return -EFAULT. But I see in other place such as KVM_[GET|SET]IRQCHIP, -ENXIO is return. So this patch used -ENXIO instead of -EFAULT. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/x86/kvm/x86.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3753c11..c6b7e9f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2857,11 +2857,13 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(irq_event, argp, sizeof irq_event)) goto out; + r = -ENXIO; if (irqchip_in_kernel(kvm)) { __s32 status; status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irq_event.irq, irq_event.level); if (ioctl == KVM_IRQ_LINE_STATUS) { + r = -EFAULT; irq_event.status = status; if (copy_to_user(argp, irq_event, sizeof irq_event)) -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: ia64: fix the error of ioctl KVM_IRQ_LINE if no irq chip
If no irq chip in kernel, ioctl KVM_IRQ_LINE will return -EFAULT. But I see in other place such as KVM_[GET|SET]IRQCHIP, -ENXIO is return. So this patch used -ENXIO instead of -EFAULT. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- arch/ia64/kvm/kvm-ia64.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 26e0e08..0d2e41a 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -979,11 +979,13 @@ long kvm_arch_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(irq_event, argp, sizeof irq_event)) goto out; + r = -ENXIO; if (irqchip_in_kernel(kvm)) { __s32 status; status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irq_event.irq, irq_event.level); if (ioctl == KVM_IRQ_LINE_STATUS) { + r = -EFAULT; irq_event.status = status; if (copy_to_user(argp, irq_event, sizeof irq_event)) -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] KVM: coalesced_mmio: NULLify the pointers before freeing ring page and dev
Takuya Yoshikawa wrote: kvm_coalesced_mmio_init() keeps to hold the addresses of a coalesced mmio ring page and dev even after it has freed them. This may trigger problems, e.g., if we call kvm_coalesced_mmio_free() in kvm_destroy_vm() or kvm_vm_ioctl_register_coalesced_mmio() afterward. This patch avoids such problems by NULLifying the pointers. After this patch, I think we also need to do some check in kvm_vcpu_fault() for coalesced_mmio_ring, since the coalesced_mmio may not be init correctly. This is other issue, so I will send a new patch for this. Signed-off-by: Takuya Yoshikawa yoshikawa.tak...@oss.ntt.co.jp --- virt/kvm/coalesced_mmio.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 5169736..11776b7 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c @@ -119,8 +119,10 @@ int kvm_coalesced_mmio_init(struct kvm *kvm) return ret; out_free_dev: + kvm-coalesced_mmio_dev = NULL; kfree(dev); out_free_page: + kvm-coalesced_mmio_ring = NULL; __free_page(page); out_err: return ret; -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: fix to not use NULL kvm-coalesced_mmio_ring in kvm_vcpu_fault()
If coalesced_mmio init fail, the kvm-coalesced_mmio_ring will be set to NULL. If so, we should return VM_FAULT_SIGBUS in kvm_vcpu_fault() even if vmf-pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- virt/kvm/kvm_main.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index e758ef7..0e06a6d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1253,7 +1253,8 @@ static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf) page = virt_to_page(vcpu-arch.pio_data); #endif #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET - else if (vmf-pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET) + else if (vmf-pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET +vcpu-kvm-coalesced_mmio_ring) page = virt_to_page(vcpu-kvm-coalesced_mmio_ring); #endif else -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM: fix the errno of ioctl KVM_[UN]REGISTER_COALESCED_MMIO failure
This patch change the errno of ioctl KVM_[UN]REGISTER_COALESCED_MMIO from -EINVAL to -ENXIO if no coalesced mmio dev exists. Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com --- virt/kvm/coalesced_mmio.c |4 ++-- virt/kvm/kvm_main.c |2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 5169736..22500d4 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c @@ -138,7 +138,7 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, struct kvm_coalesced_mmio_dev *dev = kvm-coalesced_mmio_dev; if (dev == NULL) - return -EINVAL; + return -ENXIO; mutex_lock(kvm-slots_lock); if (dev-nb_zones = KVM_COALESCED_MMIO_ZONE_MAX) { @@ -161,7 +161,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, struct kvm_coalesced_mmio_zone *z; if (dev == NULL) - return -EINVAL; + return -ENXIO; mutex_lock(kvm-slots_lock); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 0e06a6d..861435e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1603,7 +1603,6 @@ static long kvm_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(zone, argp, sizeof zone)) goto out; - r = -ENXIO; r = kvm_vm_ioctl_register_coalesced_mmio(kvm, zone); if (r) goto out; @@ -1615,7 +1614,6 @@ static long kvm_vm_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(zone, argp, sizeof zone)) goto out; - r = -ENXIO; r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, zone); if (r) goto out; -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html