Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf

* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (35 commits)
  PPC: KVM: Fix BAT put
  PPC: e500: Only expose even TLB sizes in initial TLB
  ppc/pseries: Reset VPA registration on CPU reset
  pseries: Don't test for MSR_PR for hypercalls under KVM
  PPC: e500: calculate initrd_base like dt_base
  PPC: e500: increase DTC_LOAD_PAD
  device tree: simplify dumpdtb code
  fdt: move dumpdtb interpretation code to device_tree.c
  target-ppc: Remove unused power_mode field from cpu state
  pseries: Set hash table size based on RAM size
  pseries: Remove unnecessary locking from PAPR hash table hcalls
  ppc405_uc: Fix buffer overflow
  target-ppc: KVM: Fix some kernel version edge cases for kvmppc_reset_htab()
  pseries: Fix semantics of RTAS int-on, int-off and set-xive functions
  pseries: Rework implementation of TCE bypass
  pseries: Remove never used flags field from spapr vio devices
  pseries: Remove XICS irq type enum type
  pseries: Remove C bitfields from xics code
  pseries: Small cleanup to H_CEDE implementation
  pseries: Fix XICS reset
  ...
This commit is contained in:
Aurelien Jarno 2012-10-06 18:51:36 +02:00
commit 6b2f90fbbd
21 changed files with 576 additions and 437 deletions

View file

@ -60,6 +60,7 @@ static int cap_booke_sregs;
static int cap_ppc_smt;
static int cap_ppc_rma;
static int cap_spapr_tce;
static int cap_hior;
/* XXX We have a race condition where we actually have a level triggered
* interrupt, but the infrastructure can't expose that yet, so the guest
@ -86,6 +87,7 @@ int kvm_arch_init(KVMState *s)
cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
if (!cap_interrupt_level) {
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@ -469,6 +471,54 @@ int kvm_arch_put_registers(CPUPPCState *env, int level)
env->tlb_dirty = false;
}
if (cap_segstate && (level >= KVM_PUT_RESET_STATE)) {
struct kvm_sregs sregs;
sregs.pvr = env->spr[SPR_PVR];
sregs.u.s.sdr1 = env->spr[SPR_SDR1];
/* Sync SLB */
#ifdef TARGET_PPC64
for (i = 0; i < 64; i++) {
sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
}
#endif
/* Sync SRs */
for (i = 0; i < 16; i++) {
sregs.u.s.ppc32.sr[i] = env->sr[i];
}
/* Sync BATs */
for (i = 0; i < 8; i++) {
/* Beware. We have to swap upper and lower bits here */
sregs.u.s.ppc32.dbat[i] = ((uint64_t)env->DBAT[0][i] << 32)
| env->DBAT[1][i];
sregs.u.s.ppc32.ibat[i] = ((uint64_t)env->IBAT[0][i] << 32)
| env->IBAT[1][i];
}
ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
if (ret) {
return ret;
}
}
if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
uint64_t hior = env->spr[SPR_HIOR];
struct kvm_one_reg reg = {
.id = KVM_REG_PPC_HIOR,
.addr = (uintptr_t) &hior,
};
ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &reg);
if (ret) {
return ret;
}
}
return ret;
}
@ -946,52 +996,14 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
void kvmppc_set_papr(CPUPPCState *env)
{
struct kvm_enable_cap cap = {};
struct kvm_one_reg reg = {};
struct kvm_sregs sregs = {};
int ret;
uint64_t hior = env->spr[SPR_HIOR];
cap.cap = KVM_CAP_PPC_PAPR;
ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap);
if (ret) {
goto fail;
cpu_abort(env, "This KVM version does not support PAPR\n");
}
/*
* XXX We set HIOR here. It really should be a qdev property of
* the CPU node, but we don't have CPUs converted to qdev yet.
*
* Once we have qdev CPUs, move HIOR to a qdev property and
* remove this chunk.
*/
reg.id = KVM_REG_PPC_HIOR;
reg.addr = (uintptr_t)&hior;
ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &reg);
if (ret) {
fprintf(stderr, "Couldn't set HIOR. Maybe you're running an old \n"
"kernel with support for HV KVM but no PAPR PR \n"
"KVM in which case things will work. If they don't \n"
"please update your host kernel!\n");
}
/* Set SDR1 so kernel space finds the HTAB */
ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
if (ret) {
goto fail;
}
sregs.u.s.sdr1 = env->spr[SPR_SDR1];
ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
if (ret) {
goto fail;
}
return;
fail:
cpu_abort(env, "This KVM version does not support PAPR\n");
}
int kvmppc_smt_threads(void)
@ -999,6 +1011,7 @@ int kvmppc_smt_threads(void)
return cap_ppc_smt ? cap_ppc_smt : 1;
}
#ifdef TARGET_PPC64
off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
{
void *rma;
@ -1042,6 +1055,16 @@ off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
return size;
}
uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
{
if (cap_ppc_rma >= 2) {
return current_size;
}
return MIN(current_size,
getrampagesize() << (hash_shift - 7));
}
#endif
void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
{
struct kvm_create_spapr_tce args = {
@ -1101,6 +1124,44 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
return 0;
}
int kvmppc_reset_htab(int shift_hint)
{
uint32_t shift = shift_hint;
if (!kvm_enabled()) {
/* Full emulation, tell caller to allocate htab itself */
return 0;
}
if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) {
int ret;
ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift);
if (ret == -ENOTTY) {
/* At least some versions of PR KVM advertise the
* capability, but don't implement the ioctl(). Oops.
* Return 0 so that we allocate the htab in qemu, as is
* correct for PR. */
return 0;
} else if (ret < 0) {
return ret;
}
return shift;
}
/* We have a kernel that predates the htab reset calls. For PR
* KVM, we need to allocate the htab ourselves, for an HV KVM of
* this era, it has allocated a 16MB fixed size hash table
* already. Kernels of this era have the GET_PVINFO capability
* only on PR, so we use this hack to determine the right
* answer */
if (kvm_check_extension(kvm_state, KVM_CAP_PPC_GET_PVINFO)) {
/* PR - tell caller to allocate htab */
return 0;
} else {
/* HV - assume 16MB kernel allocated htab */
return 24;
}
}
static inline uint32_t mfpvr(void)
{
uint32_t pvr;