* [Qemu-devel] [PULL 1/8] target-i386: Remove unused data from local array
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 2/8] kvm: add set_one_reg/get_one_reg helpers Paolo Bonzini
` (7 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Stefan Weil
From: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target-i386/kvm.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7a295f6..114f9e1 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -130,14 +130,13 @@ struct kvm_para_features {
{ KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
{ KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
- { -1, -1 }
};
static int get_para_features(KVMState *s)
{
int i, features = 0;
- for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
+ for (i = 0; i < ARRAY_SIZE(para_features); i++) {
if (kvm_check_extension(s, para_features[i].cap)) {
features |= (1 << para_features[i].feature);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 2/8] kvm: add set_one_reg/get_one_reg helpers
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 1/8] target-i386: Remove unused data from local array Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 3/8] pci-assign: Fix a bug when map MSI-X table memory failed Paolo Bonzini
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Alexey Kardashevskiy
From: Alexey Kardashevskiy <aik@ozlabs.ru>
This adds QEMU wrappers for KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctls.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/sysemu/kvm.h | 20 ++++++++++++++++++++
kvm-all.c | 18 ++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0bee1e8..84a4f40 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -343,6 +343,26 @@ void kvm_pc_setup_irq_routing(bool pci_enabled);
void kvm_init_irq_routing(KVMState *s);
/**
+ * kvm_set_one_reg - set a register value in KVM via KVM_SET_ONE_REG ioctl
+ * @id: The register ID
+ * @addr: The pointer to a value must point to a variable of the correct
+ * type/size for the register being accessed.
+ *
+ * Returns: 0 on success, or a negative errno on failure.
+ */
+int kvm_set_one_reg(CPUState *cs, uint64_t id, void *addr);
+
+/**
+ * kvm_get_one_reg - get a register value from KVM via KVM_GET_ONE_REG ioctl
+ * @id: The register ID
+ * @addr: The pointer to a value must point to a variable of the correct
+ * type/size for the register being accessed.
+ *
+ * Returns: 0 on success, or a negative errno on failure.
+ */
+int kvm_get_one_reg(CPUState *cs, uint64_t id, void *addr);
+
+/**
* kvm_arch_irqchip_create:
* @KVMState: The KVMState pointer
*
diff --git a/kvm-all.c b/kvm-all.c
index 82a9119..724c423 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2114,3 +2114,21 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test)
return test ? 0 : create_dev.fd;
}
+
+int kvm_set_one_reg(CPUState *cs, uint64_t id, void *addr)
+{
+ struct kvm_one_reg reg = {
+ .id = id,
+ .addr = (uintptr_t)addr,
+ };
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+}
+
+int kvm_get_one_reg(CPUState *cs, uint64_t id, void *addr)
+{
+ struct kvm_one_reg reg = {
+ .id = id,
+ .addr = (uintptr_t)addr,
+ };
+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 3/8] pci-assign: Fix a bug when map MSI-X table memory failed
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 1/8] target-i386: Remove unused data from local array Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 2/8] kvm: add set_one_reg/get_one_reg helpers Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 4/8] pci-assign: limit # of msix vectors Paolo Bonzini
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Gonglei
From: Gonglei <arei.gonglei@huawei.com>
when map MSI-X table memory failed, the dev->msix_table not be
set to NULL, the assigned_dev_unregister_msix_mmio() will case
a segfault when munmap the failed dev->msix_table.
Signed-off-by: Gonglei Arei <arei.gonglei@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/kvm/pci-assign.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index a825871..570333f 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1608,6 +1608,7 @@ static int assigned_dev_register_msix_mmio(AssignedDevice *dev)
MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
if (dev->msix_table == MAP_FAILED) {
error_report("fail allocate msix_table! %s", strerror(errno));
+ dev->msix_table = NULL;
return -EFAULT;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 4/8] pci-assign: limit # of msix vectors
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (2 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 3/8] pci-assign: Fix a bug when map MSI-X table memory failed Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 5/8] target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c Paolo Bonzini
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable, Michael S. Tsirkin
From: "Michael S. Tsirkin" <mst@redhat.com>
KVM only supports MSIX table size up to 256 vectors,
but some assigned devices support more vectors,
at the moment attempts to assign them fail with EINVAL.
Tweak the MSIX capability exposed to guest to limit table size
to a supported value.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Gonglei <arei.gonglei@huawei.com>
Cc: qemu-stable@nongnu.org
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/i386/kvm/pci-assign.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 570333f..ca58508 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1258,6 +1258,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
if (pos != 0 && kvm_device_msix_supported(kvm_state)) {
int bar_nr;
uint32_t msix_table_entry;
+ uint16_t msix_max;
if (!check_irqchip_in_kernel()) {
return -ENOTSUP;
@@ -1269,9 +1270,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
}
pci_dev->msix_cap = pos;
- pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS,
- pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) &
- PCI_MSIX_FLAGS_QSIZE);
+ msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) &
+ PCI_MSIX_FLAGS_QSIZE) + 1;
+ msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV);
+ pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1);
/* Only enable and function mask bits are writable */
pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS,
@@ -1281,9 +1283,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK;
msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK;
dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry;
- dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS);
- dev->msix_max &= PCI_MSIX_FLAGS_QSIZE;
- dev->msix_max += 1;
+ dev->msix_max = msix_max;
}
/* Minimal PM support, nothing writable, device appears to NAK changes */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 5/8] target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (3 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 4/8] pci-assign: limit # of msix vectors Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 6/8] target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c Paolo Bonzini
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin O'Connor
From: Kevin O'Connor <kevin@koconnor.net>
The svm_load_seg_cache() function calls cpu_x86_load_seg_cache() which
inspects env->eflags. So, make sure all changes to eflags are done
prior to loading the segment cache.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target-i386/svm_helper.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index aa17ecd..848a4b9 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -703,7 +703,8 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
cpu_load_eflags(env, ldq_phys(cs->as,
env->vm_hsave + offsetof(struct vmcb,
save.rflags)),
- ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
+ ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK |
+ VM_MASK));
CC_OP = CC_OP_EFLAGS;
svm_load_seg_cache(env, env->vm_hsave + offsetof(struct vmcb, save.es),
@@ -756,10 +757,6 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
from the page table indicated the host's CR3. If the PDPEs contain
illegal state, the processor causes a shutdown. */
- /* Forces CR0.PE = 1, RFLAGS.VM = 0. */
- env->cr[0] |= CR0_PE_MASK;
- env->eflags &= ~VM_MASK;
-
/* Disables all breakpoints in the host DR7 register. */
/* Checks the reloaded host state for consistency. */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 6/8] target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (4 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 5/8] target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 7/8] target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c Paolo Bonzini
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin O'Connor
From: Kevin O'Connor <kevin@koconnor.net>
The cpu_x86_load_seg_cache() function inspects cr0 and eflags, so make
sure all changes to eflags and cr0 are done prior to loading the
segment caches.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target-i386/smm_helper.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 35901c9..4841d53 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -163,6 +163,13 @@ void do_smm_enter(X86CPU *cpu)
cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
DF_MASK));
env->eip = 0x00008000;
+ cpu_x86_update_cr0(env,
+ env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
+ CR0_PG_MASK));
+ cpu_x86_update_cr4(env, 0);
+ env->dr[7] = 0x00000400;
+ CC_OP = CC_OP_EFLAGS;
+
cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff, 0);
@@ -170,13 +177,6 @@ void do_smm_enter(X86CPU *cpu)
cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff, 0);
cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff, 0);
-
- cpu_x86_update_cr0(env,
- env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
- CR0_PG_MASK));
- cpu_x86_update_cr4(env, 0);
- env->dr[7] = 0x00000400;
- CC_OP = CC_OP_EFLAGS;
}
void helper_rsm(CPUX86State *env)
@@ -191,16 +191,6 @@ void helper_rsm(CPUX86State *env)
#ifdef TARGET_X86_64
cpu_load_efer(env, ldq_phys(cs->as, sm_state + 0x7ed0));
- for (i = 0; i < 6; i++) {
- offset = 0x7e00 + i * 16;
- cpu_x86_load_seg_cache(env, i,
- lduw_phys(cs->as, sm_state + offset),
- ldq_phys(cs->as, sm_state + offset + 8),
- ldl_phys(cs->as, sm_state + offset + 4),
- (lduw_phys(cs->as, sm_state + offset + 2) &
- 0xf0ff) << 8);
- }
-
env->gdt.base = ldq_phys(cs->as, sm_state + 0x7e68);
env->gdt.limit = ldl_phys(cs->as, sm_state + 0x7e64);
@@ -238,6 +228,16 @@ void helper_rsm(CPUX86State *env)
cpu_x86_update_cr3(env, ldl_phys(cs->as, sm_state + 0x7f50));
cpu_x86_update_cr0(env, ldl_phys(cs->as, sm_state + 0x7f58));
+ for (i = 0; i < 6; i++) {
+ offset = 0x7e00 + i * 16;
+ cpu_x86_load_seg_cache(env, i,
+ lduw_phys(cs->as, sm_state + offset),
+ ldq_phys(cs->as, sm_state + offset + 8),
+ ldl_phys(cs->as, sm_state + offset + 4),
+ (lduw_phys(cs->as, sm_state + offset + 2) &
+ 0xf0ff) << 8);
+ }
+
val = ldl_phys(cs->as, sm_state + 0x7efc); /* revision ID */
if (val & 0x20000) {
env->smbase = ldl_phys(cs->as, sm_state + 0x7f00) & ~0x7fff;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 7/8] target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (5 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 6/8] target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-10 6:50 ` [Qemu-devel] [PULL 8/8] target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly Paolo Bonzini
2014-05-13 10:31 ` [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Cornelia Huck
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin O'Connor
From: Kevin O'Connor <kevin@koconnor.net>
The cpu_x86_load_seg_cache() function inspects eflags, so make sure
all changes to eflags are done prior to loading the segment caches.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target-i386/seg_helper.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 8c3f92c..2e0b113 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -739,6 +739,12 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
}
}
+ /* interrupt gate clear IF mask */
+ if ((type & 1) == 0) {
+ env->eflags &= ~IF_MASK;
+ }
+ env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
+
if (new_stack) {
if (env->eflags & VM_MASK) {
cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0, 0);
@@ -759,12 +765,6 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
e2);
cpu_x86_set_cpl(env, dpl);
env->eip = offset;
-
- /* interrupt gate clear IF mask */
- if ((type & 1) == 0) {
- env->eflags &= ~IF_MASK;
- }
- env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
}
#ifdef TARGET_X86_64
@@ -911,6 +911,12 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
PUSHQ(esp, error_code);
}
+ /* interrupt gate clear IF mask */
+ if ((type & 1) == 0) {
+ env->eflags &= ~IF_MASK;
+ }
+ env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
+
if (new_stack) {
ss = 0 | dpl;
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
@@ -924,12 +930,6 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
e2);
cpu_x86_set_cpl(env, dpl);
env->eip = offset;
-
- /* interrupt gate clear IF mask */
- if ((type & 1) == 0) {
- env->eflags &= ~IF_MASK;
- }
- env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);
}
#endif
@@ -960,6 +960,8 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
code64 = env->hflags & HF_CS64_MASK;
+ env->eflags &= ~env->fmask;
+ cpu_load_eflags(env, env->eflags, 0);
cpu_x86_set_cpl(env, 0);
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
0, 0xffffffff,
@@ -972,8 +974,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~env->fmask;
- cpu_load_eflags(env, env->eflags, 0);
if (code64) {
env->eip = env->lstar;
} else {
@@ -982,6 +982,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
} else {
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
+ env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
cpu_x86_set_cpl(env, 0);
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
0, 0xffffffff,
@@ -993,7 +994,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK |
DESC_W_MASK | DESC_A_MASK);
- env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
env->eip = (uint32_t)env->star;
}
}
@@ -1014,6 +1014,9 @@ void helper_sysret(CPUX86State *env, int dflag)
}
selector = (env->star >> 48) & 0xffff;
if (env->hflags & HF_LMA_MASK) {
+ cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK
+ | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK |
+ NT_MASK);
if (dflag == 2) {
cpu_x86_load_seg_cache(env, R_CS, (selector + 16) | 3,
0, 0xffffffff,
@@ -1035,11 +1038,9 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
- cpu_load_eflags(env, (uint32_t)(env->regs[11]), TF_MASK | AC_MASK
- | ID_MASK | IF_MASK | IOPL_MASK | VM_MASK | RF_MASK |
- NT_MASK);
cpu_x86_set_cpl(env, 3);
} else {
+ env->eflags |= IF_MASK;
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -1051,7 +1052,6 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
- env->eflags |= IF_MASK;
cpu_x86_set_cpl(env, 3);
}
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PULL 8/8] target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly.
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (6 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 7/8] target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c Paolo Bonzini
@ 2014-05-10 6:50 ` Paolo Bonzini
2014-05-13 10:31 ` [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Cornelia Huck
8 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-10 6:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin O'Connor
From: Kevin O'Connor <kevin@koconnor.net>
Instead of manually calling cpu_x86_set_cpl() when the CPL changes,
check for CPL changes on calls to cpu_x86_load_seg_cache(R_CS). Every
location that called cpu_x86_set_cpl() also called
cpu_x86_load_seg_cache(R_CS), so cpu_x86_set_cpl() is no longer
required.
This fixes the SMM handler code as it was not setting/restoring the
CPL level manually.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
bsd-user/main.c | 2 --
linux-user/main.c | 2 --
target-i386/cpu.h | 25 ++++++++++++-------------
target-i386/seg_helper.c | 15 ---------------
target-i386/svm_helper.c | 4 ----
5 files changed, 12 insertions(+), 36 deletions(-)
diff --git a/bsd-user/main.c b/bsd-user/main.c
index f81ba55..9f895b4 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1003,8 +1003,6 @@ int main(int argc, char **argv)
cpu->opaque = ts;
#if defined(TARGET_I386)
- cpu_x86_set_cpl(env, 3);
-
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK;
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
diff --git a/linux-user/main.c b/linux-user/main.c
index af924dc..37b3d40 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4059,8 +4059,6 @@ int main(int argc, char **argv, char **envp)
#endif
#if defined(TARGET_I386)
- cpu_x86_set_cpl(env, 3);
-
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK;
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4d1374c..e00699f 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -124,9 +124,9 @@
#define ID_MASK 0x00200000
/* hidden flags - used internally by qemu to represent additional cpu
- states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
- redundant. We avoid using the IOPL_MASK, TF_MASK, VM_MASK and AC_MASK
- bit positions to ease oring with eflags. */
+ states. Only the INHIBIT_IRQ, SMM and SVMI are not redundant. We
+ avoid using the IOPL_MASK, TF_MASK, VM_MASK and AC_MASK bit
+ positions to ease oring with eflags. */
/* current cpl */
#define HF_CPL_SHIFT 0
/* true if soft mmu is being used */
@@ -974,6 +974,7 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
/* update the hidden flags */
{
if (seg_reg == R_CS) {
+ int cpl = selector & 3;
#ifdef TARGET_X86_64
if ((env->hflags & HF_LMA_MASK) && (flags & DESC_L_MASK)) {
/* long mode */
@@ -983,11 +984,19 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
#endif
{
/* legacy / compatibility case */
+ if (!(env->cr[0] & CR0_PE_MASK))
+ cpl = 0;
+ else if (env->eflags & VM_MASK)
+ cpl = 3;
new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
>> (DESC_B_SHIFT - HF_CS32_SHIFT);
env->hflags = (env->hflags & ~(HF_CS32_MASK | HF_CS64_MASK)) |
new_hflags;
}
+#if HF_CPL_MASK != 3
+#error HF_CPL_MASK is hardcoded
+#endif
+ env->hflags = (env->hflags & ~HF_CPL_MASK) | cpl;
}
new_hflags = (env->segs[R_SS].flags & DESC_B_MASK)
>> (DESC_B_SHIFT - HF_SS32_SHIFT);
@@ -1031,16 +1040,6 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
target_ulong *base, unsigned int *limit,
unsigned int *flags);
-/* wrapper, just in case memory mappings must be changed */
-static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
-{
-#if HF_CPL_MASK == 3
- s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
-#else
-#error HF_CPL_MASK is hardcoded
-#endif
-}
-
/* op_helper.c */
/* used for debug or cpu save/restore */
void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 2e0b113..3cf862e 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -409,11 +409,7 @@ static void switch_tss(CPUX86State *env, int tss_selector,
for (i = 0; i < 6; i++) {
load_seg_vm(env, i, new_segs[i]);
}
- /* in vm86, CPL is always 3 */
- cpu_x86_set_cpl(env, 3);
} else {
- /* CPL is set the RPL of CS */
- cpu_x86_set_cpl(env, new_segs[R_CS] & 3);
/* first just selectors as the rest may trigger exceptions */
for (i = 0; i < 6; i++) {
cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);
@@ -763,7 +759,6 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
- cpu_x86_set_cpl(env, dpl);
env->eip = offset;
}
@@ -928,7 +923,6 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
- cpu_x86_set_cpl(env, dpl);
env->eip = offset;
}
#endif
@@ -962,7 +956,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
env->eflags &= ~env->fmask;
cpu_load_eflags(env, env->eflags, 0);
- cpu_x86_set_cpl(env, 0);
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_P_MASK |
@@ -983,7 +976,6 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
env->regs[R_ECX] = (uint32_t)(env->eip + next_eip_addend);
env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
- cpu_x86_set_cpl(env, 0);
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -1038,7 +1030,6 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
- cpu_x86_set_cpl(env, 3);
} else {
env->eflags |= IF_MASK;
cpu_x86_load_seg_cache(env, R_CS, selector | 3,
@@ -1052,7 +1043,6 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_W_MASK | DESC_A_MASK);
- cpu_x86_set_cpl(env, 3);
}
}
#endif
@@ -1905,7 +1895,6 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
- cpu_x86_set_cpl(env, dpl);
SET_ESP(sp, sp_mask);
env->eip = offset;
}
@@ -2134,7 +2123,6 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
get_seg_base(e1, e2),
get_seg_limit(e1, e2),
e2);
- cpu_x86_set_cpl(env, rpl);
sp = new_esp;
#ifdef TARGET_X86_64
if (env->hflags & HF_CS64_MASK) {
@@ -2185,7 +2173,6 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
IF_MASK | IOPL_MASK | VM_MASK | NT_MASK | VIF_MASK |
VIP_MASK);
load_seg_vm(env, R_CS, new_cs & 0xffff);
- cpu_x86_set_cpl(env, 3);
load_seg_vm(env, R_SS, new_ss & 0xffff);
load_seg_vm(env, R_ES, new_es & 0xffff);
load_seg_vm(env, R_DS, new_ds & 0xffff);
@@ -2238,7 +2225,6 @@ void helper_sysenter(CPUX86State *env)
raise_exception_err(env, EXCP0D_GPF, 0);
}
env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
- cpu_x86_set_cpl(env, 0);
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
@@ -2274,7 +2260,6 @@ void helper_sysexit(CPUX86State *env, int dflag)
if (env->sysenter_cs == 0 || cpl != 0) {
raise_exception_err(env, EXCP0D_GPF, 0);
}
- cpu_x86_set_cpl(env, 3);
#ifdef TARGET_X86_64
if (dflag == 2) {
cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 32) & 0xfffc) |
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 848a4b9..846eaa5 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -282,9 +282,6 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
env->vm_vmcb + offsetof(struct vmcb, save.dr7));
env->dr[6] = ldq_phys(cs->as,
env->vm_vmcb + offsetof(struct vmcb, save.dr6));
- cpu_x86_set_cpl(env, ldub_phys(cs->as,
- env->vm_vmcb + offsetof(struct vmcb,
- save.cpl)));
/* FIXME: guest state consistency checks */
@@ -729,7 +726,6 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
env->vm_hsave + offsetof(struct vmcb, save.dr7));
/* other setups */
- cpu_x86_set_cpl(env, 0);
stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, control.exit_code),
exit_code);
stq_phys(cs->as, env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1),
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08
2014-05-10 6:50 [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Paolo Bonzini
` (7 preceding siblings ...)
2014-05-10 6:50 ` [Qemu-devel] [PULL 8/8] target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly Paolo Bonzini
@ 2014-05-13 10:31 ` Cornelia Huck
2014-05-13 11:13 ` Paolo Bonzini
8 siblings, 1 reply; 11+ messages in thread
From: Cornelia Huck @ 2014-05-13 10:31 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Alexey Kardashevskiy, Christian Borntraeger, qemu-devel,
Alexander Graf
On Sat, 10 May 2014 08:50:44 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:
> The following changes since commit 3a87f8b6859e6221b827ab4737779dddb37553ec:
>
> Merge remote-tracking branch 'remotes/afaerber/tags/ppc-for-2.0' into staging (2014-03-20 11:45:38 +0000)
>
> are available in the git repository at:
>
>
> git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
I rebased to qemu/master, where compilation fails with
/home/cohuck/git/qemu/target-s390x/kvm.c:132: error: static declaration of ‘kvm_set_one_reg’ follows non-static declaration
/home/cohuck/git/qemu/include/sysemu/kvm.h:383: error: previous declaration of ‘kvm_set_one_reg’ was here
/home/cohuck/git/qemu/target-s390x/kvm.c:146: error: static declaration of ‘kvm_get_one_reg’ follows non-static declaration
/home/cohuck/git/qemu/include/sysemu/kvm.h:393: error: previous declaration of ‘kvm_get_one_reg’ was here
>
> for you to fetch changes up to 12474c96368ec3a01ad95c81fe9d00bd33e01877:
>
> target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly. (2014-05-10 08:47:56 +0200)
>
> ----------------------------------------------------------------
> Alexey Kardashevskiy (1):
> kvm: add set_one_reg/get_one_reg helpers
Here's where the conflict gets introduced. I don't mind using generic
helper functions, but these are missing the trace events on failure. So
I'd either like to have this patch replaced by
<1399622806-61662-1-git-send-email-cornelia.huck@de.ibm.com>, or
alternatively I can do an add-on patch that removes the s390
implementation introduced with 860643bc ("s390x/kvm: rework KVM
synchronize to tracing for some ONEREGS") and adds a trace event to the
common code implementation.
>
> Gonglei (1):
> pci-assign: Fix a bug when map MSI-X table memory failed
>
> Kevin O'Connor (4):
> target-i386: set eflags prior to calling svm_load_seg_cache() in svm_helper.c
> target-i386: set eflags and cr0 prior to calling cpu_x86_load_seg_cache() in smm_helper.c
> target-i386: set eflags prior to calling cpu_x86_load_seg_cache() in seg_helper.c
> target-i386: the x86 CPL is stored in CS.selector - auto update hflags accordingly.
>
> Michael S. Tsirkin (1):
> pci-assign: limit # of msix vectors
>
> Stefan Weil (1):
> target-i386: Remove unused data from local array
>
> bsd-user/main.c | 2 --
> hw/i386/kvm/pci-assign.c | 13 ++++++------
> include/sysemu/kvm.h | 20 ++++++++++++++++++
> kvm-all.c | 18 ++++++++++++++++
> linux-user/main.c | 2 --
> target-i386/cpu.h | 25 +++++++++++------------
> target-i386/kvm.c | 3 +--
> target-i386/seg_helper.c | 53 +++++++++++++++++-------------------------------
> target-i386/smm_helper.c | 34 +++++++++++++++----------------
> target-i386/svm_helper.c | 11 ++--------
> 10 files changed, 96 insertions(+), 85 deletions(-)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08
2014-05-13 10:31 ` [Qemu-devel] [PULL 0/8] KVM changes for 2014-05-08 Cornelia Huck
@ 2014-05-13 11:13 ` Paolo Bonzini
0 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2014-05-13 11:13 UTC (permalink / raw)
To: Cornelia Huck
Cc: Alexey Kardashevskiy, Christian Borntraeger, qemu-devel,
Alexander Graf
Il 13/05/2014 12:31, Cornelia Huck ha scritto:
> On Sat, 10 May 2014 08:50:44 +0200
> Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>> The following changes since commit 3a87f8b6859e6221b827ab4737779dddb37553ec:
>>
>> Merge remote-tracking branch 'remotes/afaerber/tags/ppc-for-2.0' into staging (2014-03-20 11:45:38 +0000)
>>
>> are available in the git repository at:
>>
>>
>> git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
>
> I rebased to qemu/master, where compilation fails with
>
> /home/cohuck/git/qemu/target-s390x/kvm.c:132: error: static declaration of ‘kvm_set_one_reg’ follows non-static declaration
> /home/cohuck/git/qemu/include/sysemu/kvm.h:383: error: previous declaration of ‘kvm_set_one_reg’ was here
> /home/cohuck/git/qemu/target-s390x/kvm.c:146: error: static declaration of ‘kvm_get_one_reg’ follows non-static declaration
> /home/cohuck/git/qemu/include/sysemu/kvm.h:393: error: previous declaration of ‘kvm_get_one_reg’ was here
I'll resend the pull request, thanks.
Paolo
^ permalink raw reply [flat|nested] 11+ messages in thread