Module Name: src Committed By: bouyer Date: Tue Apr 21 16:57:40 UTC 2020
Modified Files: src/sys/arch/xen/xen [bouyer-xenpvh]: xengnt.c Log Message: It is possible to use grant_v2 with HVM guest; but the status table has to be mapped using XENMEM_add_to_physmap. To generate a diff of this commit: cvs rdiff -u -r1.29.2.2 -r1.29.2.3 src/sys/arch/xen/xen/xengnt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/xen/xen/xengnt.c diff -u src/sys/arch/xen/xen/xengnt.c:1.29.2.2 src/sys/arch/xen/xen/xengnt.c:1.29.2.3 --- src/sys/arch/xen/xen/xengnt.c:1.29.2.2 Mon Apr 20 19:42:10 2020 +++ src/sys/arch/xen/xen/xengnt.c Tue Apr 21 16:57:40 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: xengnt.c,v 1.29.2.2 2020/04/20 19:42:10 bouyer Exp $ */ +/* $NetBSD: xengnt.c,v 1.29.2.3 2020/04/21 16:57:40 bouyer Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.29.2.2 2020/04/20 19:42:10 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.29.2.3 2020/04/21 16:57:40 bouyer Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -44,16 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1 #include "opt_xen.h" -/* - * grant table v2 is not supported for HVM guests on 4.11 at last. - * see xen/arch/x86/hvm/hypercall.c in Xen sources (missing - * GNTTABOP_get_status_frames) - */ - -#ifdef XENPV -#define USE_GRANT_V2 -#endif - /* #define XENDEBUG */ #ifdef XENDEBUG #define DPRINTF(x) printf x @@ -77,7 +67,6 @@ int last_gnt_entry; #define XENGNT_NO_ENTRY 0xffffffff /* VM address of the grant table */ -#ifdef USE_GRANT_V2 #define NR_GRANT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v2_t)) #define NR_GRANT_STATUS_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t)) @@ -86,10 +75,6 @@ grant_entry_v2_t *grant_table; int gnt_status_frames; grant_status_t *grant_status; -#else /* USE_GRANT_V2 */ -#define NR_GRANT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_v1_t)) -grant_entry_v1_t *grant_table; -#endif /* USE_GRANT_V2 */ kmutex_t grant_lock; static grant_ref_t xengnt_get_entry(void); @@ -118,13 +103,11 @@ xengnt_init(void) gnt_nr_grant_frames = gnt_max_grant_frames; -#ifdef USE_GRANT_V2 struct gnttab_set_version gntversion; gntversion.version = 2; rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gntversion, 1); if (rc < 0 || gntversion.version != 2) panic("GNTTABOP_set_version 2 failed %d", rc); -#endif /* USE_GRANT_V2 */ nr_grant_entries = gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE; @@ -139,14 +122,12 @@ xengnt_init(void) for (i = 0; i <= nr_grant_entries; i++) gnt_entries[i] = XENGNT_NO_ENTRY; -#ifdef USE_GRANT_V2 gnt_status_frames = round_page(nr_grant_entries * sizeof(grant_status_t)) / PAGE_SIZE; grant_status = (void *)uvm_km_alloc(kernel_map, gnt_status_frames * PAGE_SIZE, 0, UVM_KMF_VAONLY); if (grant_status == NULL) panic("xengnt_init() status no VM space"); -#endif /* USE_GRANT_V2 */ mutex_init(&grant_lock, MUTEX_DEFAULT, IPL_VM); @@ -194,10 +175,8 @@ xengnt_suspend(void) { /* Remove virtual => machine mapping for grant table */ pmap_kremove((vaddr_t)grant_table, gnt_nr_grant_frames * PAGE_SIZE); -#ifdef USE_GRANT_V2 /* Remove virtual => machine mapping for status table */ pmap_kremove((vaddr_t)grant_status, gnt_status_frames * PAGE_SIZE); -#endif pmap_update(pmap_kernel()); mutex_exit(&grant_lock); @@ -210,12 +189,8 @@ xengnt_suspend(void) { static int xengnt_map_status(void) { -#ifdef USE_GRANT_V2 - gnttab_get_status_frames_t getstatus; uint64_t *pages; size_t sz; - int err; - KASSERT(mutex_owned(&grant_lock)); sz = gnt_status_frames * sizeof(*pages); @@ -223,6 +198,10 @@ xengnt_map_status(void) if (pages == NULL) return ENOMEM; +#ifdef XENPV + gnttab_get_status_frames_t getstatus; + int err; + getstatus.dom = DOMID_SELF; getstatus.nr_frames = gnt_status_frames; set_xen_guest_handle(getstatus.frame_list, pages); @@ -240,7 +219,23 @@ xengnt_map_status(void) kmem_free(pages, sz); return ENOMEM; } +#else /* XENPV */ + for (int i = 0; i < gnt_status_frames; i++) { + struct vm_page *pg; + struct xen_add_to_physmap xmap; + + pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); + pages[i] = atop(uvm_vm_page_to_phys(pg)); + + xmap.domid = DOMID_SELF; + xmap.space = XENMAPSPACE_grant_table; + xmap.idx = i | XENMAPIDX_grant_table_status; + xmap.gpfn = pages[i]; + if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) + panic("%s: Unable to add grant tables\n", __func__); + } +#endif /* XENPV */ /* * map between status_table addresses and the machine addresses of * the status table frames @@ -253,8 +248,6 @@ xengnt_map_status(void) pmap_update(pmap_kernel()); kmem_free(pages, sz); - -#endif /* USE_GRANT_V2 */ return 0; } @@ -298,7 +291,7 @@ xengnt_more_entries(void) xmap.gpfn = pages[gnt_nr_grant_frames]; if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xmap) < 0) - panic("%s: Unable to register HYPERVISOR_shared_info\n", __func__); + panic("%s: Unable to add grant frames\n", __func__); } else { setup.dom = DOMID_SELF; @@ -398,7 +391,6 @@ xengnt_free_entry(grant_ref_t entry) mutex_exit(&grant_lock); } -#ifdef USE_GRANT_V2 int xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp) { @@ -451,67 +443,3 @@ xengnt_status(grant_ref_t entry) { return grant_status[entry] & (GTF_reading|GTF_writing); } -#else /* USE_GRANT_V2 */ - -int -xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp) -{ - mutex_enter(&grant_lock); - - *entryp = xengnt_get_entry(); - if (__predict_false(*entryp == XENGNT_NO_ENTRY)) { - mutex_exit(&grant_lock); - return ENOMEM; - } - - grant_table[*entryp].frame = ma >> PAGE_SHIFT; - grant_table[*entryp].domid = dom; - /* - * ensure that the above values reach global visibility - * before permitting frame's access (done when we set flags) - */ - xen_rmb(); - grant_table[*entryp].flags = - GTF_permit_access | (ro ? GTF_readonly : 0); - mutex_exit(&grant_lock); - return 0; -} - - -static inline uint16_t -xen_atomic_cmpxchg16(volatile uint16_t *ptr, uint16_t val, uint16_t newval) -{ - unsigned long result; - - __asm volatile(__LOCK_PREFIX - "cmpxchgw %w1,%2" - :"=a" (result) - :"q"(newval), "m" (*ptr), "0" (val) - :"memory"); - - return result; -} - -void -xengnt_revoke_access(grant_ref_t entry) -{ - - uint16_t flags, nflags; - - nflags = grant_table[entry].flags; - - do { - if ((flags = nflags) & (GTF_reading|GTF_writing)) - panic("xengnt_revoke_access: still in use"); - nflags = xen_atomic_cmpxchg16(&grant_table[entry].flags, - flags, 0); - } while (nflags != flags); - xengnt_free_entry(entry); -} - -int -xengnt_status(grant_ref_t entry) -{ - return (grant_table[entry].flags & (GTF_reading|GTF_writing)); -} -#endif /* USE_GRANT_V2 */