static int handle_set_prefix(struct kvm_vcpu *vcpu) { int base2 = vcpu->arch.sie_block->ipb >> 28; int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); u64 operand2; u32 address = 0; u8 tmp; vcpu->stat.instruction_spx++; operand2 = disp2; if (base2) operand2 += vcpu->arch.guest_gprs[base2]; /* must be word boundary */ if (operand2 & 3) { kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); goto out; } /* get the value */ if (get_guest_u32(vcpu, operand2, &address)) { kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); goto out; } address = address & 0x7fffe000u; /* make sure that the new value is valid memory */ if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1))) { kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); goto out; } vcpu->arch.sie_block->prefix = address; vcpu->arch.sie_block->ihcpu = 0xffff; VCPU_EVENT(vcpu, 5, "setting prefix to %x", address); out: return 0; }
static int handle_set_prefix(struct kvm_vcpu *vcpu) { u64 operand2; u32 address = 0; u8 tmp; vcpu->stat.instruction_spx++; operand2 = kvm_s390_get_base_disp_s(vcpu); /* must be word boundary */ if (operand2 & 3) { kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); goto out; } /* get the value */ if (get_guest_u32(vcpu, operand2, &address)) { kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); goto out; } address = address & 0x7fffe000u; /* make sure that the new value is valid memory */ if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1))) { kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); goto out; } kvm_s390_set_prefix(vcpu, address); VCPU_EVENT(vcpu, 5, "setting prefix to %x", address); trace_kvm_s390_handle_prefix(vcpu, 1, address); out: return 0; }
static int handle_lctl(struct kvm_vcpu *vcpu) { int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; int reg3 = vcpu->arch.sie_block->ipa & 0x000f; int base2 = vcpu->arch.sie_block->ipb >> 28; int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); u64 useraddr; u32 val = 0; int reg, rc; vcpu->stat.instruction_lctl++; useraddr = disp2; if (base2) useraddr += vcpu->arch.guest_gprs[base2]; if (useraddr & 3) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2, disp2); reg = reg1; do { rc = get_guest_u32(vcpu, useraddr, &val); if (rc == -EFAULT) { kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); break; } vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; vcpu->arch.sie_block->gcr[reg] |= val; useraddr += 4; if (reg == reg3) break; reg = (reg + 1) % 16; } while (1); return 0; }