Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b73117c4 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge branch 'kvm-ppc-next' of git://github.com/agraf/linux-2.6 into kvm-queue

Conflicts:
	arch/powerpc/kvm/book3s_hv_rmhandlers.S
	arch/powerpc/kvm/booke.c
parents 77f01bdf 40688909
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -343,6 +343,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.
+111 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -91,14 +91,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
+13 −14
Original line number Diff line number Diff line
@@ -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);
@@ -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));
}

/*
@@ -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)
Loading