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 more KVM updates from Paolo Bonzini:
 "Second batch of KVM updates.  Some minor x86 fixes, two s390 guest
  features that need some handling in the host, and all the PPC changes.

  The PPC changes include support for little-endian guests and
  enablement for new POWER8 features"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (45 commits)
  x86, kvm: correctly access the KVM_CPUID_FEATURES leaf at 0x40000101
  x86, kvm: cache the base of the KVM cpuid leaves
  kvm: x86: move KVM_CAP_HYPERV_TIME outside #ifdef
  KVM: PPC: Book3S PR: Cope with doorbell interrupts
  KVM: PPC: Book3S HV: Add software abort codes for transactional memory
  KVM: PPC: Book3S HV: Add new state for transactional memory
  powerpc/Kconfig: Make TM select VSX and VMX
  KVM: PPC: Book3S HV: Basic little-endian guest support
  KVM: PPC: Book3S HV: Add support for DABRX register on POWER7
  KVM: PPC: Book3S HV: Prepare for host using hypervisor doorbells
  KVM: PPC: Book3S HV: Handle new LPCR bits on POWER8
  KVM: PPC: Book3S HV: Handle guest using doorbells for IPIs
  KVM: PPC: Book3S HV: Consolidate code that checks reason for wake from nap
  KVM: PPC: Book3S HV: Implement architecture compatibility modes for POWER8
  KVM: PPC: Book3S HV: Add handler for HV facility unavailable
  KVM: PPC: Book3S HV: Flush the correct number of TLB sets on POWER8
  KVM: PPC: Book3S HV: Context-switch new POWER8 SPRs
  KVM: PPC: Book3S HV: Align physical and virtual CPU thread numbers
  KVM: PPC: Book3S HV: Don't set DABR on POWER8
  kvm/ppc: IRQ disabling cleanup
  ...
  • Loading branch information
torvalds committed Jan 31, 2014
2 parents e30b82b + b73117c commit e2a0f81
Show file tree
Hide file tree
Showing 53 changed files with 1,715 additions and 1,122 deletions.
1 change: 1 addition & 0 deletions Documentation/virtual/kvm/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,7 @@ registers, find a list below:
PPC | KVM_REG_PPC_LPCR | 64
PPC | KVM_REG_PPC_PPR | 64
PPC | KVM_REG_PPC_ARCH_COMPAT 32
PPC | KVM_REG_PPC_DABRX | 32
PPC | KVM_REG_PPC_TM_GPR0 | 64
...
PPC | KVM_REG_PPC_TM_GPR31 | 64
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ config PPC_TRANSACTIONAL_MEM
bool "Transactional Memory support for POWERPC"
depends on PPC_BOOK3S_64
depends on SMP
select ALTIVEC
select VSX
default n
---help---
Support user-mode Transactional Memory on POWERPC.
Expand Down
111 changes: 111 additions & 0 deletions arch/powerpc/include/asm/epapr_hcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,5 +460,116 @@ static inline unsigned int ev_idle(void)

return r3;
}

#ifdef CONFIG_EPAPR_PARAVIRT
static inline unsigned long epapr_hypercall(unsigned long *in,
unsigned long *out,
unsigned long nr)
{
unsigned long register r0 asm("r0");
unsigned long register r3 asm("r3") = in[0];
unsigned long register r4 asm("r4") = in[1];
unsigned long register r5 asm("r5") = in[2];
unsigned long register r6 asm("r6") = in[3];
unsigned long register r7 asm("r7") = in[4];
unsigned long register r8 asm("r8") = in[5];
unsigned long register r9 asm("r9") = in[6];
unsigned long register r10 asm("r10") = in[7];
unsigned long register r11 asm("r11") = nr;
unsigned long register r12 asm("r12");

asm volatile("bl epapr_hypercall_start"
: "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6),
"=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11),
"=r"(r12)
: "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "r"(r8),
"r"(r9), "r"(r10), "r"(r11)
: "memory", "cc", "xer", "ctr", "lr");

out[0] = r4;
out[1] = r5;
out[2] = r6;
out[3] = r7;
out[4] = r8;
out[5] = r9;
out[6] = r10;
out[7] = r11;

return r3;
}
#else
static unsigned long epapr_hypercall(unsigned long *in,
unsigned long *out,
unsigned long nr)
{
return EV_UNIMPLEMENTED;
}
#endif

static inline long epapr_hypercall0_1(unsigned int nr, unsigned long *r2)
{
unsigned long in[8];
unsigned long out[8];
unsigned long r;

r = epapr_hypercall(in, out, nr);
*r2 = out[0];

return r;
}

static inline long epapr_hypercall0(unsigned int nr)
{
unsigned long in[8];
unsigned long out[8];

return epapr_hypercall(in, out, nr);
}

static inline long epapr_hypercall1(unsigned int nr, unsigned long p1)
{
unsigned long in[8];
unsigned long out[8];

in[0] = p1;
return epapr_hypercall(in, out, nr);
}

static inline long epapr_hypercall2(unsigned int nr, unsigned long p1,
unsigned long p2)
{
unsigned long in[8];
unsigned long out[8];

in[0] = p1;
in[1] = p2;
return epapr_hypercall(in, out, nr);
}

static inline long epapr_hypercall3(unsigned int nr, unsigned long p1,
unsigned long p2, unsigned long p3)
{
unsigned long in[8];
unsigned long out[8];

in[0] = p1;
in[1] = p2;
in[2] = p3;
return epapr_hypercall(in, out, nr);
}

static inline long epapr_hypercall4(unsigned int nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4)
{
unsigned long in[8];
unsigned long out[8];

in[0] = p1;
in[1] = p2;
in[2] = p3;
in[3] = p4;
return epapr_hypercall(in, out, nr);
}
#endif /* !__ASSEMBLY__ */
#endif /* _EPAPR_HCALLS_H */
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/kvm_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,17 @@
#define BOOK3S_INTERRUPT_FP_UNAVAIL 0x800
#define BOOK3S_INTERRUPT_DECREMENTER 0x900
#define BOOK3S_INTERRUPT_HV_DECREMENTER 0x980
#define BOOK3S_INTERRUPT_DOORBELL 0xa00
#define BOOK3S_INTERRUPT_SYSCALL 0xc00
#define BOOK3S_INTERRUPT_TRACE 0xd00
#define BOOK3S_INTERRUPT_H_DATA_STORAGE 0xe00
#define BOOK3S_INTERRUPT_H_INST_STORAGE 0xe20
#define BOOK3S_INTERRUPT_H_EMUL_ASSIST 0xe40
#define BOOK3S_INTERRUPT_H_DOORBELL 0xe80
#define BOOK3S_INTERRUPT_PERFMON 0xf00
#define BOOK3S_INTERRUPT_ALTIVEC 0xf20
#define BOOK3S_INTERRUPT_VSX 0xf40
#define BOOK3S_INTERRUPT_H_FAC_UNAVAIL 0xf80

#define BOOK3S_IRQPRIO_SYSTEM_RESET 0
#define BOOK3S_IRQPRIO_DATA_SEGMENT 1
Expand Down
27 changes: 13 additions & 14 deletions arch/powerpc/include/asm/kvm_book3s.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,6 @@ extern void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr,

extern void kvmppc_entry_trampoline(void);
extern void kvmppc_hv_entry_trampoline(void);
extern void kvmppc_load_up_fpu(void);
extern void kvmppc_load_up_altivec(void);
extern void kvmppc_load_up_vsx(void);
extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst);
extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst);
extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
Expand Down Expand Up @@ -271,16 +268,25 @@ static inline ulong kvmppc_get_pc(struct kvm_vcpu *vcpu)
return vcpu->arch.pc;
}

static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu)
{
ulong pc = kvmppc_get_pc(vcpu);
return (vcpu->arch.shared->msr & MSR_LE) != (MSR_KERNEL & MSR_LE);
}

static inline u32 kvmppc_get_last_inst_internal(struct kvm_vcpu *vcpu, ulong pc)
{
/* Load the instruction manually if it failed to do so in the
* exit path */
if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED)
kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false);

return vcpu->arch.last_inst;
return kvmppc_need_byteswap(vcpu) ? swab32(vcpu->arch.last_inst) :
vcpu->arch.last_inst;
}

static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
{
return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu));
}

/*
Expand All @@ -290,14 +296,7 @@ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
*/
static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu)
{
ulong pc = kvmppc_get_pc(vcpu) - 4;

/* Load the instruction manually if it failed to do so in the
* exit path */
if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED)
kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false);

return vcpu->arch.last_inst;
return kvmppc_get_last_inst_internal(vcpu, kvmppc_get_pc(vcpu) - 4);
}

static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu)
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/kvm_book3s_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ struct kvmppc_host_state {
u8 hwthread_req;
u8 hwthread_state;
u8 host_ipi;
u8 ptid;
struct kvm_vcpu *kvm_vcpu;
struct kvmppc_vcore *kvm_vcore;
unsigned long xics_phys;
Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/include/asm/kvm_booke.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu)
return vcpu->arch.xer;
}

static inline bool kvmppc_need_byteswap(struct kvm_vcpu *vcpu)
{
/* XXX Would need to check TLB entry */
return false;
}

static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu)
{
return vcpu->arch.last_inst;
Expand Down
61 changes: 51 additions & 10 deletions arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct kvmppc_vcore {
int n_woken;
int nap_count;
int napping_threads;
int first_vcpuid;
u16 pcpu;
u16 last_cpu;
u8 vcore_state;
Expand All @@ -298,10 +299,12 @@ struct kvmppc_vcore {
u64 stolen_tb;
u64 preempt_tb;
struct kvm_vcpu *runner;
struct kvm *kvm;
u64 tb_offset; /* guest timebase - host timebase */
ulong lpcr;
u32 arch_compat;
ulong pcr;
ulong dpdes; /* doorbell state (POWER8) */
};

#define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff)
Expand Down Expand Up @@ -410,8 +413,7 @@ struct kvm_vcpu_arch {

ulong gpr[32];

u64 fpr[32];
u64 fpscr;
struct thread_fp_state fp;

#ifdef CONFIG_SPE
ulong evr[32];
Expand All @@ -420,12 +422,7 @@ struct kvm_vcpu_arch {
u64 acc;
#endif
#ifdef CONFIG_ALTIVEC
vector128 vr[32];
vector128 vscr;
#endif

#ifdef CONFIG_VSX
u64 vsr[64];
struct thread_vr_state vr;
#endif

#ifdef CONFIG_KVM_BOOKE_HV
Expand All @@ -452,6 +449,7 @@ struct kvm_vcpu_arch {
ulong pc;
ulong ctr;
ulong lr;
ulong tar;

ulong xer;
u32 cr;
Expand All @@ -461,13 +459,30 @@ struct kvm_vcpu_arch {
ulong guest_owned_ext;
ulong purr;
ulong spurr;
ulong ic;
ulong vtb;
ulong dscr;
ulong amr;
ulong uamor;
ulong iamr;
u32 ctrl;
u32 dabrx;
ulong dabr;
ulong dawr;
ulong dawrx;
ulong ciabr;
ulong cfar;
ulong ppr;
ulong pspb;
ulong fscr;
ulong ebbhr;
ulong ebbrr;
ulong bescr;
ulong csigr;
ulong tacr;
ulong tcscr;
ulong acop;
ulong wort;
ulong shadow_srr1;
#endif
u32 vrsave; /* also USPRG0 */
Expand Down Expand Up @@ -502,10 +517,33 @@ struct kvm_vcpu_arch {
u32 ccr1;
u32 dbsr;

u64 mmcr[3];
u64 mmcr[5];
u32 pmc[8];
u32 spmc[2];
u64 siar;
u64 sdar;
u64 sier;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
u64 tfhar;
u64 texasr;
u64 tfiar;

u32 cr_tm;
u64 lr_tm;
u64 ctr_tm;
u64 amr_tm;
u64 ppr_tm;
u64 dscr_tm;
u64 tar_tm;

ulong gpr_tm[32];

struct thread_fp_state fp_tm;

struct thread_vr_state vr_tm;
u32 vrsave_tm; /* also USPRG0 */

#endif

#ifdef CONFIG_KVM_EXIT_TIMING
struct mutex exit_timing_lock;
Expand Down Expand Up @@ -546,6 +584,7 @@ struct kvm_vcpu_arch {
#endif
gpa_t paddr_accessed;
gva_t vaddr_accessed;
pgd_t *pgdir;

u8 io_gpr; /* GPR used as IO source/target */
u8 mmio_is_bigendian;
Expand Down Expand Up @@ -603,7 +642,6 @@ struct kvm_vcpu_arch {
struct list_head run_list;
struct task_struct *run_task;
struct kvm_run *kvm_run;
pgd_t *pgdir;

spinlock_t vpa_update_lock;
struct kvmppc_vpa vpa;
Expand All @@ -616,9 +654,12 @@ struct kvm_vcpu_arch {
spinlock_t tbacct_lock;
u64 busy_stolen;
u64 busy_preempt;
unsigned long intr_msr;
#endif
};

#define VCPU_FPR(vcpu, i) (vcpu)->arch.fp.fpr[i][TS_FPROFFSET]

/* Values for vcpu->arch.state */
#define KVMPPC_VCPU_NOTREADY 0
#define KVMPPC_VCPU_RUNNABLE 1
Expand Down
Loading

0 comments on commit e2a0f81

Please sign in to comment.