static void kvm_set_status(struct virtio_device *vdev, u8 status) { BUG_ON(!status); to_kvmdev(vdev)->desc->status = status; kvm_hypercall1(KVM_S390_VIRTIO_SET_STATUS, (unsigned long) to_kvmdev(vdev)->desc); }
/*G:035 * Notice the lazy_hcall() above, rather than hcall(). This is our first real * optimization trick! * * When lazy_mode is set, it means we're allowed to defer all hypercalls and do * them as a batch when lazy_mode is eventually turned off. Because hypercalls * are reasonably expensive, batching them up makes sense. For example, a * large munmap might update dozens of page table entries: that code calls * paravirt_enter_lazy_mmu(), does the dozen updates, then calls * lguest_leave_lazy_mode(). * * So, when we're in lazy mode, we call async_hcall() to store the call for * future processing: */ static void lazy_hcall1(unsigned long call, unsigned long arg1) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) kvm_hypercall1(call, arg1); else async_hcall(call, arg1, 0, 0, 0); }
/* code for early console output with virtio_console */ static __init int early_put_chars(u32 vtermno, const char *buf, int count) { char scratch[17]; unsigned int len = count; if (len > sizeof(scratch) - 1) len = sizeof(scratch) - 1; scratch[len] = '\0'; memcpy(scratch, buf, len); kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch)); return len; }
/* * We will eventually use the virtio console device to produce console output, * but before that is set up we use LHCALL_NOTIFY on normal memory to produce * console output. */ static __init int early_put_chars(u32 vtermno, const char *buf, int count) { char scratch[17]; unsigned int len = count; /* We use a nul-terminated string, so we make a copy. Icky, huh? */ if (len > sizeof(scratch) - 1) len = sizeof(scratch) - 1; scratch[len] = '\0'; memcpy(scratch, buf, len); kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); /* This routine returns the number of bytes actually written. */ return len; }
/* * We also need a "struct clock_event_device": Linux asks us to set it to go * off some time in the future. Actually, James Morris figured all this out, I * just applied the patch. */ static int lguest_clockevent_set_next_event(unsigned long delta, struct clock_event_device *evt) { /* FIXME: I don't think this can ever happen, but James tells me he had * to put this code in. Maybe we should remove it now. Anyone? */ if (delta < LG_CLOCK_MIN_DELTA) { if (printk_ratelimit()) printk(KERN_DEBUG "%s: small delta %lu ns\n", __func__, delta); return -ETIME; } /* Please wake us this far in the future. */ kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); return 0; }
/* * When the virtio_ring code wants to notify the Host, it calls us here and we * make a hypercall. We hand the address of the virtqueue so the Host * knows which virtqueue we're talking about. */ static void kvm_notify(struct virtqueue *vq) { struct kvm_vqconfig *config = vq->priv; kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address); }
/* * To reset the device, we use the KVM_VIRTIO_RESET hypercall, using the * descriptor address. The Host will zero the status and all the * features. */ static void kvm_reset(struct virtio_device *vdev) { kvm_hypercall1(KVM_S390_VIRTIO_RESET, (unsigned long) to_kvmdev(vdev)->desc); }