cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ucall.c (1274B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ucall support. A ucall is a "hypercall to userspace".
      4 *
      5 * Copyright (C) 2019 Red Hat, Inc.
      6 */
      7#include "kvm_util.h"
      8
      9void ucall_init(struct kvm_vm *vm, void *arg)
     10{
     11}
     12
     13void ucall_uninit(struct kvm_vm *vm)
     14{
     15}
     16
     17void ucall(uint64_t cmd, int nargs, ...)
     18{
     19	struct ucall uc = {
     20		.cmd = cmd,
     21	};
     22	va_list va;
     23	int i;
     24
     25	nargs = nargs <= UCALL_MAX_ARGS ? nargs : UCALL_MAX_ARGS;
     26
     27	va_start(va, nargs);
     28	for (i = 0; i < nargs; ++i)
     29		uc.args[i] = va_arg(va, uint64_t);
     30	va_end(va);
     31
     32	/* Exit via DIAGNOSE 0x501 (normally used for breakpoints) */
     33	asm volatile ("diag 0,%0,0x501" : : "a"(&uc) : "memory");
     34}
     35
     36uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
     37{
     38	struct kvm_run *run = vcpu_state(vm, vcpu_id);
     39	struct ucall ucall = {};
     40
     41	if (uc)
     42		memset(uc, 0, sizeof(*uc));
     43
     44	if (run->exit_reason == KVM_EXIT_S390_SIEIC &&
     45	    run->s390_sieic.icptcode == 4 &&
     46	    (run->s390_sieic.ipa >> 8) == 0x83 &&    /* 0x83 means DIAGNOSE */
     47	    (run->s390_sieic.ipb >> 16) == 0x501) {
     48		int reg = run->s390_sieic.ipa & 0xf;
     49
     50		memcpy(&ucall, addr_gva2hva(vm, run->s.regs.gprs[reg]),
     51		       sizeof(ucall));
     52
     53		vcpu_run_complete_io(vm, vcpu_id);
     54		if (uc)
     55			memcpy(uc, &ucall, sizeof(ucall));
     56	}
     57
     58	return ucall.cmd;
     59}