Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 93846
b: refs/heads/master
c: ba5c1e9
h: refs/heads/master
v: v3
  • Loading branch information
Carsten Otte authored and Avi Kivity committed Apr 27, 2008
1 parent 28b36af commit ec18519
Show file tree
Hide file tree
Showing 8 changed files with 858 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f2abe6a1e525e878bdf58f68ccd146d543fde84
refs/heads/master: ba5c1e9b6ceebdc39343cc03eb39f077abd3c571
2 changes: 1 addition & 1 deletion trunk/arch/s390/kvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o)

EXTRA_CFLAGS += -Ivirt/kvm -Iarch/s390/kvm

kvm-objs := $(common-objs) kvm-s390.o sie64a.o intercept.o
kvm-objs := $(common-objs) kvm-s390.o sie64a.o intercept.o interrupt.o
obj-$(CONFIG_KVM) += kvm.o
116 changes: 116 additions & 0 deletions trunk/arch/s390/kvm/intercept.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,86 @@
#include <asm/kvm_host.h>

#include "kvm-s390.h"
#include "gaccess.h"

static int handle_lctg(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) +
((vcpu->arch.sie_block->ipb & 0xff00) << 4);
u64 useraddr;
int reg, rc;

vcpu->stat.instruction_lctg++;
if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f)
return -ENOTSUPP;

useraddr = disp2;
if (base2)
useraddr += vcpu->arch.guest_gprs[base2];

reg = reg1;

VCPU_EVENT(vcpu, 5, "lctg r1:%x, r3:%x,b2:%x,d2:%x", reg1, reg3, base2,
disp2);

do {
rc = get_guest_u64(vcpu, useraddr,
&vcpu->arch.sie_block->gcr[reg]);
if (rc == -EFAULT) {
kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
break;
}
useraddr += 8;
if (reg == reg3)
break;
reg = (reg + 1) % 16;
} while (1);
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];

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;
}

static intercept_handler_t instruction_handlers[256] = {
[0xb7] = handle_lctl,
[0xeb] = handle_lctg,
};

static int handle_noop(struct kvm_vcpu *vcpu)
{
Expand Down Expand Up @@ -58,10 +138,46 @@ static int handle_validity(struct kvm_vcpu *vcpu)
return -ENOTSUPP;
}

static int handle_instruction(struct kvm_vcpu *vcpu)
{
intercept_handler_t handler;

vcpu->stat.exit_instruction++;
handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
if (handler)
return handler(vcpu);
return -ENOTSUPP;
}

static int handle_prog(struct kvm_vcpu *vcpu)
{
vcpu->stat.exit_program_interruption++;
return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc);
}

static int handle_instruction_and_prog(struct kvm_vcpu *vcpu)
{
int rc, rc2;

vcpu->stat.exit_instr_and_program++;
rc = handle_instruction(vcpu);
rc2 = handle_prog(vcpu);

if (rc == -ENOTSUPP)
vcpu->arch.sie_block->icptcode = 0x04;
if (rc)
return rc;
return rc2;
}

static const intercept_handler_t intercept_funcs[0x48 >> 2] = {
[0x00 >> 2] = handle_noop,
[0x04 >> 2] = handle_instruction,
[0x08 >> 2] = handle_prog,
[0x0C >> 2] = handle_instruction_and_prog,
[0x10 >> 2] = handle_noop,
[0x14 >> 2] = handle_noop,
[0x1C >> 2] = kvm_s390_handle_wait,
[0x20 >> 2] = handle_validity,
[0x28 >> 2] = handle_stop,
};
Expand Down
Loading

0 comments on commit ec18519

Please sign in to comment.