Re: [PATCH 3/4] kvm-s390: provide general purpose guest registers via kvm_run

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05.01.2012, at 10:54, Christian Borntraeger wrote:

> This patch adds the general purpose registers to the kvm_run structure.
> 
> Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx>
> ---
> arch/s390/include/asm/kvm.h      |    2 ++
> arch/s390/include/asm/kvm_host.h |    3 +--
> arch/s390/kvm/diag.c             |    6 +++---
> arch/s390/kvm/intercept.c        |    4 ++--
> arch/s390/kvm/kvm-s390.c         |   13 +++++++------
> arch/s390/kvm/priv.c             |   24 ++++++++++++------------
> arch/s390/kvm/sigp.c             |   20 ++++++++++----------
> 7 files changed, 37 insertions(+), 35 deletions(-)
> 
> diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
> index b48edc3..5dfe143b29 100644
> --- a/arch/s390/include/asm/kvm.h
> +++ b/arch/s390/include/asm/kvm.h
> @@ -47,6 +47,8 @@ struct kvm_sync_ro_regs {
> 	__u32 prefix;	/* prefix register */
> };
> 
> +#define KVM_SYNC_RW_GPRS   (1UL << 0)
> struct kvm_sync_rw_regs {
> +	__u64          gprs[16];	/* general purpose registers */

I would recommend having a bitmap in parallel to the "these fields are available" one that says "these fields are dirty". It doesn't make too much sense for GPRs, since they're reread on every guest entry anyway, but might come in handy later for other registers.

> };
> #endif
> diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
> index b0c235c..173f44d 100644
> --- a/arch/s390/include/asm/kvm_host.h
> +++ b/arch/s390/include/asm/kvm_host.h
> @@ -227,7 +227,6 @@ struct kvm_s390_float_interrupt {
> 
> struct kvm_vcpu_arch {
> 	struct kvm_s390_sie_block *sie_block;
> -	unsigned long	  guest_gprs[16];
> 	s390_fp_regs      host_fpregs;
> 	unsigned int      host_acrs[NUM_ACRS];
> 	s390_fp_regs      guest_fpregs;
> @@ -253,5 +252,5 @@ struct kvm_arch{
> 	struct gmap *gmap;
> };
> 
> -extern int sie64a(struct kvm_s390_sie_block *, unsigned long *);
> +extern int sie64a(struct kvm_s390_sie_block *, u64 *);
> #endif
> diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
> index 8943e82..9a1ef76 100644
> --- a/arch/s390/kvm/diag.c
> +++ b/arch/s390/kvm/diag.c
> @@ -20,8 +20,8 @@ static int diag_release_pages(struct kvm_vcpu *vcpu)
> 	unsigned long start, end;
> 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
> 
> -	start = vcpu->arch.guest_gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
> -	end = vcpu->arch.guest_gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
> +	start = vcpu->run->sync_rw.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
> +	end = vcpu->run->sync_rw.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
> 
> 	if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end
> 	    || start < 2 * PAGE_SIZE)
> @@ -56,7 +56,7 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu)
> static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
> {
> 	unsigned int reg = vcpu->arch.sie_block->ipa & 0xf;
> -	unsigned long subcode = vcpu->arch.guest_gprs[reg] & 0xffff;
> +	unsigned long subcode = vcpu->run->sync_rw.gprs[reg] & 0xffff;
> 
> 	VCPU_EVENT(vcpu, 5, "diag ipl functions, subcode %lx", subcode);
> 	switch (subcode) {
> diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
> index 0243454..b93a908 100644
> --- a/arch/s390/kvm/intercept.c
> +++ b/arch/s390/kvm/intercept.c
> @@ -36,7 +36,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
> 
> 	useraddr = disp2;
> 	if (base2)
> -		useraddr += vcpu->arch.guest_gprs[base2];
> +		useraddr += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (useraddr & 7)
> 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
> @@ -75,7 +75,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
> 
> 	useraddr = disp2;
> 	if (base2)
> -		useraddr += vcpu->arch.guest_gprs[base2];
> +		useraddr += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (useraddr & 3)
> 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index 1b48a73..0f9bbb2 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -258,6 +258,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
> {
> 	vcpu->arch.gmap = vcpu->kvm->arch.gmap;
> 	vcpu->run->kvm_valid_sync_ro_regs = KVM_SYNC_RO_PREFIX;
> +	vcpu->run->kvm_valid_sync_rw_regs = KVM_SYNC_RW_GPRS;
> 	return 0;
> }
> 
> @@ -390,13 +391,13 @@ static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
> 
> int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
> {
> -	memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
> +	memcpy(&vcpu->run->sync_rw.gprs, &regs->gprs, sizeof(regs->gprs));

The &s look suspicious here. You're already pointing at arrays, no?

> 	return 0;
> }
> 
> int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
> {
> -	memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
> +	memcpy(&regs->gprs, &vcpu->run->sync_rw.gprs, sizeof(regs->gprs));
> 	return 0;
> }
> 
> @@ -471,7 +472,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
> 
> static void __vcpu_run(struct kvm_vcpu *vcpu)
> {
> -	memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
> +	memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->sync_rw.gprs[14], 16);
> 
> 	if (need_resched())
> 		schedule();
> @@ -487,7 +488,7 @@ static void __vcpu_run(struct kvm_vcpu *vcpu)
> 	local_irq_enable();
> 	VCPU_EVENT(vcpu, 6, "entering sie flags %x",
> 		   atomic_read(&vcpu->arch.sie_block->cpuflags));
> -	if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
> +	if (sie64a(vcpu->arch.sie_block, vcpu->run->sync_rw.gprs)) {
> 		VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
> 		kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
> 	}
> @@ -497,7 +498,7 @@ static void __vcpu_run(struct kvm_vcpu *vcpu)
> 	kvm_guest_exit();
> 	local_irq_enable();
> 
> -	memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
> +	memcpy(&vcpu->run->sync_rw.gprs[14], &vcpu->arch.sie_block->gg14, 16);
> }
> 
> int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
> @@ -605,7 +606,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
> 		return -EFAULT;
> 
> 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
> -			vcpu->arch.guest_gprs, 128, prefix))
> +			vcpu->run->sync_rw.gprs, 128, prefix))
> 		return -EFAULT;
> 
> 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
> diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
> index d026389..738bc43 100644
> --- a/arch/s390/kvm/priv.c
> +++ b/arch/s390/kvm/priv.c
> @@ -33,7 +33,7 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
> 
> 	operand2 = disp2;
> 	if (base2)
> -		operand2 += vcpu->arch.guest_gprs[base2];
> +		operand2 += vcpu->run->sync_rw.gprs[base2];
> 
> 	/* must be word boundary */
> 	if (operand2 & 3) {
> @@ -74,7 +74,7 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu)
> 	vcpu->stat.instruction_stpx++;
> 	operand2 = disp2;
> 	if (base2)
> -		operand2 += vcpu->arch.guest_gprs[base2];
> +		operand2 += vcpu->run->sync_rw.gprs[base2];
> 
> 	/* must be word boundary */
> 	if (operand2 & 3) {
> @@ -106,7 +106,7 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
> 	vcpu->stat.instruction_stap++;
> 	useraddr = disp2;
> 	if (base2)
> -		useraddr += vcpu->arch.guest_gprs[base2];
> +		useraddr += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (useraddr & 1) {
> 		kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
> @@ -181,7 +181,7 @@ static int handle_stidp(struct kvm_vcpu *vcpu)
> 	vcpu->stat.instruction_stidp++;
> 	operand2 = disp2;
> 	if (base2)
> -		operand2 += vcpu->arch.guest_gprs[base2];
> +		operand2 += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (operand2 & 7) {
> 		kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
> @@ -232,9 +232,9 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
> 
> static int handle_stsi(struct kvm_vcpu *vcpu)
> {
> -	int fc = (vcpu->arch.guest_gprs[0] & 0xf0000000) >> 28;
> -	int sel1 = vcpu->arch.guest_gprs[0] & 0xff;
> -	int sel2 = vcpu->arch.guest_gprs[1] & 0xffff;
> +	int fc = (vcpu->run->sync_rw.gprs[0] & 0xf0000000) >> 28;
> +	int sel1 = vcpu->run->sync_rw.gprs[0] & 0xff;
> +	int sel2 = vcpu->run->sync_rw.gprs[1] & 0xffff;
> 	int base2 = vcpu->arch.sie_block->ipb >> 28;
> 	int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
> 	u64 operand2;
> @@ -245,14 +245,14 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
> 
> 	operand2 = disp2;
> 	if (base2)
> -		operand2 += vcpu->arch.guest_gprs[base2];
> +		operand2 += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (operand2 & 0xfff && fc > 0)
> 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
> 
> 	switch (fc) {
> 	case 0:
> -		vcpu->arch.guest_gprs[0] = 3 << 28;
> +		vcpu->run->sync_rw.gprs[0] = 3 << 28;
> 		vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
> 		return 0;
> 	case 1: /* same handling for 1 and 2 */
> @@ -281,7 +281,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
> 	}
> 	free_page(mem);
> 	vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
> -	vcpu->arch.guest_gprs[0] = 0;
> +	vcpu->run->sync_rw.gprs[0] = 0;
> 	return 0;
> out_mem:
> 	free_page(mem);
> @@ -333,8 +333,8 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
> 	int disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16;
> 	int base2 = (vcpu->arch.sie_block->ipb & 0xf000) >> 12;
> 	int disp2 = vcpu->arch.sie_block->ipb & 0x0fff;
> -	u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0;
> -	u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0;
> +	u64 address1 = disp1 + base1 ? vcpu->run->sync_rw.gprs[base1] : 0;
> +	u64 address2 = disp2 + base2 ? vcpu->run->sync_rw.gprs[base2] : 0;
> 	struct vm_area_struct *vma;
> 	unsigned long user_address;
> 
> diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
> index 0a7941d..b7883ac 100644
> --- a/arch/s390/kvm/sigp.c
> +++ b/arch/s390/kvm/sigp.c
> @@ -48,7 +48,7 @@
> 
> 
> static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
> -			unsigned long *reg)
> +			u64 *reg)

Looks short enough to eliminate the line wrap now :).

> {
> 	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
> 	int rc;
> @@ -220,7 +220,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
> }
> 
> static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
> -			     unsigned long *reg)
> +			     u64 *reg)
> {
> 	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
> 	struct kvm_s390_local_interrupt *li = NULL;
> @@ -278,7 +278,7 @@ out_fi:
> }
> 
> static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
> -				unsigned long *reg)
> +				u64 *reg)
> {
> 	int rc;
> 	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
> @@ -316,7 +316,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
> 	int base2 = vcpu->arch.sie_block->ipb >> 28;
> 	int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
> 	u32 parameter;
> -	u16 cpu_addr = vcpu->arch.guest_gprs[r3];
> +	u16 cpu_addr = vcpu->run->sync_rw.gprs[r3];
> 	u8 order_code;
> 	int rc;
> 
> @@ -327,18 +327,18 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
> 
> 	order_code = disp2;
> 	if (base2)
> -		order_code += vcpu->arch.guest_gprs[base2];
> +		order_code += vcpu->run->sync_rw.gprs[base2];
> 
> 	if (r1 % 2)
> -		parameter = vcpu->arch.guest_gprs[r1];
> +		parameter = vcpu->run->sync_rw.gprs[r1];
> 	else
> -		parameter = vcpu->arch.guest_gprs[r1 + 1];
> +		parameter = vcpu->run->sync_rw.gprs[r1 + 1];
> 
> 	switch (order_code) {
> 	case SIGP_SENSE:
> 		vcpu->stat.instruction_sigp_sense++;
> 		rc = __sigp_sense(vcpu, cpu_addr,
> -				  &vcpu->arch.guest_gprs[r1]);
> +				  &vcpu->run->sync_rw.gprs[r1]);
> 		break;
> 	case SIGP_EXTERNAL_CALL:
> 		vcpu->stat.instruction_sigp_external_call++;
> @@ -363,12 +363,12 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
> 	case SIGP_SET_PREFIX:
> 		vcpu->stat.instruction_sigp_prefix++;
> 		rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
> -				       &vcpu->arch.guest_gprs[r1]);
> +				       &vcpu->run->sync_rw.gprs[r1]);
> 		break;
> 	case SIGP_SENSE_RUNNING:
> 		vcpu->stat.instruction_sigp_sense_running++;
> 		rc = __sigp_sense_running(vcpu, cpu_addr,
> -					  &vcpu->arch.guest_gprs[r1]);
> +					  &vcpu->run->sync_rw.gprs[r1]);
> 		break;
> 	case SIGP_RESTART:
> 		vcpu->stat.instruction_sigp_restart++;
> -- 
> 1.7.8.2
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux