* [PATCH 01/39] KVM: VMX: Clean up magic number 0x66 in init_rmode_tss
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 02/39] KVM: remove unused field from the assigned dev struct Avi Kivity
` (37 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Sheng Yang
From: Sheng Yang <sheng.yang@intel.com>
Signed-off-by: Sheng Yang <sheng.yang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ddb49e3..229e2d0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1732,7 +1732,8 @@ static int init_rmode_tss(struct kvm *kvm)
if (r < 0)
goto out;
data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE;
- r = kvm_write_guest_page(kvm, fn++, &data, 0x66, sizeof(u16));
+ r = kvm_write_guest_page(kvm, fn++, &data,
+ TSS_IOPB_BASE_OFFSET, sizeof(u16));
if (r < 0)
goto out;
r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE);
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 02/39] KVM: remove unused field from the assigned dev struct
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
2008-09-25 11:54 ` [PATCH 01/39] KVM: VMX: Clean up magic number 0x66 in init_rmode_tss Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 03/39] KVM: set debug registers after "schedulable" section Avi Kivity
` (36 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Ben-Ami Yassour
From: Ben-Ami Yassour <benami@il.ibm.com>
Remove unused field: struct kvm_assigned_pci_dev assigned_dev
from struct: struct kvm_assigned_dev_kernel
Signed-off-by: Ben-Ami Yassour <benami@il.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
include/asm-x86/kvm_host.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index fb7d7b7..1161af1 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -341,7 +341,6 @@ struct kvm_assigned_dev_kernel {
struct kvm_irq_ack_notifier ack_notifier;
struct work_struct interrupt_work;
struct list_head list;
- struct kvm_assigned_pci_dev assigned_dev;
int assigned_dev_id;
int host_busnr;
int host_devfn;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 03/39] KVM: set debug registers after "schedulable" section
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
2008-09-25 11:54 ` [PATCH 01/39] KVM: VMX: Clean up magic number 0x66 in init_rmode_tss Avi Kivity
2008-09-25 11:54 ` [PATCH 02/39] KVM: remove unused field from the assigned dev struct Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 04/39] KVM: VMX: Use interrupt queue for !irqchip_in_kernel Avi Kivity
` (35 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Marcelo Tosatti
From: Marcelo Tosatti <mtosatti@redhat.com>
The vcpu thread can be preempted after the guest_debug_pre() callback,
resulting in invalid debug registers on the new vcpu.
Move it inside the non-preemptable section.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f1b0223..4a03375 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3113,10 +3113,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
down_read(&vcpu->kvm->slots_lock);
vapic_enter(vcpu);
-preempted:
- if (vcpu->guest_debug.enabled)
- kvm_x86_ops->guest_debug_pre(vcpu);
-
again:
if (vcpu->requests)
if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
@@ -3170,6 +3166,9 @@ again:
goto out;
}
+ if (vcpu->guest_debug.enabled)
+ kvm_x86_ops->guest_debug_pre(vcpu);
+
vcpu->guest_mode = 1;
/*
* Make sure that guest_mode assignment won't happen after
@@ -3244,7 +3243,7 @@ out:
if (r > 0) {
kvm_resched(vcpu);
down_read(&vcpu->kvm->slots_lock);
- goto preempted;
+ goto again;
}
post_kvm_run_save(vcpu, kvm_run);
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 04/39] KVM: VMX: Use interrupt queue for !irqchip_in_kernel
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (2 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 03/39] KVM: set debug registers after "schedulable" section Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 05/39] KVM: Simplify exception entries by using __ASM_SIZE and _ASM_PTR Avi Kivity
` (34 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 229e2d0..81db7d4 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2173,7 +2173,7 @@ static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
if (!vcpu->arch.irq_pending[word_index])
clear_bit(word_index, &vcpu->arch.irq_summary);
- vmx_inject_irq(vcpu, irq);
+ kvm_queue_interrupt(vcpu, irq);
}
@@ -2187,13 +2187,12 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
if (vcpu->arch.interrupt_window_open &&
- vcpu->arch.irq_summary &&
- !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK))
- /*
- * If interrupts enabled, and not blocked by sti or mov ss. Good.
- */
+ vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending)
kvm_do_inject_irq(vcpu);
+ if (vcpu->arch.interrupt_window_open && vcpu->arch.interrupt.pending)
+ vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
+
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
if (!vcpu->arch.interrupt_window_open &&
(vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 05/39] KVM: Simplify exception entries by using __ASM_SIZE and _ASM_PTR
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (3 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 04/39] KVM: VMX: Use interrupt queue for !irqchip_in_kernel Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 06/39] KVM: fix i8259 reset irq acking Avi Kivity
` (33 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
include/asm-x86/kvm_host.h | 13 ++-----------
1 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 1161af1..982b6b2 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -734,15 +734,6 @@ enum {
TASK_SWITCH_GATE = 3,
};
-
-#ifdef CONFIG_64BIT
-# define KVM_EX_ENTRY ".quad"
-# define KVM_EX_PUSH "pushq"
-#else
-# define KVM_EX_ENTRY ".long"
-# define KVM_EX_PUSH "pushl"
-#endif
-
/*
* Hardware virtualization extension instructions may fault if a
* reboot turns off virtualization while processes are running.
@@ -754,11 +745,11 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
"666: " insn "\n\t" \
".pushsection .fixup, \"ax\" \n" \
"667: \n\t" \
- KVM_EX_PUSH " $666b \n\t" \
+ __ASM_SIZE(push) " $666b \n\t" \
"jmp kvm_handle_fault_on_reboot \n\t" \
".popsection \n\t" \
".pushsection __ex_table, \"a\" \n\t" \
- KVM_EX_ENTRY " 666b, 667b \n\t" \
+ _ASM_PTR " 666b, 667b \n\t" \
".popsection"
#define KVM_ARCH_WANT_MMU_NOTIFIER
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 06/39] KVM: fix i8259 reset irq acking
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (4 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 05/39] KVM: Simplify exception entries by using __ASM_SIZE and _ASM_PTR Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 07/39] KVM: Handle spurious acks for PIT interrupts Avi Kivity
` (32 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Marcelo Tosatti
From: Marcelo Tosatti <mtosatti@redhat.com>
The irq ack during pic reset has three problems:
- Ignores slave/master PIC, using gsi 0-8 for both.
- Generates an ACK even if the APIC is in control.
- Depends upon IMR being clear, which is broken if the irq was masked
at the time it was generated.
The last one causes the BIOS to hang after the first reboot of
Windows installation, since PIT interrupts stop.
[avi: fix check whether pic interrupts are seen by cpu]
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/i8259.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index de70499..71e3eee 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -195,13 +195,19 @@ int kvm_pic_read_irq(struct kvm *kvm)
void kvm_pic_reset(struct kvm_kpic_state *s)
{
- int irq;
+ int irq, irqbase;
struct kvm *kvm = s->pics_state->irq_request_opaque;
+ struct kvm_vcpu *vcpu0 = kvm->vcpus[0];
- for (irq = 0; irq < PIC_NUM_PINS; irq++) {
- if (!(s->imr & (1 << irq)) && (s->irr & (1 << irq) ||
- s->isr & (1 << irq)))
- kvm_notify_acked_irq(kvm, irq);
+ if (s == &s->pics_state->pics[0])
+ irqbase = 0;
+ else
+ irqbase = 8;
+
+ for (irq = 0; irq < PIC_NUM_PINS/2; irq++) {
+ if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
+ if (s->irr & (1 << irq) || s->isr & (1 << irq))
+ kvm_notify_acked_irq(kvm, irq+irqbase);
}
s->last_irr = 0;
s->irr = 0;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 07/39] KVM: Handle spurious acks for PIT interrupts
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (5 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 06/39] KVM: fix i8259 reset irq acking Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 08/39] KVM: Device assignment: Check for privileges before assigning irq Avi Kivity
` (31 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Spurious acks can be generated, for example if the PIC is being reset.
Handle those acks gracefully rather than flooding the log with warnings.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/i8254.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 7d04dd3..c842060 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -228,7 +228,7 @@ void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
irq_ack_notifier);
spin_lock(&ps->inject_lock);
if (atomic_dec_return(&ps->pit_timer.pending) < 0)
- WARN_ON(1);
+ atomic_inc(&ps->pit_timer.pending);
ps->irq_ack = 1;
spin_unlock(&ps->inject_lock);
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 08/39] KVM: Device assignment: Check for privileges before assigning irq
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (6 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 07/39] KVM: Handle spurious acks for PIT interrupts Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 09/39] KVM: VMX: Add Guest State Validity Checks Avi Kivity
` (30 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Amit Shah
From: Amit Shah <amit.shah@qumranet.com>
Even though we don't share irqs at the moment, we should ensure
regular user processes don't try to allocate system resources.
We check for capability to access IO devices (CAP_SYS_RAWIO) before
we request_irq on behalf of the guest.
Noticed by Avi.
Signed-off-by: Amit Shah <amit.shah@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4a03375..fffdf4f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -191,6 +191,11 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
kvm_assigned_dev_interrupt_work_handler);
if (irqchip_in_kernel(kvm)) {
+ if (!capable(CAP_SYS_RAWIO)) {
+ return -EPERM;
+ goto out;
+ }
+
if (assigned_irq->host_irq)
match->host_irq = assigned_irq->host_irq;
else
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 09/39] KVM: VMX: Add Guest State Validity Checks
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (7 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 08/39] KVM: Device assignment: Check for privileges before assigning irq Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 10/39] KVM: VMX: Add module parameter and emulation flag Avi Kivity
` (29 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Mohammed Gamal
From: Mohammed Gamal <m.gamal005@gmail.com>
This patch adds functions to check whether guest state is VMX compliant.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 180 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 81db7d4..e889b76 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1721,6 +1721,186 @@ static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
vmcs_writel(GUEST_GDTR_BASE, dt->base);
}
+static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg)
+{
+ struct kvm_segment var;
+ u32 ar;
+
+ vmx_get_segment(vcpu, &var, seg);
+ ar = vmx_segment_access_rights(&var);
+
+ if (var.base != (var.selector << 4))
+ return false;
+ if (var.limit != 0xffff)
+ return false;
+ if (ar != 0xf3)
+ return false;
+
+ return true;
+}
+
+static bool code_segment_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment cs;
+ unsigned int cs_rpl;
+
+ vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
+ cs_rpl = cs.selector & SELECTOR_RPL_MASK;
+
+ if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK))
+ return false;
+ if (!cs.s)
+ return false;
+ if (!(~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK))) {
+ if (cs.dpl > cs_rpl)
+ return false;
+ } else if (cs.type & AR_TYPE_CODE_MASK) {
+ if (cs.dpl != cs_rpl)
+ return false;
+ }
+ if (!cs.present)
+ return false;
+
+ /* TODO: Add Reserved field check, this'll require a new member in the kvm_segment_field structure */
+ return true;
+}
+
+static bool stack_segment_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment ss;
+ unsigned int ss_rpl;
+
+ vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
+ ss_rpl = ss.selector & SELECTOR_RPL_MASK;
+
+ if ((ss.type != 3) || (ss.type != 7))
+ return false;
+ if (!ss.s)
+ return false;
+ if (ss.dpl != ss_rpl) /* DPL != RPL */
+ return false;
+ if (!ss.present)
+ return false;
+
+ return true;
+}
+
+static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg)
+{
+ struct kvm_segment var;
+ unsigned int rpl;
+
+ vmx_get_segment(vcpu, &var, seg);
+ rpl = var.selector & SELECTOR_RPL_MASK;
+
+ if (!var.s)
+ return false;
+ if (!var.present)
+ return false;
+ if (~var.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK)) {
+ if (var.dpl < rpl) /* DPL < RPL */
+ return false;
+ }
+
+ /* TODO: Add other members to kvm_segment_field to allow checking for other access
+ * rights flags
+ */
+ return true;
+}
+
+static bool tr_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment tr;
+
+ vmx_get_segment(vcpu, &tr, VCPU_SREG_TR);
+
+ if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */
+ return false;
+ if ((tr.type != 3) || (tr.type != 11)) /* TODO: Check if guest is in IA32e mode */
+ return false;
+ if (!tr.present)
+ return false;
+
+ return true;
+}
+
+static bool ldtr_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment ldtr;
+
+ vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR);
+
+ if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */
+ return false;
+ if (ldtr.type != 2)
+ return false;
+ if (!ldtr.present)
+ return false;
+
+ return true;
+}
+
+static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment cs, ss;
+
+ vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
+ vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
+
+ return ((cs.selector & SELECTOR_RPL_MASK) ==
+ (ss.selector & SELECTOR_RPL_MASK));
+}
+
+/*
+ * Check if guest state is valid. Returns true if valid, false if
+ * not.
+ * We assume that registers are always usable
+ */
+static bool guest_state_valid(struct kvm_vcpu *vcpu)
+{
+ /* real mode guest state checks */
+ if (!(vcpu->arch.cr0 & X86_CR0_PE)) {
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_DS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_ES))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_FS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_GS))
+ return false;
+ } else {
+ /* protected mode guest state checks */
+ if (!cs_ss_rpl_check(vcpu))
+ return false;
+ if (!code_segment_valid(vcpu))
+ return false;
+ if (!stack_segment_valid(vcpu))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_DS))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_ES))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_FS))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_GS))
+ return false;
+ if (!tr_valid(vcpu))
+ return false;
+ if (!ldtr_valid(vcpu))
+ return false;
+ }
+ /* TODO:
+ * - Add checks on RIP
+ * - Add checks on RFLAGS
+ */
+
+ return true;
+}
+
static int init_rmode_tss(struct kvm *kvm)
{
gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 10/39] KVM: VMX: Add module parameter and emulation flag.
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (8 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 09/39] KVM: VMX: Add Guest State Validity Checks Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 11/39] KVM: VMX: Add invalid guest state handler Avi Kivity
` (28 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Mohammed Gamal
From: Mohammed Gamal <m.gamal005@gmail.com>
The patch adds the module parameter required to enable emulating invalid
guest state, as well as the emulation_required flag used to drive
emulation whenever needed.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e889b76..7c5f611 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -49,6 +49,9 @@ module_param(flexpriority_enabled, bool, 0);
static int enable_ept = 1;
module_param(enable_ept, bool, 0);
+static int emulate_invalid_guest_state = 0;
+module_param(emulate_invalid_guest_state, bool, 0);
+
struct vmcs {
u32 revision_id;
u32 abort;
@@ -86,6 +89,7 @@ struct vcpu_vmx {
} irq;
} rmode;
int vpid;
+ bool emulation_required;
};
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 11/39] KVM: VMX: Add invalid guest state handler
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (9 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 10/39] KVM: VMX: Add module parameter and emulation flag Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 12/39] KVM: VMX: Modify mode switching and vmentry functions Avi Kivity
` (27 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Mohammed Gamal
From: Mohammed Gamal <m.gamal005@gmail.com>
This adds the invalid guest state handler function which invokes the x86
emulator until getting the guest to a VMX-friendly state.
[avi: leave atomic context if scheduling]
[guillaume: return to atomic context correctly]
Signed-off-by: Laurent Vivier <laurent.vivier@bull.net>
Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7c5f611..eae1f2c 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2892,6 +2892,43 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}
+static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
+ struct kvm_run *kvm_run)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ int err;
+
+ preempt_enable();
+ local_irq_enable();
+
+ while (!guest_state_valid(vcpu)) {
+ err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+
+ switch (err) {
+ case EMULATE_DONE:
+ break;
+ case EMULATE_DO_MMIO:
+ kvm_report_emulation_failure(vcpu, "mmio");
+ /* TODO: Handle MMIO */
+ return;
+ default:
+ kvm_report_emulation_failure(vcpu, "emulation failure");
+ return;
+ }
+
+ if (signal_pending(current))
+ break;
+ if (need_resched())
+ schedule();
+ }
+
+ local_irq_disable();
+ preempt_disable();
+
+ /* Guest state should be valid now, no more emulation should be needed */
+ vmx->emulation_required = 0;
+}
+
/*
* The exit handlers return 1 if the exit was handled fully and guest execution
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 12/39] KVM: VMX: Modify mode switching and vmentry functions
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (10 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 11/39] KVM: VMX: Add invalid guest state handler Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 13/39] KVM: SVM: Fix typo Avi Kivity
` (26 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Mohammed Gamal
From: Mohammed Gamal <m.gamal005@gmail.com>
This patch modifies mode switching and vmentry function in order to
drive invalid guest state emulation.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index eae1f2c..9840f37 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1298,7 +1298,9 @@ static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save)
static void enter_pmode(struct kvm_vcpu *vcpu)
{
unsigned long flags;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ vmx->emulation_required = 1;
vcpu->arch.rmode.active = 0;
vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base);
@@ -1315,6 +1317,9 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
update_exception_bitmap(vcpu);
+ if (emulate_invalid_guest_state)
+ return;
+
fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
@@ -1355,7 +1360,9 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
static void enter_rmode(struct kvm_vcpu *vcpu)
{
unsigned long flags;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ vmx->emulation_required = 1;
vcpu->arch.rmode.active = 1;
vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
@@ -1377,6 +1384,9 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME);
update_exception_bitmap(vcpu);
+ if (emulate_invalid_guest_state)
+ goto continue_rmode;
+
vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4);
vmcs_write32(GUEST_SS_LIMIT, 0xffff);
vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
@@ -1392,6 +1402,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
+continue_rmode:
kvm_mmu_reset_context(vcpu);
init_rmode(vcpu->kvm);
}
@@ -2317,6 +2328,9 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
ret = 0;
+ /* HACK: Don't enable emulation on guest boot/reset */
+ vmx->emulation_required = 0;
+
out:
up_read(&vcpu->kvm->slots_lock);
return ret;
@@ -3190,6 +3204,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 intr_info;
+ /* Handle invalid guest state instead of entering VMX */
+ if (vmx->emulation_required && emulate_invalid_guest_state) {
+ handle_invalid_guest_state(vcpu, kvm_run);
+ return;
+ }
+
if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 13/39] KVM: SVM: Fix typo
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (11 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 12/39] KVM: VMX: Modify mode switching and vmentry functions Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 14/39] KVM: Use kvm_set_irq to inject interrupts Avi Kivity
` (25 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Amit Shah
From: Amit Shah <amit.shah@qumranet.com>
Fix typo in as-yet unused macro definition.
Signed-off-by: Amit Shah <amit.shah@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/svm.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 179c2e0..be86c09 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL");
#define SVM_FEATURE_NPT (1 << 0)
#define SVM_FEATURE_LBRV (1 << 1)
-#define SVM_DEATURE_SVML (1 << 2)
+#define SVM_FEATURE_SVML (1 << 2)
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 14/39] KVM: Use kvm_set_irq to inject interrupts
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (12 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 13/39] KVM: SVM: Fix typo Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 15/39] KVM: make irq ack notifier functions static Avi Kivity
` (24 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Amit Shah
From: Amit Shah <amit.shah@qumranet.com>
... instead of using the pic and ioapic variants
Signed-off-by: Amit Shah <amit.shah@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/i8254.c | 6 ++----
arch/x86/kvm/x86.c | 8 +-------
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index c842060..fdaa0f0 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -596,10 +596,8 @@ void kvm_free_pit(struct kvm *kvm)
static void __inject_pit_timer_intr(struct kvm *kvm)
{
mutex_lock(&kvm->lock);
- kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1);
- kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 0);
- kvm_pic_set_irq(pic_irqchip(kvm), 0, 1);
- kvm_pic_set_irq(pic_irqchip(kvm), 0, 0);
+ kvm_set_irq(kvm, 0, 1);
+ kvm_set_irq(kvm, 0, 0);
mutex_unlock(&kvm->lock);
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fffdf4f..5b3c882 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1956,13 +1956,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
if (irqchip_in_kernel(kvm)) {
mutex_lock(&kvm->lock);
- if (irq_event.irq < 16)
- kvm_pic_set_irq(pic_irqchip(kvm),
- irq_event.irq,
- irq_event.level);
- kvm_ioapic_set_irq(kvm->arch.vioapic,
- irq_event.irq,
- irq_event.level);
+ kvm_set_irq(kvm, irq_event.irq, irq_event.level);
mutex_unlock(&kvm->lock);
r = 0;
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 15/39] KVM: make irq ack notifier functions static
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (13 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 14/39] KVM: Use kvm_set_irq to inject interrupts Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 16/39] KVM: ia64: add a dummy irq ack notification Avi Kivity
` (23 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Harvey Harrison
From: Harvey Harrison <harvey.harrison@gmail.com>
sparse says:
arch/x86/kvm/x86.c:107:32: warning: symbol 'kvm_find_assigned_dev' was not declared. Should it be static?
arch/x86/kvm/i8254.c:225:6: warning: symbol 'kvm_pit_ack_irq' was not declared. Should it be static?
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/i8254.c | 2 +-
arch/x86/kvm/x86.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index fdaa0f0..4cb4430 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -222,7 +222,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu)
return 0;
}
-void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
+static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
{
struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
irq_ack_notifier);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5b3c882..22edd95 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -104,7 +104,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ NULL }
};
-struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
+static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
int assigned_dev_id)
{
struct list_head *ptr;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 16/39] KVM: ia64: add a dummy irq ack notification
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (14 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 15/39] KVM: make irq ack notifier functions static Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 17/39] KVM: VMX: Change cs reset state to be a data segment Avi Kivity
` (22 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Xiantao Zhang
From: Xiantao Zhang <xiantao.zhang@intel.com>
Before enabling notify_acked_irq for ia64, leave the related APIs as
nop-op first.
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/ia64/kvm/irq.h | 32 ++++++++++++++++++++++++++++++++
virt/kvm/ioapic.c | 2 +-
2 files changed, 33 insertions(+), 1 deletions(-)
create mode 100644 arch/ia64/kvm/irq.h
diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h
new file mode 100644
index 0000000..f2e6545
--- /dev/null
+++ b/arch/ia64/kvm/irq.h
@@ -0,0 +1,32 @@
+/*
+ * irq.h: In-kernel interrupt controller related definitions
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ * Xiantao Zhang <xiantao.zhang@intel.com>
+ *
+ */
+
+#ifndef __IRQ_H
+#define __IRQ_H
+
+struct kvm;
+
+static inline void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi)
+{
+}
+
+#endif
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 515cd7c..53772bb 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -386,7 +386,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
break;
#ifdef CONFIG_IA64
case IOAPIC_REG_EOI:
- kvm_ioapic_update_eoi(ioapic->kvm, data);
+ kvm_ioapic_update_eoi(ioapic->kvm, data, IOAPIC_LEVEL_TRIG);
break;
#endif
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 17/39] KVM: VMX: Change cs reset state to be a data segment
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (15 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 16/39] KVM: ia64: add a dummy irq ack notification Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 18/39] KVM: VMX: Change segment dpl at reset to 3 Avi Kivity
` (21 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Real mode cs is a data segment, not a code segment.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 9840f37..6aa305a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2239,6 +2239,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
fx_init(&vmx->vcpu);
+ seg_setup(VCPU_SREG_CS);
/*
* GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
* insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
@@ -2250,8 +2251,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_write16(GUEST_CS_SELECTOR, vmx->vcpu.arch.sipi_vector << 8);
vmcs_writel(GUEST_CS_BASE, vmx->vcpu.arch.sipi_vector << 12);
}
- vmcs_write32(GUEST_CS_LIMIT, 0xffff);
- vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
seg_setup(VCPU_SREG_DS);
seg_setup(VCPU_SREG_ES);
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 18/39] KVM: VMX: Change segment dpl at reset to 3
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (16 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 17/39] KVM: VMX: Change cs reset state to be a data segment Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 19/39] KVM: Load real mode segments correctly Avi Kivity
` (20 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
This is more emulation friendly, if not 100% correct.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/vmx.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 6aa305a..71e57ae 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1991,7 +1991,7 @@ static void seg_setup(int seg)
vmcs_write16(sf->selector, 0);
vmcs_writel(sf->base, 0);
vmcs_write32(sf->limit, 0xffff);
- vmcs_write32(sf->ar_bytes, 0x93);
+ vmcs_write32(sf->ar_bytes, 0xf3);
}
static int alloc_apic_access_page(struct kvm *kvm)
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 19/39] KVM: Load real mode segments correctly
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (17 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 18/39] KVM: VMX: Change segment dpl at reset to 3 Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 20/39] KVM: x86 emulator: remove duplicate SrcImm Avi Kivity
` (19 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Real mode segments to not reference the GDT or LDT; they simply compute
base = selector * 16.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 22edd95..bfc7c33 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3588,11 +3588,33 @@ static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu,
return 0;
}
+int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg)
+{
+ struct kvm_segment segvar = {
+ .base = selector << 4,
+ .limit = 0xffff,
+ .selector = selector,
+ .type = 3,
+ .present = 1,
+ .dpl = 3,
+ .db = 0,
+ .s = 1,
+ .l = 0,
+ .g = 0,
+ .avl = 0,
+ .unusable = 0,
+ };
+ kvm_x86_ops->set_segment(vcpu, &segvar, seg);
+ return 0;
+}
+
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
int type_bits, int seg)
{
struct kvm_segment kvm_seg;
+ if (!(vcpu->arch.cr0 & X86_CR0_PE))
+ return kvm_load_realmode_segment(vcpu, selector, seg);
if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
return 1;
kvm_seg.type |= type_bits;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 20/39] KVM: x86 emulator: remove duplicate SrcImm
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (18 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 19/39] KVM: Load real mode segments correctly Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 21/39] KVM: x86 emulator: remove bad ByteOp specifier from NEG descriptor Avi Kivity
` (18 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, roel kluin
From: roel kluin <roel.kluin@gmail.com>
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86_emulate.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index d5da7f1..5d6c144 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -269,7 +269,7 @@ static u16 group_table[] = {
ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
0, 0, 0, 0,
[Group3*8] =
- DstMem | SrcImm | ModRM | SrcImm, 0,
+ DstMem | SrcImm | ModRM, 0,
DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
0, 0, 0, 0,
[Group4*8] =
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 21/39] KVM: x86 emulator: remove bad ByteOp specifier from NEG descriptor
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (19 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 20/39] KVM: x86 emulator: remove duplicate SrcImm Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 22/39] KVM: MMU: Move SHADOW_PT_INDEX to mmu.c Avi Kivity
` (17 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86_emulate.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 5d6c144..ae30435 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -270,7 +270,7 @@ static u16 group_table[] = {
0, 0, 0, 0,
[Group3*8] =
DstMem | SrcImm | ModRM, 0,
- DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
+ DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
0, 0, 0, 0,
[Group4*8] =
ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 22/39] KVM: MMU: Move SHADOW_PT_INDEX to mmu.c
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (20 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 21/39] KVM: x86 emulator: remove bad ByteOp specifier from NEG descriptor Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 23/39] KVM: MMU: Unify direct map 4K and large page paths Avi Kivity
` (16 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
It is not specific to the paging mode, so can be made global (and reusable).
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 2 ++
arch/x86/kvm/paging_tmpl.h | 3 ---
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 171bcea..51d4cd7 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -135,6 +135,8 @@ module_param(dbg, bool, 0644);
#define ACC_USER_MASK PT_USER_MASK
#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
+#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
+
struct kvm_rmap_desc {
u64 *shadow_ptes[RMAP_EXT];
struct kvm_rmap_desc *more;
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 4a814bf..ebb26a0 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -29,7 +29,6 @@
#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
#define PT_INDEX(addr, level) PT64_INDEX(addr, level)
- #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
#define PT_LEVEL_BITS PT64_LEVEL_BITS
#ifdef CONFIG_X86_64
@@ -46,7 +45,6 @@
#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
#define PT_INDEX(addr, level) PT32_INDEX(addr, level)
- #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
#define PT_LEVEL_BITS PT32_LEVEL_BITS
#define PT_MAX_FULL_LEVELS 2
@@ -504,7 +502,6 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
#undef FNAME
#undef PT_BASE_ADDR_MASK
#undef PT_INDEX
-#undef SHADOW_PT_INDEX
#undef PT_LEVEL_MASK
#undef PT_DIR_BASE_ADDR_MASK
#undef PT_LEVEL_BITS
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 23/39] KVM: MMU: Unify direct map 4K and large page paths
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (21 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 22/39] KVM: MMU: Move SHADOW_PT_INDEX to mmu.c Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 24/39] KVM: ia64: Enable virtio driver for ia64 in Kconfig Avi Kivity
` (15 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
The two paths are equivalent except for one argument, which is already
available. Merge the two codepaths.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 11 +++--------
1 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 51d4cd7..3ee856f 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1240,15 +1240,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
ASSERT(VALID_PAGE(table_addr));
table = __va(table_addr);
- if (level == 1) {
+ if (level == 1 || (largepage && level == 2)) {
mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
- 0, write, 1, &pt_write, 0, gfn, pfn, false);
- return pt_write;
- }
-
- if (largepage && level == 2) {
- mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
- 0, write, 1, &pt_write, 1, gfn, pfn, false);
+ 0, write, 1, &pt_write, largepage,
+ gfn, pfn, false);
return pt_write;
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 24/39] KVM: ia64: Enable virtio driver for ia64 in Kconfig
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (22 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 23/39] KVM: MMU: Unify direct map 4K and large page paths Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 25/39] KVM: MMU: Infer shadow root level in direct_map() Avi Kivity
` (14 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Xiantao Zhang
From: Xiantao Zhang <xiantao.zhang@intel.com>
kvm/ia64 uses the virtio drivers to optimize its I/O subsytem.
Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/ia64/kvm/Kconfig | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 7914e48..8e99fed 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -46,4 +46,6 @@ config KVM_INTEL
config KVM_TRACE
bool
+source drivers/virtio/Kconfig
+
endif # VIRTUALIZATION
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 25/39] KVM: MMU: Infer shadow root level in direct_map()
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (23 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 24/39] KVM: ia64: Enable virtio driver for ia64 in Kconfig Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 26/39] KVM: MMU: Add generic shadow walker Avi Kivity
` (13 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
In all cases the shadow root level is available in mmu.shadow_root_level,
so there is no need to pass it as a parameter.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 3ee856f..72f739a 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1227,11 +1227,11 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
}
static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int largepage, gfn_t gfn, pfn_t pfn,
- int level)
+ int largepage, gfn_t gfn, pfn_t pfn)
{
hpa_t table_addr = vcpu->arch.mmu.root_hpa;
int pt_write = 0;
+ int level = vcpu->arch.mmu.shadow_root_level;
for (; ; level--) {
u32 index = PT64_INDEX(v, level);
@@ -1299,8 +1299,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
- r = __direct_map(vcpu, v, write, largepage, gfn, pfn,
- PT32E_ROOT_LEVEL);
+ r = __direct_map(vcpu, v, write, largepage, gfn, pfn);
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -1455,7 +1454,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
- largepage, gfn, pfn, kvm_x86_ops->get_tdp_level());
+ largepage, gfn, pfn);
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 26/39] KVM: MMU: Add generic shadow walker
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (24 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 25/39] KVM: MMU: Infer shadow root level in direct_map() Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:54 ` [PATCH 27/39] KVM: MMU: Convert direct maps to use the " Avi Kivity
` (12 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
We currently walk the shadow page tables in two places: direct map (for
real mode and two dimensional paging) and paging mode shadow. Since we
anticipate requiring a third walk (for invlpg), it makes sense to have
a generic facility for shadow walk.
This patch adds such a shadow walker, walks the page tables and calls a
method for every spte encountered. The method can examine the spte,
modify it, or even instantiate it. The walk can be aborted by returning
nonzero from the method.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 34 ++++++++++++++++++++++++++++++++++
1 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 72f739a..8b95cf7 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -142,6 +142,11 @@ struct kvm_rmap_desc {
struct kvm_rmap_desc *more;
};
+struct kvm_shadow_walk {
+ int (*entry)(struct kvm_shadow_walk *walk, struct kvm_vcpu *vcpu,
+ gva_t addr, u64 *spte, int level);
+};
+
static struct kmem_cache *pte_chain_cache;
static struct kmem_cache *rmap_desc_cache;
static struct kmem_cache *mmu_page_header_cache;
@@ -935,6 +940,35 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
return sp;
}
+static int walk_shadow(struct kvm_shadow_walk *walker,
+ struct kvm_vcpu *vcpu, gva_t addr)
+{
+ hpa_t shadow_addr;
+ int level;
+ int r;
+ u64 *sptep;
+ unsigned index;
+
+ shadow_addr = vcpu->arch.mmu.root_hpa;
+ level = vcpu->arch.mmu.shadow_root_level;
+ if (level == PT32E_ROOT_LEVEL) {
+ shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
+ shadow_addr &= PT64_BASE_ADDR_MASK;
+ --level;
+ }
+
+ while (level >= PT_PAGE_TABLE_LEVEL) {
+ index = SHADOW_PT_INDEX(addr, level);
+ sptep = ((u64 *)__va(shadow_addr)) + index;
+ r = walker->entry(walker, vcpu, addr, sptep, level);
+ if (r)
+ return r;
+ shadow_addr = *sptep & PT64_BASE_ADDR_MASK;
+ --level;
+ }
+ return 0;
+}
+
static void kvm_mmu_page_unlink_children(struct kvm *kvm,
struct kvm_mmu_page *sp)
{
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 27/39] KVM: MMU: Convert direct maps to use the generic shadow walker
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (25 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 26/39] KVM: MMU: Add generic shadow walker Avi Kivity
@ 2008-09-25 11:54 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 28/39] KVM: MMU: Convert the paging mode shadow walk to use the generic walker Avi Kivity
` (11 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:54 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 93 ++++++++++++++++++++++++++++++---------------------
1 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 8b95cf7..a1ca4ff 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1260,49 +1260,66 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
{
}
-static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int largepage, gfn_t gfn, pfn_t pfn)
-{
- hpa_t table_addr = vcpu->arch.mmu.root_hpa;
- int pt_write = 0;
- int level = vcpu->arch.mmu.shadow_root_level;
-
- for (; ; level--) {
- u32 index = PT64_INDEX(v, level);
- u64 *table;
+struct direct_shadow_walk {
+ struct kvm_shadow_walk walker;
+ pfn_t pfn;
+ int write;
+ int largepage;
+ int pt_write;
+};
- ASSERT(VALID_PAGE(table_addr));
- table = __va(table_addr);
+static int direct_map_entry(struct kvm_shadow_walk *_walk,
+ struct kvm_vcpu *vcpu,
+ gva_t addr, u64 *sptep, int level)
+{
+ struct direct_shadow_walk *walk =
+ container_of(_walk, struct direct_shadow_walk, walker);
+ struct kvm_mmu_page *sp;
+ gfn_t pseudo_gfn;
+ gfn_t gfn = addr >> PAGE_SHIFT;
+
+ if (level == PT_PAGE_TABLE_LEVEL
+ || (walk->largepage && level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
+ 0, walk->write, 1, &walk->pt_write,
+ walk->largepage, gfn, walk->pfn, false);
+ return 1;
+ }
- if (level == 1 || (largepage && level == 2)) {
- mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
- 0, write, 1, &pt_write, largepage,
- gfn, pfn, false);
- return pt_write;
+ if (*sptep == shadow_trap_nonpresent_pte) {
+ pseudo_gfn = (addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
+ sp = kvm_mmu_get_page(vcpu, pseudo_gfn, addr, level - 1,
+ 1, ACC_ALL, sptep);
+ if (!sp) {
+ pgprintk("nonpaging_map: ENOMEM\n");
+ kvm_release_pfn_clean(walk->pfn);
+ return -ENOMEM;
}
- if (table[index] == shadow_trap_nonpresent_pte) {
- struct kvm_mmu_page *new_table;
- gfn_t pseudo_gfn;
-
- pseudo_gfn = (v & PT64_DIR_BASE_ADDR_MASK)
- >> PAGE_SHIFT;
- new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
- v, level - 1,
- 1, ACC_ALL, &table[index]);
- if (!new_table) {
- pgprintk("nonpaging_map: ENOMEM\n");
- kvm_release_pfn_clean(pfn);
- return -ENOMEM;
- }
-
- set_shadow_pte(&table[index],
- __pa(new_table->spt)
- | PT_PRESENT_MASK | PT_WRITABLE_MASK
- | shadow_user_mask | shadow_x_mask);
- }
- table_addr = table[index] & PT64_BASE_ADDR_MASK;
+ set_shadow_pte(sptep,
+ __pa(sp->spt)
+ | PT_PRESENT_MASK | PT_WRITABLE_MASK
+ | shadow_user_mask | shadow_x_mask);
}
+ return 0;
+}
+
+static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
+ int largepage, gfn_t gfn, pfn_t pfn)
+{
+ int r;
+ struct direct_shadow_walk walker = {
+ .walker = { .entry = direct_map_entry, },
+ .pfn = pfn,
+ .largepage = largepage,
+ .write = write,
+ .pt_write = 0,
+ };
+
+ r = walk_shadow(&walker.walker, vcpu, (gva_t)gfn << PAGE_SHIFT);
+ if (r < 0)
+ return r;
+ return walker.pt_write;
}
static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 28/39] KVM: MMU: Convert the paging mode shadow walk to use the generic walker
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (26 preceding siblings ...)
2008-09-25 11:54 ` [PATCH 27/39] KVM: MMU: Convert direct maps to use the " Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 29/39] KVM: Allocate guest memory as MAP_PRIVATE, not MAP_SHARED Avi Kivity
` (10 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/paging_tmpl.h | 158 ++++++++++++++++++++++++--------------------
1 files changed, 86 insertions(+), 72 deletions(-)
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index ebb26a0..b7064e1 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -25,6 +25,7 @@
#if PTTYPE == 64
#define pt_element_t u64
#define guest_walker guest_walker64
+ #define shadow_walker shadow_walker64
#define FNAME(name) paging##64_##name
#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
@@ -41,6 +42,7 @@
#elif PTTYPE == 32
#define pt_element_t u32
#define guest_walker guest_walker32
+ #define shadow_walker shadow_walker32
#define FNAME(name) paging##32_##name
#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
@@ -71,6 +73,17 @@ struct guest_walker {
u32 error_code;
};
+struct shadow_walker {
+ struct kvm_shadow_walk walker;
+ struct guest_walker *guest_walker;
+ int user_fault;
+ int write_fault;
+ int largepage;
+ int *ptwrite;
+ pfn_t pfn;
+ u64 *sptep;
+};
+
static gfn_t gpte_to_gfn(pt_element_t gpte)
{
return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -272,86 +285,86 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
/*
* Fetch a shadow pte for a specific level in the paging hierarchy.
*/
-static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
- struct guest_walker *walker,
- int user_fault, int write_fault, int largepage,
- int *ptwrite, pfn_t pfn)
+static int FNAME(shadow_walk_entry)(struct kvm_shadow_walk *_sw,
+ struct kvm_vcpu *vcpu, gva_t addr,
+ u64 *sptep, int level)
{
- hpa_t shadow_addr;
- int level;
- u64 *shadow_ent;
- unsigned access = walker->pt_access;
-
- if (!is_present_pte(walker->ptes[walker->level - 1]))
- return NULL;
-
- shadow_addr = vcpu->arch.mmu.root_hpa;
- level = vcpu->arch.mmu.shadow_root_level;
- if (level == PT32E_ROOT_LEVEL) {
- shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
- shadow_addr &= PT64_BASE_ADDR_MASK;
- --level;
+ struct shadow_walker *sw =
+ container_of(_sw, struct shadow_walker, walker);
+ struct guest_walker *gw = sw->guest_walker;
+ unsigned access = gw->pt_access;
+ struct kvm_mmu_page *shadow_page;
+ u64 spte;
+ int metaphysical;
+ gfn_t table_gfn;
+ int r;
+ pt_element_t curr_pte;
+
+ if (level == PT_PAGE_TABLE_LEVEL
+ || (sw->largepage && level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
+ sw->user_fault, sw->write_fault,
+ gw->ptes[gw->level-1] & PT_DIRTY_MASK,
+ sw->ptwrite, sw->largepage, gw->gfn, sw->pfn,
+ false);
+ sw->sptep = sptep;
+ return 1;
}
- for (; ; level--) {
- u32 index = SHADOW_PT_INDEX(addr, level);
- struct kvm_mmu_page *shadow_page;
- u64 shadow_pte;
- int metaphysical;
- gfn_t table_gfn;
-
- shadow_ent = ((u64 *)__va(shadow_addr)) + index;
- if (level == PT_PAGE_TABLE_LEVEL)
- break;
-
- if (largepage && level == PT_DIRECTORY_LEVEL)
- break;
-
- if (is_shadow_present_pte(*shadow_ent)
- && !is_large_pte(*shadow_ent)) {
- shadow_addr = *shadow_ent & PT64_BASE_ADDR_MASK;
- continue;
- }
+ if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
+ return 0;
- if (is_large_pte(*shadow_ent))
- rmap_remove(vcpu->kvm, shadow_ent);
-
- if (level - 1 == PT_PAGE_TABLE_LEVEL
- && walker->level == PT_DIRECTORY_LEVEL) {
- metaphysical = 1;
- if (!is_dirty_pte(walker->ptes[level - 1]))
- access &= ~ACC_WRITE_MASK;
- table_gfn = gpte_to_gfn(walker->ptes[level - 1]);
- } else {
- metaphysical = 0;
- table_gfn = walker->table_gfn[level - 2];
- }
- shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
- metaphysical, access,
- shadow_ent);
- if (!metaphysical) {
- int r;
- pt_element_t curr_pte;
- r = kvm_read_guest_atomic(vcpu->kvm,
- walker->pte_gpa[level - 2],
- &curr_pte, sizeof(curr_pte));
- if (r || curr_pte != walker->ptes[level - 2]) {
- kvm_release_pfn_clean(pfn);
- return NULL;
- }
+ if (is_large_pte(*sptep))
+ rmap_remove(vcpu->kvm, sptep);
+
+ if (level == PT_DIRECTORY_LEVEL && gw->level == PT_DIRECTORY_LEVEL) {
+ metaphysical = 1;
+ if (!is_dirty_pte(gw->ptes[level - 1]))
+ access &= ~ACC_WRITE_MASK;
+ table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
+ } else {
+ metaphysical = 0;
+ table_gfn = gw->table_gfn[level - 2];
+ }
+ shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
+ metaphysical, access, sptep);
+ if (!metaphysical) {
+ r = kvm_read_guest_atomic(vcpu->kvm, gw->pte_gpa[level - 2],
+ &curr_pte, sizeof(curr_pte));
+ if (r || curr_pte != gw->ptes[level - 2]) {
+ kvm_release_pfn_clean(sw->pfn);
+ sw->sptep = NULL;
+ return 1;
}
- shadow_addr = __pa(shadow_page->spt);
- shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK
- | PT_WRITABLE_MASK | PT_USER_MASK;
- set_shadow_pte(shadow_ent, shadow_pte);
}
- mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access,
- user_fault, write_fault,
- walker->ptes[walker->level-1] & PT_DIRTY_MASK,
- ptwrite, largepage, walker->gfn, pfn, false);
+ spte = __pa(shadow_page->spt) | PT_PRESENT_MASK | PT_ACCESSED_MASK
+ | PT_WRITABLE_MASK | PT_USER_MASK;
+ *sptep = spte;
+ return 0;
+}
+
+static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
+ struct guest_walker *guest_walker,
+ int user_fault, int write_fault, int largepage,
+ int *ptwrite, pfn_t pfn)
+{
+ struct shadow_walker walker = {
+ .walker = { .entry = FNAME(shadow_walk_entry), },
+ .guest_walker = guest_walker,
+ .user_fault = user_fault,
+ .write_fault = write_fault,
+ .largepage = largepage,
+ .ptwrite = ptwrite,
+ .pfn = pfn,
+ };
+
+ if (!is_present_pte(guest_walker->ptes[guest_walker->level - 1]))
+ return NULL;
+
+ walk_shadow(&walker.walker, vcpu, addr);
- return shadow_ent;
+ return walker.sptep;
}
/*
@@ -499,6 +512,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
#undef pt_element_t
#undef guest_walker
+#undef shadow_walker
#undef FNAME
#undef PT_BASE_ADDR_MASK
#undef PT_INDEX
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 29/39] KVM: Allocate guest memory as MAP_PRIVATE, not MAP_SHARED
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (27 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 28/39] KVM: MMU: Convert the paging mode shadow walk to use the generic walker Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 30/39] KVM: Don't call get_user_pages(.force = 1) Avi Kivity
` (9 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
There is no reason to share internal memory slots with fork()ed instances.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bfc7c33..675d010 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4296,7 +4296,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
userspace_addr = do_mmap(NULL, 0,
npages * PAGE_SIZE,
PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS,
+ MAP_PRIVATE | MAP_ANONYMOUS,
0);
up_write(¤t->mm->mmap_sem);
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 30/39] KVM: Don't call get_user_pages(.force = 1)
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (28 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 29/39] KVM: Allocate guest memory as MAP_PRIVATE, not MAP_SHARED Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 31/39] KVM: x86 emulator: Add mov r, imm instructions (opcodes 0xb0-0xbf) Avi Kivity
` (8 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
This is esoteric and only needed to break COW on MAP_SHARED mappings. Since
KVM no longer does these sorts of mappings, breaking COW on them is no longer
necessary.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
virt/kvm/kvm_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 0309571..de3b029 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -734,7 +734,7 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
return page_to_pfn(bad_page);
}
- npages = get_user_pages(current, current->mm, addr, 1, 1, 1, page,
+ npages = get_user_pages(current, current->mm, addr, 1, 1, 0, page,
NULL);
if (unlikely(npages != 1)) {
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 31/39] KVM: x86 emulator: Add mov r, imm instructions (opcodes 0xb0-0xbf)
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (29 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 30/39] KVM: Don't call get_user_pages(.force = 1) Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 32/39] KVM: MMU: Account for npt/ept/realmode page faults Avi Kivity
` (7 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Mohammed Gamal
From: Mohammed Gamal <m.gamal005@gmail.com>
The emulator only supported one instance of mov r, imm instruction
(opcode 0xb8), this adds the rest of these instructions.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86_emulate.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index ae30435..66e0bd6 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -154,9 +154,16 @@ static u16 opcode_table[256] = {
0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
ByteOp | ImplicitOps | String, ImplicitOps | String,
- /* 0xB0 - 0xBF */
- 0, 0, 0, 0, 0, 0, 0, 0,
- DstReg | SrcImm | Mov, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xB0 - 0xB7 */
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ /* 0xB8 - 0xBF */
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
/* 0xC0 - 0xC7 */
ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
0, ImplicitOps | Stack, 0, 0,
@@ -1660,7 +1667,7 @@ special_insn:
case 0xae ... 0xaf: /* scas */
DPRINTF("Urk! I don't handle SCAS.\n");
goto cannot_emulate;
- case 0xb8: /* mov r, imm */
+ case 0xb0 ... 0xbf: /* mov r, imm */
goto mov;
case 0xc0 ... 0xc1:
emulate_grp2(ctxt);
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 32/39] KVM: MMU: Account for npt/ept/realmode page faults
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (30 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 31/39] KVM: x86 emulator: Add mov r, imm instructions (opcodes 0xb0-0xbf) Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 33/39] KVM: MMU: Add locking around kvm_mmu_slot_remove_write_access() Avi Kivity
` (6 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Now that two-dimensional paging is becoming common, account for tdp page
faults.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index a1ca4ff..a24da8f 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1283,6 +1283,7 @@ static int direct_map_entry(struct kvm_shadow_walk *_walk,
mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
0, walk->write, 1, &walk->pt_write,
walk->largepage, gfn, walk->pfn, false);
+ ++vcpu->stat.pf_fixed;
return 1;
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 33/39] KVM: MMU: Add locking around kvm_mmu_slot_remove_write_access()
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (31 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 32/39] KVM: MMU: Account for npt/ept/realmode page faults Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 34/39] KVM: MMU: Flush tlbs after clearing write permission when accessing dirty log Avi Kivity
` (5 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
It was generally safe due to slots_lock being held for write, but it wasn't
very nice.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index a24da8f..5052acd 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2097,6 +2097,7 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
{
struct kvm_mmu_page *sp;
+ spin_lock(&kvm->mmu_lock);
list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link) {
int i;
u64 *pt;
@@ -2110,6 +2111,7 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
if (pt[i] & PT_WRITABLE_MASK)
pt[i] &= ~PT_WRITABLE_MASK;
}
+ spin_unlock(&kvm->mmu_lock);
}
void kvm_mmu_zap_all(struct kvm *kvm)
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 34/39] KVM: MMU: Flush tlbs after clearing write permission when accessing dirty log
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (32 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 33/39] KVM: MMU: Add locking around kvm_mmu_slot_remove_write_access() Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 35/39] KVM: MMU: Fix setting the accessed bit on non-speculative sptes Avi Kivity
` (4 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
Otherwise, the cpu may allow writes to the tracked pages, and we lose
some display bits or fail to migrate correctly.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/mmu.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 5052acd..853a288 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2111,6 +2111,7 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
if (pt[i] & PT_WRITABLE_MASK)
pt[i] &= ~PT_WRITABLE_MASK;
}
+ kvm_flush_remote_tlbs(kvm);
spin_unlock(&kvm->mmu_lock);
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 35/39] KVM: MMU: Fix setting the accessed bit on non-speculative sptes
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (33 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 34/39] KVM: MMU: Flush tlbs after clearing write permission when accessing dirty log Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 36/39] KVM: SVM: No need to unprotect memory during event injection when using npt Avi Kivity
` (3 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
The accessed bit was accidentally turned on in a random flag word, rather
than, the spte itself, which was lucky, since it used the non-EPT compatible
PT_ACCESSED_MASK.
Fix by turning the bit on in the spte and changing it to use the portable
accessed mask.
Signed-off-by: Avi Kivity <avi@qumranet.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 853a288..866d713 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -1192,7 +1192,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
*/
spte = shadow_base_present_pte | shadow_dirty_mask;
if (!speculative)
- pte_access |= PT_ACCESSED_MASK;
+ spte |= shadow_accessed_mask;
if (!dirty)
pte_access &= ~ACC_WRITE_MASK;
if (pte_access & ACC_EXEC_MASK)
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 36/39] KVM: SVM: No need to unprotect memory during event injection when using npt
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (34 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 35/39] KVM: MMU: Fix setting the accessed bit on non-speculative sptes Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 37/39] KVM: add MC5_MISC msr read support Avi Kivity
` (2 subsequent siblings)
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Avi Kivity
From: Avi Kivity <avi@qumranet.com>
No memory is protected anyway.
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/svm.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index be86c09..6022888 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1021,7 +1021,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
if (npt_enabled)
svm_flush_tlb(&svm->vcpu);
- if (event_injection)
+ if (!npt_enabled && event_injection)
kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
}
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 37/39] KVM: add MC5_MISC msr read support
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (35 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 36/39] KVM: SVM: No need to unprotect memory during event injection when using npt Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 38/39] KVM: s390: Make facility bits future-proof Avi Kivity
2008-09-25 11:55 ` [PATCH 39/39] KVM: s390: change help text of guest Kconfig Avi Kivity
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Joerg Roedel
From: Joerg Roedel <joerg.roedel@amd.com>
Currently KVM implements MC0-MC4_MISC read support. When booting Linux this
results in KVM warnings in the kernel log when the guest tries to read
MC5_MISC. Fix this warnings with this patch.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/x86/kvm/x86.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 675d010..e3b8966 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -991,6 +991,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MC0_MISC+8:
case MSR_IA32_MC0_MISC+12:
case MSR_IA32_MC0_MISC+16:
+ case MSR_IA32_MC0_MISC+20:
case MSR_IA32_UCODE_REV:
case MSR_IA32_EBL_CR_POWERON:
case MSR_IA32_DEBUGCTLMSR:
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 38/39] KVM: s390: Make facility bits future-proof
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (36 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 37/39] KVM: add MC5_MISC msr read support Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
2008-09-25 11:55 ` [PATCH 39/39] KVM: s390: change help text of guest Kconfig Avi Kivity
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Christian Borntraeger
From: Christian Borntraeger <borntraeger@de.ibm.com>
Heiko Carstens pointed out, that its safer to activate working facilities
instead of disabling problematic facilities. The new code uses the host
facility bits and masks it with known good ones.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/s390/kvm/priv.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index d1faf5c..cce40ff 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -157,8 +157,8 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
int rc;
vcpu->stat.instruction_stfl++;
- facility_list &= ~(1UL<<24); /* no stfle */
- facility_list &= ~(1UL<<23); /* no large pages */
+ /* only pass the facility bits, which we can handle */
+ facility_list &= 0xfe00fff3;
rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
&facility_list, sizeof(facility_list));
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread* [PATCH 39/39] KVM: s390: change help text of guest Kconfig
2008-09-25 11:54 [PATCH 00/39] KVM Updates for 2.6.28 merge window (part 2 of 3) Avi Kivity
` (37 preceding siblings ...)
2008-09-25 11:55 ` [PATCH 38/39] KVM: s390: Make facility bits future-proof Avi Kivity
@ 2008-09-25 11:55 ` Avi Kivity
38 siblings, 0 replies; 40+ messages in thread
From: Avi Kivity @ 2008-09-25 11:55 UTC (permalink / raw)
To: linux-kernel; +Cc: kvm, Christian Borntraeger
From: Christian Borntraeger <borntraeger@de.ibm.com>
The current help text for CONFIG_S390_GUEST is not very helpful.
Lets add more text.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
arch/s390/Kconfig | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 8d41908..c9bfed9 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -564,13 +564,16 @@ config ZFCPDUMP
Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
config S390_GUEST
-bool "s390 guest support (EXPERIMENTAL)"
+bool "s390 guest support for KVM (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
select VIRTIO_CONSOLE
help
- Select this option if you want to run the kernel under s390 linux
+ Select this option if you want to run the kernel as a guest under
+ the KVM hypervisor. This will add detection for KVM as well as a
+ virtio transport. If KVM is detected, the virtio console will be
+ the default console.
endmenu
source "net/Kconfig"
--
1.6.0.1
^ permalink raw reply related [flat|nested] 40+ messages in thread