Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  ucall_common.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
#include "linux/types.h"
#include "linux/bitmap.h"
#include "linux/atomic.h"

#include "kvm_util.h"
#include "ucall_common.h"


#define GUEST_UCALL_FAILED -1

struct ucall_header {
 DECLARE_BITMAP(in_use, KVM_MAX_VCPUS);
 struct ucall ucalls[KVM_MAX_VCPUS];
};

int ucall_nr_pages_required(uint64_t page_size)
{
 return align_up(sizeof(struct ucall_header), page_size) / page_size;
}

/*
 * ucall_pool holds per-VM values (global data is duplicated by each VM), it
 * must not be accessed from host code.
 */

static struct ucall_header *ucall_pool;

void ucall_init(struct kvm_vm *vm, vm_paddr_t mmio_gpa)
{
 struct ucall_header *hdr;
 struct ucall *uc;
 vm_vaddr_t vaddr;
 int i;

 vaddr = vm_vaddr_alloc_shared(vm, sizeof(*hdr), KVM_UTIL_MIN_VADDR,
          MEM_REGION_DATA);
 hdr = (struct ucall_header *)addr_gva2hva(vm, vaddr);
 memset(hdr, 0, sizeof(*hdr));

 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
  uc = &hdr->ucalls[i];
  uc->hva = uc;
 }

 write_guest_global(vm, ucall_pool, (struct ucall_header *)vaddr);

 ucall_arch_init(vm, mmio_gpa);
}

static struct ucall *ucall_alloc(void)
{
 struct ucall *uc;
 int i;

 if (!ucall_pool)
  goto ucall_failed;

 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
  if (!test_and_set_bit(i, ucall_pool->in_use)) {
   uc = &ucall_pool->ucalls[i];
   memset(uc->args, 0, sizeof(uc->args));
   return uc;
  }
 }

ucall_failed:
 /*
 * If the vCPU cannot grab a ucall structure, make a bare ucall with a
 * magic value to signal to get_ucall() that things went sideways.
 * GUEST_ASSERT() depends on ucall_alloc() and so cannot be used here.
 */

 ucall_arch_do_ucall(GUEST_UCALL_FAILED);
 return NULL;
}

static void ucall_free(struct ucall *uc)
{
 /* Beware, here be pointer arithmetic.  */
 clear_bit(uc - ucall_pool->ucalls, ucall_pool->in_use);
}

void ucall_assert(uint64_t cmd, const char *exp, const char *file,
    unsigned int line, const char *fmt, ...)
{
 struct ucall *uc;
 va_list va;

 uc = ucall_alloc();
 uc->cmd = cmd;

 WRITE_ONCE(uc->args[GUEST_ERROR_STRING], (uint64_t)(exp));
 WRITE_ONCE(uc->args[GUEST_FILE], (uint64_t)(file));
 WRITE_ONCE(uc->args[GUEST_LINE], line);

 va_start(va, fmt);
 guest_vsnprintf(uc->buffer, UCALL_BUFFER_LEN, fmt, va);
 va_end(va);

 ucall_arch_do_ucall((vm_vaddr_t)uc->hva);

 ucall_free(uc);
}

void ucall_fmt(uint64_t cmd, const char *fmt, ...)
{
 struct ucall *uc;
 va_list va;

 uc = ucall_alloc();
 uc->cmd = cmd;

 va_start(va, fmt);
 guest_vsnprintf(uc->buffer, UCALL_BUFFER_LEN, fmt, va);
 va_end(va);

 ucall_arch_do_ucall((vm_vaddr_t)uc->hva);

 ucall_free(uc);
}

void ucall(uint64_t cmd, int nargs, ...)
{
 struct ucall *uc;
 va_list va;
 int i;

 uc = ucall_alloc();

 WRITE_ONCE(uc->cmd, cmd);

 nargs = min(nargs, UCALL_MAX_ARGS);

 va_start(va, nargs);
 for (i = 0; i < nargs; ++i)
  WRITE_ONCE(uc->args[i], va_arg(va, uint64_t));
 va_end(va);

 ucall_arch_do_ucall((vm_vaddr_t)uc->hva);

 ucall_free(uc);
}

uint64_t get_ucall(struct kvm_vcpu *vcpu, struct ucall *uc)
{
 struct ucall ucall;
 void *addr;

 if (!uc)
  uc = &ucall;

 addr = ucall_arch_get_ucall(vcpu);
 if (addr) {
  TEST_ASSERT(addr != (void *)GUEST_UCALL_FAILED,
       "Guest failed to allocate ucall struct");

  memcpy(uc, addr, sizeof(*uc));
  vcpu_run_complete_io(vcpu);
 } else {
  memset(uc, 0, sizeof(*uc));
 }

 return uc->cmd;
}

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge