Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Browse files Browse the repository at this point in the history
Pull KVM fixes from Paolo Bonzini:
 "Bug fixes for all architectures.  Nothing really stands out"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (21 commits)
  KVM: nVMX: remove incorrect vpid check in nested invvpid emulation
  arm64: kvm: report original PAR_EL1 upon panic
  arm64: kvm: avoid %p in __kvm_hyp_panic
  KVM: arm/arm64: vgic: Trust the LR state for HW IRQs
  KVM: arm/arm64: arch_timer: Preserve physical dist. active state on LR.active
  KVM: arm/arm64: Fix preemptible timer active state crazyness
  arm64: KVM: Add workaround for Cortex-A57 erratum 834220
  arm64: KVM: Fix AArch32 to AArch64 register mapping
  ARM/arm64: KVM: test properly for a PTE's uncachedness
  KVM: s390: fix wrong lookup of VCPUs by array index
  KVM: s390: avoid memory overwrites on emergency signal injection
  KVM: Provide function for VCPU lookup by id
  KVM: s390: fix pfmf intercept handler
  KVM: s390: enable SIMD only when no VCPUs were created
  KVM: x86: request interrupt window when IRQ chip is split
  KVM: x86: set KVM_REQ_EVENT on local interrupt request from user space
  KVM: x86: split kvm_vcpu_ready_for_interrupt_injection out of dm_request_for_irq_injection
  KVM: x86: fix interrupt window handling in split IRQ chip case
  MIPS: KVM: Uninit VCPU in vcpu_create error path
  MIPS: KVM: Fix CACHE immediate offset sign extension
  ...
  • Loading branch information
torvalds committed Nov 25, 2015
2 parents 6ffeba9 + b2467e7 commit 4cf193b
Show file tree
Hide file tree
Showing 21 changed files with 171 additions and 111 deletions.
7 changes: 1 addition & 6 deletions arch/arm/kvm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,18 +563,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
if (vcpu->arch.power_off || vcpu->arch.pause)
vcpu_sleep(vcpu);

/*
* Disarming the background timer must be done in a
* preemptible context, as this call may sleep.
*/
kvm_timer_flush_hwstate(vcpu);

/*
* Preparing the interrupts to be injected also
* involves poking the GIC, which must be done in a
* non-preemptible context.
*/
preempt_disable();
kvm_timer_flush_hwstate(vcpu);
kvm_vgic_flush_hwstate(vcpu);

local_irq_disable();
Expand Down
15 changes: 7 additions & 8 deletions arch/arm/kvm/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ static void kvm_flush_dcache_pud(pud_t pud)
__kvm_flush_dcache_pud(pud);
}

static bool kvm_is_device_pfn(unsigned long pfn)
{
return !pfn_valid(pfn);
}

/**
* stage2_dissolve_pmd() - clear and flush huge PMD entry
* @kvm: pointer to kvm structure.
Expand Down Expand Up @@ -213,7 +218,7 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
kvm_tlb_flush_vmid_ipa(kvm, addr);

/* No need to invalidate the cache for device mappings */
if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
if (!kvm_is_device_pfn(__phys_to_pfn(addr)))
kvm_flush_dcache_pte(old_pte);

put_page(virt_to_page(pte));
Expand Down Expand Up @@ -305,8 +310,7 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,

pte = pte_offset_kernel(pmd, addr);
do {
if (!pte_none(*pte) &&
(pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
if (!pte_none(*pte) && !kvm_is_device_pfn(__phys_to_pfn(addr)))
kvm_flush_dcache_pte(*pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
}
Expand Down Expand Up @@ -1037,11 +1041,6 @@ static bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
return kvm_vcpu_dabt_iswrite(vcpu);
}

static bool kvm_is_device_pfn(unsigned long pfn)
{
return !pfn_valid(pfn);
}

/**
* stage2_wp_ptes - write protect PMD range
* @pmd: pointer to pmd entry
Expand Down
21 changes: 21 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,27 @@ config ARM64_ERRATUM_832075

If unsure, say Y.

config ARM64_ERRATUM_834220
bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
depends on KVM
default y
help
This option adds an alternative code sequence to work around ARM
erratum 834220 on Cortex-A57 parts up to r1p2.

Affected Cortex-A57 parts might report a Stage 2 translation
fault as the result of a Stage 1 fault for load crossing a
page boundary when there is a permission or device memory
alignment fault at Stage 1 and a translation fault at Stage 2.

The workaround is to verify that the Stage 1 translation
doesn't generate a fault before handling the Stage 2 fault.
Please note that this does not necessarily enable the workaround,
as it depends on the alternative framework, which will only patch
the kernel if an affected CPU is detected.

If unsure, say Y.

config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
#define ARM64_HAS_PAN 4
#define ARM64_HAS_LSE_ATOMICS 5
#define ARM64_WORKAROUND_CAVIUM_23154 6
#define ARM64_WORKAROUND_834220 7

#define ARM64_NCAPS 7
#define ARM64_NCAPS 8

#ifndef __ASSEMBLY__

Expand Down
8 changes: 5 additions & 3 deletions arch/arm64/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
*vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
}

/*
* vcpu_reg should always be passed a register number coming from a
* read of ESR_EL2. Otherwise, it may give the wrong result on AArch32
* with banked registers.
*/
static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num)
{
if (vcpu_mode_is_32bit(vcpu))
return vcpu_reg32(vcpu, reg_num);

return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.regs[reg_num];
}

Expand Down
9 changes: 9 additions & 0 deletions arch/arm64/kernel/cpu_errata.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
(1 << MIDR_VARIANT_SHIFT) | 2),
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_834220
{
/* Cortex-A57 r0p0 - r1p2 */
.desc = "ARM erratum 834220",
.capability = ARM64_WORKAROUND_834220,
MIDR_RANGE(MIDR_CORTEX_A57, 0x00,
(1 << MIDR_VARIANT_SHIFT) | 2),
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_845719
{
/* Cortex-A53 r0p[01234] */
Expand Down
14 changes: 12 additions & 2 deletions arch/arm64/kvm/hyp.S
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,10 @@ ENTRY(__kvm_flush_vm_context)
ENDPROC(__kvm_flush_vm_context)

__kvm_hyp_panic:
// Stash PAR_EL1 before corrupting it in __restore_sysregs
mrs x0, par_el1
push x0, xzr

// Guess the context by looking at VTTBR:
// If zero, then we're already a host.
// Otherwise restore a minimal host context before panicing.
Expand Down Expand Up @@ -898,7 +902,7 @@ __kvm_hyp_panic:
mrs x3, esr_el2
mrs x4, far_el2
mrs x5, hpfar_el2
mrs x6, par_el1
pop x6, xzr // active context PAR_EL1
mrs x7, tpidr_el2

mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
Expand All @@ -914,7 +918,7 @@ __kvm_hyp_panic:
ENDPROC(__kvm_hyp_panic)

__hyp_panic_str:
.ascii "HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p PAR:%p\nVCPU:%p\n\0"
.ascii "HYP panic:\nPS:%08x PC:%016x ESR:%08x\nFAR:%016x HPFAR:%016x PAR:%016x\nVCPU:%p\n\0"

.align 2

Expand Down Expand Up @@ -1015,9 +1019,15 @@ el1_trap:
b.ne 1f // Not an abort we care about

/* This is an abort. Check for permission fault */
alternative_if_not ARM64_WORKAROUND_834220
and x2, x1, #ESR_ELx_FSC_TYPE
cmp x2, #FSC_PERM
b.ne 1f // Not a permission fault
alternative_else
nop // Use the permission fault path to
nop // check for a valid S1 translation,
nop // regardless of the ESR value.
alternative_endif

/*
* Check for Stage-1 page table walk, which is guaranteed
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kvm/inject_fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)

/* Note: These now point to the banked copies */
*vcpu_spsr(vcpu) = new_spsr_value;
*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
*vcpu_reg32(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;

/* Branch to exception vector */
if (sctlr & (1 << 13))
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,

base = (inst >> 21) & 0x1f;
op_inst = (inst >> 16) & 0x1f;
offset = inst & 0xffff;
offset = (int16_t)inst;
cache = (inst >> 16) & 0x3;
op = (inst >> 18) & 0x7;

Expand Down
16 changes: 10 additions & 6 deletions arch/mips/kvm/locore.S
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,11 @@ FEXPORT(__kvm_mips_vcpu_run)

FEXPORT(__kvm_mips_load_asid)
/* Set the ASID for the Guest Kernel */
INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */
/* addresses shift to 0x80000000 */
bltz t0, 1f /* If kernel */
PTR_L t0, VCPU_COP0(k1)
LONG_L t0, COP0_STATUS(t0)
andi t0, KSU_USER | ST0_ERL | ST0_EXL
xori t0, KSU_USER
bnez t0, 1f /* If kernel */
INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */
1:
Expand Down Expand Up @@ -474,9 +476,11 @@ __kvm_mips_return_to_guest:
mtc0 t0, CP0_EPC

/* Set the ASID for the Guest Kernel */
INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */
/* addresses shift to 0x80000000 */
bltz t0, 1f /* If kernel */
PTR_L t0, VCPU_COP0(k1)
LONG_L t0, COP0_STATUS(t0)
andi t0, KSU_USER | ST0_ERL | ST0_EXL
xori t0, KSU_USER
bnez t0, 1f /* If kernel */
INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */
1:
Expand Down
5 changes: 4 additions & 1 deletion arch/mips/kvm/mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)

if (!gebase) {
err = -ENOMEM;
goto out_free_cpu;
goto out_uninit_cpu;
}
kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",
ALIGN(size, PAGE_SIZE), gebase);
Expand Down Expand Up @@ -343,6 +343,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
out_free_gebase:
kfree(gebase);

out_uninit_cpu:
kvm_vcpu_uninit(vcpu);

out_free_cpu:
kfree(vcpu);

Expand Down
7 changes: 5 additions & 2 deletions arch/s390/kvm/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,8 +1030,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
src_id, 0);

/* sending vcpu invalid */
if (src_id >= KVM_MAX_VCPUS ||
kvm_get_vcpu(vcpu->kvm, src_id) == NULL)
if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL)
return -EINVAL;

if (sclp.has_sigpif)
Expand Down Expand Up @@ -1110,6 +1109,10 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
irq->u.emerg.code, 0);

/* sending vcpu invalid */
if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL)
return -EINVAL;

set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
Expand Down
6 changes: 5 additions & 1 deletion arch/s390/kvm/kvm-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,16 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
r = 0;
break;
case KVM_CAP_S390_VECTOR_REGISTERS:
if (MACHINE_HAS_VX) {
mutex_lock(&kvm->lock);
if (atomic_read(&kvm->online_vcpus)) {
r = -EBUSY;
} else if (MACHINE_HAS_VX) {
set_kvm_facility(kvm->arch.model.fac->mask, 129);
set_kvm_facility(kvm->arch.model.fac->list, 129);
r = 0;
} else
r = -EINVAL;
mutex_unlock(&kvm->lock);
VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s",
r ? "(not available)" : "(success)");
break;
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kvm/priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)

kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);

if (!MACHINE_HAS_PFMF)
if (!test_kvm_facility(vcpu->kvm, 8))
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);

if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
Expand Down
8 changes: 2 additions & 6 deletions arch/s390/kvm/sigp.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
u16 cpu_addr, u32 parameter, u64 *status_reg)
{
int rc;
struct kvm_vcpu *dst_vcpu;
struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);

if (cpu_addr >= KVM_MAX_VCPUS)
return SIGP_CC_NOT_OPERATIONAL;

dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
if (!dst_vcpu)
return SIGP_CC_NOT_OPERATIONAL;

Expand Down Expand Up @@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu)
trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);

if (order_code == SIGP_EXTERNAL_CALL) {
dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
BUG_ON(dest_vcpu == NULL);

kvm_s390_vcpu_wakeup(dest_vcpu);
Expand Down
5 changes: 0 additions & 5 deletions arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -7394,11 +7394,6 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)

switch (type) {
case VMX_VPID_EXTENT_ALL_CONTEXT:
if (get_vmcs12(vcpu)->virtual_processor_id == 0) {
nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
return 1;
}
__vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02);
nested_vmx_succeed(vcpu);
break;
Expand Down
Loading

0 comments on commit 4cf193b

Please sign in to comment.