Skip to content

Commit

Permalink
Merge branch 'kvm-mips-fixes' into HEAD
Browse files Browse the repository at this point in the history
Merge MIPS patches destined to both 4.7 and kvm/next, to avoid
unnecessary conflicts.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Paolo Bonzini committed Jun 14, 2016
2 parents dca4d72 + 6df82a7 commit b11c3f5
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 8 deletions.
3 changes: 2 additions & 1 deletion arch/mips/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
#define KVM_GUEST_KUSEG 0x00000000UL
#define KVM_GUEST_KSEG0 0x40000000UL
#define KVM_GUEST_KSEG23 0x60000000UL
#define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) & 0x60000000)
#define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) & 0xe0000000)
#define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)

#define KVM_GUEST_CKSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0)
Expand Down Expand Up @@ -338,6 +338,7 @@ struct kvm_mips_tlb {
#define KVM_MIPS_GUEST_TLB_SIZE 64
struct kvm_vcpu_arch {
void *host_ebase, *guest_ebase;
int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
unsigned long host_stack;
unsigned long host_gp;

Expand Down
19 changes: 13 additions & 6 deletions arch/mips/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
if (index < 0) {
vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK);
vcpu->arch.host_cp0_badvaddr = va;
vcpu->arch.pc = curr_pc;
er = kvm_mips_emulate_tlbmiss_ld(cause, NULL, run,
vcpu);
preempt_enable();
Expand All @@ -1647,6 +1648,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
* invalid exception to the guest
*/
if (!TLB_IS_VALID(*tlb, va)) {
vcpu->arch.host_cp0_badvaddr = va;
vcpu->arch.pc = curr_pc;
er = kvm_mips_emulate_tlbinv_ld(cause, NULL,
run, vcpu);
preempt_enable();
Expand All @@ -1666,7 +1669,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
cache, op, base, arch->gprs[base], offset);
er = EMULATE_FAIL;
preempt_enable();
goto dont_update_pc;
goto done;

}

Expand Down Expand Up @@ -1694,16 +1697,20 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
kvm_err("NO-OP CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
cache, op, base, arch->gprs[base], offset);
er = EMULATE_FAIL;
preempt_enable();
goto dont_update_pc;
}

preempt_enable();
done:
/* Rollback PC only if emulation was unsuccessful */
if (er == EMULATE_FAIL)
vcpu->arch.pc = curr_pc;

dont_update_pc:
/* Rollback PC */
vcpu->arch.pc = curr_pc;
done:
/*
* This is for exceptions whose emulation updates the PC, so do not
* overwrite the PC under any circumstances
*/

return er;
}

Expand Down
1 change: 1 addition & 0 deletions arch/mips/kvm/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define MIPS_EXC_MAX 12
/* XXXSL More to follow */

extern char __kvm_mips_vcpu_run_end[];
extern char mips32_exception[], mips32_exceptionEnd[];
extern char mips32_GuestException[], mips32_GuestExceptionEnd[];

Expand Down
1 change: 1 addition & 0 deletions arch/mips/kvm/locore.S
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ FEXPORT(__kvm_mips_load_k0k1)

/* Jump to guest */
eret
EXPORT(__kvm_mips_vcpu_run_end)

VECTOR(MIPSX(exception), unknown)
/* Find out what mode we came from and jump to the proper handler. */
Expand Down
11 changes: 10 additions & 1 deletion arch/mips/kvm/mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
memcpy(gebase + offset, mips32_GuestException,
mips32_GuestExceptionEnd - mips32_GuestException);

#ifdef MODULE
offset += mips32_GuestExceptionEnd - mips32_GuestException;
memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
__kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
vcpu->arch.vcpu_run = gebase + offset;
#else
vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
#endif

/* Invalidate the icache for these ranges */
local_flush_icache_range((unsigned long)gebase,
(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
Expand Down Expand Up @@ -404,7 +413,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
/* Disable hardware page table walking while in guest */
htw_stop();

r = __kvm_mips_vcpu_run(run, vcpu);
r = vcpu->arch.vcpu_run(run, vcpu);

/* Re-enable HTW before enabling interrupts */
htw_start();
Expand Down

0 comments on commit b11c3f5

Please sign in to comment.