* 'kvm-updates-2.6.27' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm:
KVM: ppc: fix invalidation of large guest pages
KVM: s390: Fix possible host kernel bug on lctl(g) handling
KVM: s390: Fix instruction naming for lctlg
KVM: s390: Fix program check on interrupt delivery handling
KVM: s390: Change guestaddr type in gaccess
KVM: s390: Fix guest kconfig
KVM: s390: Advertise KVM_CAP_USER_MEMORY
KVM: ia64: Fix irq disabling leak in error handling code
KVM: VMX: Fix undefined beaviour of EPT after reload kvm-intel.ko
KVM: VMX: Fix bypass_guest_pf enabling when disable EPT in module parameter
KVM: task switch: translate guest segment limit to virt-extension byte granular field
KVM: Avoid instruction emulation when event delivery is pending
KVM: task switch: use seg regs provided by subarch instead of reading from GDT
KVM: task switch: segment base is linear address
KVM: SVM: allow enabling/disabling NPT by reloading only the architecture module
PAGE_KERNEL));
local_irq_save(saved_psr);
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+ local_irq_restore(saved_psr);
if (slot < 0)
return;
- local_irq_restore(saved_psr);
spin_lock(&vp_lock);
status = ia64_pal_vp_init_env(kvm_vsa_base ?
local_irq_save(saved_psr);
slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+ local_irq_restore(saved_psr);
if (slot < 0)
return;
- local_irq_restore(saved_psr);
status = ia64_pal_vp_exit_env(host_iva);
if (status)
uninit:
kvm_vcpu_uninit(vcpu);
fail:
+ local_irq_restore(psr);
return r;
}
vcpu->arch.msr & MSR_PR);
}
-void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
+void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
+ gva_t eend, u32 asid)
{
unsigned int pid = asid & 0xff;
int i;
if (!get_tlb_v(stlbe))
continue;
- if (eaddr < get_tlb_eaddr(stlbe))
+ if (eend < get_tlb_eaddr(stlbe))
continue;
if (eaddr > get_tlb_end(stlbe))
if (tlbe->word0 & PPC44x_TLB_VALID) {
eaddr = get_tlb_eaddr(tlbe);
asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
- kvmppc_mmu_invalidate(vcpu, eaddr, asid);
+ kvmppc_mmu_invalidate(vcpu, eaddr, get_tlb_end(tlbe), asid);
}
switch (ws) {
#include <asm/uaccess.h>
static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
- u64 guestaddr)
+ unsigned long guestaddr)
{
- u64 prefix = vcpu->arch.sie_block->prefix;
- u64 origin = vcpu->kvm->arch.guest_origin;
- u64 memsize = vcpu->kvm->arch.guest_memsize;
+ unsigned long prefix = vcpu->arch.sie_block->prefix;
+ unsigned long origin = vcpu->kvm->arch.guest_origin;
+ unsigned long memsize = vcpu->kvm->arch.guest_memsize;
if (guestaddr < 2 * PAGE_SIZE)
guestaddr += prefix;
return (void __user *) guestaddr;
}
-static inline int get_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int get_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u64 *result)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
if (IS_ERR((void __force *) uptr))
return PTR_ERR((void __force *) uptr);
- return get_user(*result, (u64 __user *) uptr);
+ return get_user(*result, (unsigned long __user *) uptr);
}
-static inline int get_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int get_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u32 *result)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return get_user(*result, (u32 __user *) uptr);
}
-static inline int get_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int get_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u16 *result)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return get_user(*result, (u16 __user *) uptr);
}
-static inline int get_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int get_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u8 *result)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return get_user(*result, (u8 __user *) uptr);
}
-static inline int put_guest_u64(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int put_guest_u64(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u64 value)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return put_user(value, (u64 __user *) uptr);
}
-static inline int put_guest_u32(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int put_guest_u32(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u32 value)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return put_user(value, (u32 __user *) uptr);
}
-static inline int put_guest_u16(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int put_guest_u16(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u16 value)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
return put_user(value, (u16 __user *) uptr);
}
-static inline int put_guest_u8(struct kvm_vcpu *vcpu, u64 guestaddr,
+static inline int put_guest_u8(struct kvm_vcpu *vcpu, unsigned long guestaddr,
u8 value)
{
void __user *uptr = __guestaddr_to_user(vcpu, guestaddr);
}
-static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu, u64 guestdest,
+static inline int __copy_to_guest_slow(struct kvm_vcpu *vcpu,
+ unsigned long guestdest,
const void *from, unsigned long n)
{
int rc;
return 0;
}
-static inline int copy_to_guest(struct kvm_vcpu *vcpu, u64 guestdest,
+static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest,
const void *from, unsigned long n)
{
- u64 prefix = vcpu->arch.sie_block->prefix;
- u64 origin = vcpu->kvm->arch.guest_origin;
- u64 memsize = vcpu->kvm->arch.guest_memsize;
+ unsigned long prefix = vcpu->arch.sie_block->prefix;
+ unsigned long origin = vcpu->kvm->arch.guest_origin;
+ unsigned long memsize = vcpu->kvm->arch.guest_memsize;
if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE))
goto slowpath;
}
static inline int __copy_from_guest_slow(struct kvm_vcpu *vcpu, void *to,
- u64 guestsrc, unsigned long n)
+ unsigned long guestsrc,
+ unsigned long n)
{
int rc;
unsigned long i;
}
static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to,
- u64 guestsrc, unsigned long n)
+ unsigned long guestsrc, unsigned long n)
{
- u64 prefix = vcpu->arch.sie_block->prefix;
- u64 origin = vcpu->kvm->arch.guest_origin;
- u64 memsize = vcpu->kvm->arch.guest_memsize;
+ unsigned long prefix = vcpu->arch.sie_block->prefix;
+ unsigned long origin = vcpu->kvm->arch.guest_origin;
+ unsigned long memsize = vcpu->kvm->arch.guest_memsize;
if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE))
goto slowpath;
return __copy_from_guest_slow(vcpu, to, guestsrc, n);
}
-static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, u64 guestdest,
+static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu,
+ unsigned long guestdest,
const void *from, unsigned long n)
{
- u64 origin = vcpu->kvm->arch.guest_origin;
- u64 memsize = vcpu->kvm->arch.guest_memsize;
+ unsigned long origin = vcpu->kvm->arch.guest_origin;
+ unsigned long memsize = vcpu->kvm->arch.guest_memsize;
if (guestdest + n > memsize)
return -EFAULT;
}
static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to,
- u64 guestsrc, unsigned long n)
+ unsigned long guestsrc,
+ unsigned long n)
{
- u64 origin = vcpu->kvm->arch.guest_origin;
- u64 memsize = vcpu->kvm->arch.guest_memsize;
+ unsigned long origin = vcpu->kvm->arch.guest_origin;
+ unsigned long memsize = vcpu->kvm->arch.guest_memsize;
if (guestsrc + n > memsize)
return -EFAULT;
#include "kvm-s390.h"
#include "gaccess.h"
-static int handle_lctg(struct kvm_vcpu *vcpu)
+static int handle_lctlg(struct kvm_vcpu *vcpu)
{
int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
u64 useraddr;
int reg, rc;
- vcpu->stat.instruction_lctg++;
+ vcpu->stat.instruction_lctlg++;
if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f)
return -ENOTSUPP;
if (base2)
useraddr += vcpu->arch.guest_gprs[base2];
+ if (useraddr & 7)
+ return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
reg = reg1;
- VCPU_EVENT(vcpu, 5, "lctg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
+ VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
disp2);
do {
if (base2)
useraddr += vcpu->arch.guest_gprs[base2];
+ if (useraddr & 3)
+ return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
disp2);
[0xae] = kvm_s390_handle_sigp,
[0xb2] = kvm_s390_handle_priv,
[0xb7] = handle_lctl,
- [0xeb] = handle_lctg,
+ [0xeb] = handle_lctlg,
};
static int handle_noop(struct kvm_vcpu *vcpu)
#include <asm/lowcore.h>
#include <asm/uaccess.h>
#include <linux/kvm_host.h>
+#include <linux/signal.h>
#include "kvm-s390.h"
#include "gaccess.h"
default:
BUG();
}
-
if (exception) {
- VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering"
- " interrupt");
- kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- if (inti->type == KVM_S390_PROGRAM_INT) {
- printk(KERN_WARNING "kvm: recursive program check\n");
- BUG();
- }
+ printk("kvm: The guest lowcore is not mapped during interrupt "
+ "delivery, killing userspace\n");
+ do_exit(SIGKILL);
}
}
__LC_EXT_NEW_PSW, sizeof(psw_t));
if (rc == -EFAULT)
exception = 1;
-
if (exception) {
- VCPU_EVENT(vcpu, 1, "%s", "program exception while delivering" \
- " ckc interrupt");
- kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
- return 0;
+ printk("kvm: The guest lowcore is not mapped during interrupt "
+ "delivery, killing userspace\n");
+ do_exit(SIGKILL);
}
-
return 1;
}
{ "exit_instruction", VCPU_STAT(exit_instruction) },
{ "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
{ "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
- { "instruction_lctg", VCPU_STAT(instruction_lctg) },
+ { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
{ "instruction_lctl", VCPU_STAT(instruction_lctl) },
{ "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
{ "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
int kvm_dev_ioctl_check_extension(long ext)
{
- return 0;
+ switch (ext) {
+ case KVM_CAP_USER_MEMORY:
+ return 1;
+ default:
+ return 0;
+ }
}
/* Section: vm related */
#define SIGP_STAT_RECEIVER_CHECK 0x00000001UL
-static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, u64 *reg)
+static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
+ unsigned long *reg)
{
struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
int rc;
}
static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
- u64 *reg)
+ unsigned long *reg)
{
struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
struct kvm_s390_local_interrupt *li;
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
}
+EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
{
}
EXPORT_SYMBOL_GPL(kvm_enable_tdp);
+void kvm_disable_tdp(void)
+{
+ tdp_enabled = false;
+}
+EXPORT_SYMBOL_GPL(kvm_disable_tdp);
+
static void free_mmu_pages(struct kvm_vcpu *vcpu)
{
struct kvm_mmu_page *sp;
if (npt_enabled) {
printk(KERN_INFO "kvm: Nested Paging enabled\n");
kvm_enable_tdp();
- }
+ } else
+ kvm_disable_tdp();
return 0;
struct kvm *kvm = svm->vcpu.kvm;
u64 fault_address;
u32 error_code;
+ bool event_injection = false;
if (!irqchip_in_kernel(kvm) &&
- is_external_interrupt(exit_int_info))
+ is_external_interrupt(exit_int_info)) {
+ event_injection = true;
push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
+ }
fault_address = svm->vmcb->control.exit_info_2;
error_code = svm->vmcb->control.exit_info_1;
(u32)fault_address, (u32)(fault_address >> 32),
handler);
+ if (event_injection)
+ kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
}
cr2 = vmcs_readl(EXIT_QUALIFICATION);
KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
(u32)((u64)cr2 >> 32), handler);
+ if (vect_info & VECTORING_INFO_VALID_MASK)
+ kvm_mmu_unprotect_page_virt(vcpu, cr2);
return kvm_mmu_page_fault(vcpu, cr2, error_code);
}
return ERR_PTR(-ENOMEM);
allocate_vpid(vmx);
- if (id == 0 && vm_need_ept()) {
- kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
- VMX_EPT_WRITABLE_MASK |
- VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
- kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK,
- VMX_EPT_FAKE_DIRTY_MASK, 0ull,
- VMX_EPT_EXECUTABLE_MASK);
- kvm_enable_tdp();
- }
err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
if (err)
vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP);
vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP);
- if (cpu_has_vmx_ept())
+ if (vm_need_ept()) {
bypass_guest_pf = 0;
+ kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
+ VMX_EPT_WRITABLE_MASK |
+ VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
+ kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK,
+ VMX_EPT_FAKE_DIRTY_MASK, 0ull,
+ VMX_EPT_EXECUTABLE_MASK);
+ kvm_enable_tdp();
+ } else
+ kvm_disable_tdp();
if (bypass_guest_pf)
kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull);
kvm_desct->base |= seg_desc->base2 << 24;
kvm_desct->limit = seg_desc->limit0;
kvm_desct->limit |= seg_desc->limit << 16;
+ if (seg_desc->g) {
+ kvm_desct->limit <<= 12;
+ kvm_desct->limit |= 0xfff;
+ }
kvm_desct->selector = selector;
kvm_desct->type = seg_desc->type;
kvm_desct->present = seg_desc->p;
static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
struct desc_struct *seg_desc)
{
+ gpa_t gpa;
struct descriptor_table dtable;
u16 index = selector >> 3;
kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
return 1;
}
- return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
+ gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
+ gpa += index * 8;
+ return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
}
/* allowed just for 8 bytes segments */
static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
struct desc_struct *seg_desc)
{
+ gpa_t gpa;
struct descriptor_table dtable;
u16 index = selector >> 3;
if (dtable.limit < index * 8 + 7)
return 1;
- return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
+ gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
+ gpa += index * 8;
+ return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
}
static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
base_addr |= (seg_desc->base1 << 16);
base_addr |= (seg_desc->base2 << 24);
- return base_addr;
-}
-
-static int load_tss_segment32(struct kvm_vcpu *vcpu,
- struct desc_struct *seg_desc,
- struct tss_segment_32 *tss)
-{
- u32 base_addr;
-
- base_addr = get_tss_base_addr(vcpu, seg_desc);
-
- return kvm_read_guest(vcpu->kvm, base_addr, tss,
- sizeof(struct tss_segment_32));
-}
-
-static int save_tss_segment32(struct kvm_vcpu *vcpu,
- struct desc_struct *seg_desc,
- struct tss_segment_32 *tss)
-{
- u32 base_addr;
-
- base_addr = get_tss_base_addr(vcpu, seg_desc);
-
- return kvm_write_guest(vcpu->kvm, base_addr, tss,
- sizeof(struct tss_segment_32));
-}
-
-static int load_tss_segment16(struct kvm_vcpu *vcpu,
- struct desc_struct *seg_desc,
- struct tss_segment_16 *tss)
-{
- u32 base_addr;
-
- base_addr = get_tss_base_addr(vcpu, seg_desc);
-
- return kvm_read_guest(vcpu->kvm, base_addr, tss,
- sizeof(struct tss_segment_16));
-}
-
-static int save_tss_segment16(struct kvm_vcpu *vcpu,
- struct desc_struct *seg_desc,
- struct tss_segment_16 *tss)
-{
- u32 base_addr;
-
- base_addr = get_tss_base_addr(vcpu, seg_desc);
-
- return kvm_write_guest(vcpu->kvm, base_addr, tss,
- sizeof(struct tss_segment_16));
+ return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
}
static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
}
static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
- struct desc_struct *cseg_desc,
+ u32 old_tss_base,
struct desc_struct *nseg_desc)
{
struct tss_segment_16 tss_segment_16;
int ret = 0;
- if (load_tss_segment16(vcpu, cseg_desc, &tss_segment_16))
+ if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
+ sizeof tss_segment_16))
goto out;
save_state_to_tss16(vcpu, &tss_segment_16);
- save_tss_segment16(vcpu, cseg_desc, &tss_segment_16);
- if (load_tss_segment16(vcpu, nseg_desc, &tss_segment_16))
+ if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
+ sizeof tss_segment_16))
goto out;
+
+ if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+ &tss_segment_16, sizeof tss_segment_16))
+ goto out;
+
if (load_state_from_tss16(vcpu, &tss_segment_16))
goto out;
}
static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
- struct desc_struct *cseg_desc,
+ u32 old_tss_base,
struct desc_struct *nseg_desc)
{
struct tss_segment_32 tss_segment_32;
int ret = 0;
- if (load_tss_segment32(vcpu, cseg_desc, &tss_segment_32))
+ if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
+ sizeof tss_segment_32))
goto out;
save_state_to_tss32(vcpu, &tss_segment_32);
- save_tss_segment32(vcpu, cseg_desc, &tss_segment_32);
- if (load_tss_segment32(vcpu, nseg_desc, &tss_segment_32))
+ if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
+ sizeof tss_segment_32))
+ goto out;
+
+ if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+ &tss_segment_32, sizeof tss_segment_32))
goto out;
+
if (load_state_from_tss32(vcpu, &tss_segment_32))
goto out;
struct desc_struct cseg_desc;
struct desc_struct nseg_desc;
int ret = 0;
+ u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
+ u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
- kvm_get_segment(vcpu, &tr_seg, VCPU_SREG_TR);
+ old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base);
+ /* FIXME: Handle errors. Failure to read either TSS or their
+ * descriptors should generate a pagefault.
+ */
if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc))
goto out;
- if (load_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc))
+ if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc))
goto out;
-
if (reason != TASK_SWITCH_IRET) {
int cpl;
if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) {
cseg_desc.type &= ~(1 << 1); //clear the B flag
- save_guest_segment_descriptor(vcpu, tr_seg.selector,
- &cseg_desc);
+ save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc);
}
if (reason == TASK_SWITCH_IRET) {
kvm_x86_ops->cache_regs(vcpu);
if (nseg_desc.type & 8)
- ret = kvm_task_switch_32(vcpu, tss_selector, &cseg_desc,
+ ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base,
&nseg_desc);
else
- ret = kvm_task_switch_16(vcpu, tss_selector, &cseg_desc,
+ ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base,
&nseg_desc);
if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) {
# it under the terms of the GNU General Public License (version 2 only)
# as published by the Free Software Foundation.
-obj-$(CONFIG_VIRTIO) += kvm_virtio.o
+obj-$(CONFIG_S390_GUEST) += kvm_virtio.o
extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
u64 asid, u32 flags);
-extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid);
+extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
+ gva_t eend, u32 asid);
extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu);
u32 exit_validity;
u32 exit_instruction;
u32 instruction_lctl;
- u32 instruction_lctg;
+ u32 instruction_lctlg;
u32 exit_program_interruption;
u32 exit_instr_and_program;
u32 deliver_emergency_signal;
struct kvm_s390_float_interrupt float_int;
};
-extern int sie64a(struct kvm_s390_sie_block *, __u64 *);
+extern int sie64a(struct kvm_s390_sie_block *, unsigned long *);
#endif
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
void kvm_enable_tdp(void);
+void kvm_disable_tdp(void);
int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
int complete_pio(struct kvm_vcpu *vcpu);