xref: /freebsd/lib/libkvm/kvm_amd64.c (revision 8a16b7a18f5d0b031f09832fd7752fba717e2a97)
1f95a0250SRodney W. Grimes /*-
2*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
3*8a16b7a1SPedro F. Giffuni  *
4f95a0250SRodney W. Grimes  * Copyright (c) 1989, 1992, 1993
5f95a0250SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
6f95a0250SRodney W. Grimes  *
7f95a0250SRodney W. Grimes  * This code is derived from software developed by the Computer Systems
8f95a0250SRodney W. Grimes  * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
9f95a0250SRodney W. Grimes  * BG 91-66 and contributed to Berkeley.
10f95a0250SRodney W. Grimes  *
11f95a0250SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
12f95a0250SRodney W. Grimes  * modification, are permitted provided that the following conditions
13f95a0250SRodney W. Grimes  * are met:
14f95a0250SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
15f95a0250SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
16f95a0250SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
17f95a0250SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
18f95a0250SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
19fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
20f95a0250SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
21f95a0250SRodney W. Grimes  *    without specific prior written permission.
22f95a0250SRodney W. Grimes  *
23f95a0250SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24f95a0250SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25f95a0250SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26f95a0250SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27f95a0250SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28f95a0250SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29f95a0250SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30f95a0250SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31f95a0250SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32f95a0250SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33f95a0250SRodney W. Grimes  * SUCH DAMAGE.
34f95a0250SRodney W. Grimes  */
35f95a0250SRodney W. Grimes 
36e67f5b9fSMatthew Dillon #include <sys/cdefs.h>
37e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$");
38e67f5b9fSMatthew Dillon 
39f95a0250SRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint)
40c4a7cdb3SPeter Wemm #if 0
41f95a0250SRodney W. Grimes static char sccsid[] = "@(#)kvm_hp300.c	8.1 (Berkeley) 6/4/93";
42c4a7cdb3SPeter Wemm #endif
43f95a0250SRodney W. Grimes #endif /* LIBC_SCCS and not lint */
44f95a0250SRodney W. Grimes 
45f95a0250SRodney W. Grimes /*
46a1de871dSPeter Wemm  * AMD64 machine dependent routines for kvm.  Hopefully, the forthcoming
47f95a0250SRodney W. Grimes  * vm code will one day obsolete this module.
48f95a0250SRodney W. Grimes  */
49f95a0250SRodney W. Grimes 
50f95a0250SRodney W. Grimes #include <sys/param.h>
517f911abeSJohn Baldwin #include <sys/endian.h>
527f911abeSJohn Baldwin #include <stdint.h>
5351295a4dSJordan K. Hubbard #include <stdlib.h>
54953e4134SEd Schouten #include <string.h>
55f95a0250SRodney W. Grimes #include <unistd.h>
568baaf913SWill Andrews #include <vm/vm.h>
57f95a0250SRodney W. Grimes #include <kvm.h>
58f95a0250SRodney W. Grimes 
59f95a0250SRodney W. Grimes #include <limits.h>
60f95a0250SRodney W. Grimes 
61f95a0250SRodney W. Grimes #include "kvm_private.h"
627f911abeSJohn Baldwin #include "kvm_amd64.h"
63f95a0250SRodney W. Grimes 
64f95a0250SRodney W. Grimes struct vmstate {
657f911abeSJohn Baldwin 	size_t		phnum;
667f911abeSJohn Baldwin 	GElf_Phdr	*phdr;
677f911abeSJohn Baldwin 	amd64_pml4e_t	*PML4;
68f95a0250SRodney W. Grimes };
69f95a0250SRodney W. Grimes 
70e55a0cd8SPeter Wemm /*
71e55a0cd8SPeter Wemm  * Translate a physical memory address to a file-offset in the crash-dump.
72e55a0cd8SPeter Wemm  */
73e55a0cd8SPeter Wemm static size_t
74e55a0cd8SPeter Wemm _kvm_pa2off(kvm_t *kd, uint64_t pa, off_t *ofs)
75e55a0cd8SPeter Wemm {
767f911abeSJohn Baldwin 	struct vmstate *vm = kd->vmst;
777f911abeSJohn Baldwin 	GElf_Phdr *p;
787f911abeSJohn Baldwin 	size_t n;
79e55a0cd8SPeter Wemm 
80d7dc9f76SHidetoshi Shimokawa 	if (kd->rawdump) {
81d7dc9f76SHidetoshi Shimokawa 		*ofs = pa;
827f911abeSJohn Baldwin 		return (AMD64_PAGE_SIZE - (pa & AMD64_PAGE_MASK));
83d7dc9f76SHidetoshi Shimokawa 	}
84d7dc9f76SHidetoshi Shimokawa 
857f911abeSJohn Baldwin 	p = vm->phdr;
867f911abeSJohn Baldwin 	n = vm->phnum;
87e55a0cd8SPeter Wemm 	while (n && (pa < p->p_paddr || pa >= p->p_paddr + p->p_memsz))
88e55a0cd8SPeter Wemm 		p++, n--;
89e55a0cd8SPeter Wemm 	if (n == 0)
90e55a0cd8SPeter Wemm 		return (0);
91e55a0cd8SPeter Wemm 	*ofs = (pa - p->p_paddr) + p->p_offset;
927f911abeSJohn Baldwin 	return (AMD64_PAGE_SIZE - (pa & AMD64_PAGE_MASK));
93e55a0cd8SPeter Wemm }
94e55a0cd8SPeter Wemm 
957f911abeSJohn Baldwin static void
967f911abeSJohn Baldwin _amd64_freevtop(kvm_t *kd)
972f85bf6eSPeter Wemm {
98e55a0cd8SPeter Wemm 	struct vmstate *vm = kd->vmst;
99e55a0cd8SPeter Wemm 
100e55a0cd8SPeter Wemm 	if (vm->PML4)
101e55a0cd8SPeter Wemm 		free(vm->PML4);
1027f911abeSJohn Baldwin 	free(vm->phdr);
103e55a0cd8SPeter Wemm 	free(vm);
104e55a0cd8SPeter Wemm 	kd->vmst = NULL;
10521d54b07SRodney W. Grimes }
106f95a0250SRodney W. Grimes 
1077f911abeSJohn Baldwin static int
1087f911abeSJohn Baldwin _amd64_probe(kvm_t *kd)
1092f85bf6eSPeter Wemm {
110e9ca6fe4SPeter Wemm 
1117f911abeSJohn Baldwin 	return (_kvm_probe_elf_kernel(kd, ELFCLASS64, EM_X86_64) &&
1127f911abeSJohn Baldwin 	    !_kvm_is_minidump(kd));
1137f911abeSJohn Baldwin }
1147f911abeSJohn Baldwin 
1157f911abeSJohn Baldwin static int
1167f911abeSJohn Baldwin _amd64_initvtop(kvm_t *kd)
1177f911abeSJohn Baldwin {
1187f911abeSJohn Baldwin 	struct kvm_nlist nl[2];
1197f911abeSJohn Baldwin 	amd64_physaddr_t pa;
1207f911abeSJohn Baldwin 	kvaddr_t kernbase;
1217f911abeSJohn Baldwin 	amd64_pml4e_t *PML4;
122f95a0250SRodney W. Grimes 
123e55a0cd8SPeter Wemm 	kd->vmst = (struct vmstate *)_kvm_malloc(kd, sizeof(*kd->vmst));
124fb0e1892SEnji Cooper 	if (kd->vmst == NULL) {
12521d54b07SRodney W. Grimes 		_kvm_err(kd, kd->program, "cannot allocate vm");
126f95a0250SRodney W. Grimes 		return (-1);
12721d54b07SRodney W. Grimes 	}
128e55a0cd8SPeter Wemm 	kd->vmst->PML4 = 0;
129e55a0cd8SPeter Wemm 
130d7dc9f76SHidetoshi Shimokawa 	if (kd->rawdump == 0) {
1317f911abeSJohn Baldwin 		if (_kvm_read_core_phdrs(kd, &kd->vmst->phnum,
1327f911abeSJohn Baldwin 		    &kd->vmst->phdr) == -1)
133e55a0cd8SPeter Wemm 			return (-1);
134d7dc9f76SHidetoshi Shimokawa 	}
135f95a0250SRodney W. Grimes 
136c10970ddSUlrich Spörlein 	nl[0].n_name = "kernbase";
137c10970ddSUlrich Spörlein 	nl[1].n_name = 0;
138f85f3040SPeter Wemm 
1397f911abeSJohn Baldwin 	if (kvm_nlist2(kd, nl) != 0) {
140f2b29125SPeter Wemm 		_kvm_err(kd, kd->program, "bad namelist - no kernbase");
141f2b29125SPeter Wemm 		return (-1);
142f2b29125SPeter Wemm 	}
143c10970ddSUlrich Spörlein 	kernbase = nl[0].n_value;
144f85f3040SPeter Wemm 
145c10970ddSUlrich Spörlein 	nl[0].n_name = "KPML4phys";
146c10970ddSUlrich Spörlein 	nl[1].n_name = 0;
147f95a0250SRodney W. Grimes 
1487f911abeSJohn Baldwin 	if (kvm_nlist2(kd, nl) != 0) {
149f2b29125SPeter Wemm 		_kvm_err(kd, kd->program, "bad namelist - no KPML4phys");
150f95a0250SRodney W. Grimes 		return (-1);
151f95a0250SRodney W. Grimes 	}
1527f911abeSJohn Baldwin 	if (kvm_read2(kd, (nl[0].n_value - kernbase), &pa, sizeof(pa)) !=
153f85f3040SPeter Wemm 	    sizeof(pa)) {
154f2b29125SPeter Wemm 		_kvm_err(kd, kd->program, "cannot read KPML4phys");
155f95a0250SRodney W. Grimes 		return (-1);
156f95a0250SRodney W. Grimes 	}
1577f911abeSJohn Baldwin 	pa = le64toh(pa);
1587f911abeSJohn Baldwin 	PML4 = _kvm_malloc(kd, AMD64_PAGE_SIZE);
159fb0e1892SEnji Cooper 	if (PML4 == NULL) {
160fb0e1892SEnji Cooper 		_kvm_err(kd, kd->program, "cannot allocate PML4");
161fb0e1892SEnji Cooper 		return (-1);
162fb0e1892SEnji Cooper 	}
1637f911abeSJohn Baldwin 	if (kvm_read2(kd, pa, PML4, AMD64_PAGE_SIZE) != AMD64_PAGE_SIZE) {
164f2b29125SPeter Wemm 		_kvm_err(kd, kd->program, "cannot read KPML4phys");
1658b4e5ab9SEnji Cooper 		free(PML4);
166f95a0250SRodney W. Grimes 		return (-1);
167f95a0250SRodney W. Grimes 	}
168e55a0cd8SPeter Wemm 	kd->vmst->PML4 = PML4;
169f95a0250SRodney W. Grimes 	return (0);
170f95a0250SRodney W. Grimes }
171f95a0250SRodney W. Grimes 
172f95a0250SRodney W. Grimes static int
1737f911abeSJohn Baldwin _amd64_vatop(kvm_t *kd, kvaddr_t va, off_t *pa)
1742f85bf6eSPeter Wemm {
1752f85bf6eSPeter Wemm 	struct vmstate *vm;
1767f911abeSJohn Baldwin 	amd64_physaddr_t offset;
1777f911abeSJohn Baldwin 	amd64_physaddr_t pdpe_pa;
1787f911abeSJohn Baldwin 	amd64_physaddr_t pde_pa;
1797f911abeSJohn Baldwin 	amd64_physaddr_t pte_pa;
1807f911abeSJohn Baldwin 	amd64_pml4e_t pml4e;
1817f911abeSJohn Baldwin 	amd64_pdpe_t pdpe;
1827f911abeSJohn Baldwin 	amd64_pde_t pde;
1837f911abeSJohn Baldwin 	amd64_pte_t pte;
1847f911abeSJohn Baldwin 	kvaddr_t pml4eindex;
1857f911abeSJohn Baldwin 	kvaddr_t pdpeindex;
1867f911abeSJohn Baldwin 	kvaddr_t pdeindex;
1877f911abeSJohn Baldwin 	kvaddr_t pteindex;
1887f911abeSJohn Baldwin 	amd64_physaddr_t a;
189e55a0cd8SPeter Wemm 	off_t ofs;
190e55a0cd8SPeter Wemm 	size_t s;
1912f85bf6eSPeter Wemm 
1922f85bf6eSPeter Wemm 	vm = kd->vmst;
1937f911abeSJohn Baldwin 	offset = va & AMD64_PAGE_MASK;
1942f85bf6eSPeter Wemm 
1952f85bf6eSPeter Wemm 	/*
1962f85bf6eSPeter Wemm 	 * If we are initializing (kernel page table descriptor pointer
1972f85bf6eSPeter Wemm 	 * not yet set) then return pa == va to avoid infinite recursion.
1982f85bf6eSPeter Wemm 	 */
199fb0e1892SEnji Cooper 	if (vm->PML4 == NULL) {
200e55a0cd8SPeter Wemm 		s = _kvm_pa2off(kd, va, pa);
201e55a0cd8SPeter Wemm 		if (s == 0) {
202e55a0cd8SPeter Wemm 			_kvm_err(kd, kd->program,
2037f911abeSJohn Baldwin 			    "_amd64_vatop: bootstrap data not in dump");
204e55a0cd8SPeter Wemm 			goto invalid;
205e55a0cd8SPeter Wemm 		} else
2067f911abeSJohn Baldwin 			return (AMD64_PAGE_SIZE - offset);
2072f85bf6eSPeter Wemm 	}
2082f85bf6eSPeter Wemm 
2097f911abeSJohn Baldwin 	pml4eindex = (va >> AMD64_PML4SHIFT) & (AMD64_NPML4EPG - 1);
2107f911abeSJohn Baldwin 	pml4e = le64toh(vm->PML4[pml4eindex]);
2117f911abeSJohn Baldwin 	if ((pml4e & AMD64_PG_V) == 0) {
2127f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pml4e not valid");
213f2b29125SPeter Wemm 		goto invalid;
214e55a0cd8SPeter Wemm 	}
215f2b29125SPeter Wemm 
2167f911abeSJohn Baldwin 	pdpeindex = (va >> AMD64_PDPSHIFT) & (AMD64_NPDPEPG - 1);
2177f911abeSJohn Baldwin 	pdpe_pa = (pml4e & AMD64_PG_FRAME) + (pdpeindex * sizeof(amd64_pdpe_t));
218f2b29125SPeter Wemm 
219e55a0cd8SPeter Wemm 	s = _kvm_pa2off(kd, pdpe_pa, &ofs);
2207f911abeSJohn Baldwin 	if (s < sizeof(pdpe)) {
2217f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pdpe_pa not found");
222e55a0cd8SPeter Wemm 		goto invalid;
223e55a0cd8SPeter Wemm 	}
2247f911abeSJohn Baldwin 	if (pread(kd->pmfd, &pdpe, sizeof(pdpe), ofs) != sizeof(pdpe)) {
2257f911abeSJohn Baldwin 		_kvm_syserr(kd, kd->program, "_amd64_vatop: read pdpe");
226f2b29125SPeter Wemm 		goto invalid;
227f2b29125SPeter Wemm 	}
2287f911abeSJohn Baldwin 	pdpe = le64toh(pdpe);
2297f911abeSJohn Baldwin 	if ((pdpe & AMD64_PG_V) == 0) {
2307f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pdpe not valid");
231f2b29125SPeter Wemm 		goto invalid;
232e55a0cd8SPeter Wemm 	}
233f2b29125SPeter Wemm 
2347f911abeSJohn Baldwin 	if (pdpe & AMD64_PG_PS) {
2354afb0d5aSTor Egge 		/*
2367f911abeSJohn Baldwin 		 * No next-level page table; pdpe describes one 1GB page.
2374afb0d5aSTor Egge 		 */
238ad3ecc20SJohn Baldwin 		a = (pdpe & AMD64_PG_1GB_FRAME) + (va & AMD64_PDPMASK);
239e55a0cd8SPeter Wemm 		s = _kvm_pa2off(kd, a, pa);
240e55a0cd8SPeter Wemm 		if (s == 0) {
241e55a0cd8SPeter Wemm 			_kvm_err(kd, kd->program,
2427f911abeSJohn Baldwin 			    "_amd64_vatop: 1GB page address not in dump");
243e55a0cd8SPeter Wemm 			goto invalid;
244e55a0cd8SPeter Wemm 		} else
2457f911abeSJohn Baldwin 			return (AMD64_NBPDP - (va & AMD64_PDPMASK));
2464afb0d5aSTor Egge 	}
2474afb0d5aSTor Egge 
2487f911abeSJohn Baldwin 	pdeindex = (va >> AMD64_PDRSHIFT) & (AMD64_NPDEPG - 1);
2497f911abeSJohn Baldwin 	pde_pa = (pdpe & AMD64_PG_FRAME) + (pdeindex * sizeof(amd64_pde_t));
2502f85bf6eSPeter Wemm 
2517f911abeSJohn Baldwin 	s = _kvm_pa2off(kd, pde_pa, &ofs);
2527f911abeSJohn Baldwin 	if (s < sizeof(pde)) {
2537f911abeSJohn Baldwin 		_kvm_syserr(kd, kd->program, "_amd64_vatop: pde_pa not found");
254e55a0cd8SPeter Wemm 		goto invalid;
255e55a0cd8SPeter Wemm 	}
2567f911abeSJohn Baldwin 	if (pread(kd->pmfd, &pde, sizeof(pde), ofs) != sizeof(pde)) {
2577f911abeSJohn Baldwin 		_kvm_syserr(kd, kd->program, "_amd64_vatop: read pde");
2582f85bf6eSPeter Wemm 		goto invalid;
2592f85bf6eSPeter Wemm 	}
2607f911abeSJohn Baldwin 	pde = le64toh(pde);
2617f911abeSJohn Baldwin 	if ((pde & AMD64_PG_V) == 0) {
2627f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pde not valid");
2632f85bf6eSPeter Wemm 		goto invalid;
264e55a0cd8SPeter Wemm 	}
2652f85bf6eSPeter Wemm 
2667f911abeSJohn Baldwin 	if (pde & AMD64_PG_PS) {
2677f911abeSJohn Baldwin 		/*
2687f911abeSJohn Baldwin 		 * No final-level page table; pde describes one 2MB page.
2697f911abeSJohn Baldwin 		 */
2707f911abeSJohn Baldwin 		a = (pde & AMD64_PG_PS_FRAME) + (va & AMD64_PDRMASK);
271e55a0cd8SPeter Wemm 		s = _kvm_pa2off(kd, a, pa);
272e55a0cd8SPeter Wemm 		if (s == 0) {
2737f911abeSJohn Baldwin 			_kvm_err(kd, kd->program,
2747f911abeSJohn Baldwin 			    "_amd64_vatop: 2MB page address not in dump");
275e55a0cd8SPeter Wemm 			goto invalid;
276e55a0cd8SPeter Wemm 		} else
2777f911abeSJohn Baldwin 			return (AMD64_NBPDR - (va & AMD64_PDRMASK));
2787f911abeSJohn Baldwin 	}
2797f911abeSJohn Baldwin 
2807f911abeSJohn Baldwin 	pteindex = (va >> AMD64_PAGE_SHIFT) & (AMD64_NPTEPG - 1);
2817f911abeSJohn Baldwin 	pte_pa = (pde & AMD64_PG_FRAME) + (pteindex * sizeof(amd64_pte_t));
2827f911abeSJohn Baldwin 
2837f911abeSJohn Baldwin 	s = _kvm_pa2off(kd, pte_pa, &ofs);
2847f911abeSJohn Baldwin 	if (s < sizeof(pte)) {
2857f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pte_pa not found");
2867f911abeSJohn Baldwin 		goto invalid;
2877f911abeSJohn Baldwin 	}
2887f911abeSJohn Baldwin 	if (pread(kd->pmfd, &pte, sizeof(pte), ofs) != sizeof(pte)) {
2897f911abeSJohn Baldwin 		_kvm_syserr(kd, kd->program, "_amd64_vatop: read");
2907f911abeSJohn Baldwin 		goto invalid;
2917f911abeSJohn Baldwin 	}
2927f911abeSJohn Baldwin 	if ((pte & AMD64_PG_V) == 0) {
2937f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: pte not valid");
2947f911abeSJohn Baldwin 		goto invalid;
2957f911abeSJohn Baldwin 	}
2967f911abeSJohn Baldwin 
2977f911abeSJohn Baldwin 	a = (pte & AMD64_PG_FRAME) + offset;
2987f911abeSJohn Baldwin 	s = _kvm_pa2off(kd, a, pa);
2997f911abeSJohn Baldwin 	if (s == 0) {
3007f911abeSJohn Baldwin 		_kvm_err(kd, kd->program, "_amd64_vatop: address not in dump");
3017f911abeSJohn Baldwin 		goto invalid;
3027f911abeSJohn Baldwin 	} else
3037f911abeSJohn Baldwin 		return (AMD64_PAGE_SIZE - offset);
3042f85bf6eSPeter Wemm 
3052f85bf6eSPeter Wemm invalid:
3067f911abeSJohn Baldwin 	_kvm_err(kd, 0, "invalid address (0x%jx)", (uintmax_t)va);
3072f85bf6eSPeter Wemm 	return (0);
308f95a0250SRodney W. Grimes }
309f95a0250SRodney W. Grimes 
3107f911abeSJohn Baldwin static int
3117f911abeSJohn Baldwin _amd64_kvatop(kvm_t *kd, kvaddr_t va, off_t *pa)
3122f85bf6eSPeter Wemm {
313e55a0cd8SPeter Wemm 
314e55a0cd8SPeter Wemm 	if (ISALIVE(kd)) {
315e55a0cd8SPeter Wemm 		_kvm_err(kd, 0, "kvm_kvatop called in live kernel!");
316e55a0cd8SPeter Wemm 		return (0);
317e55a0cd8SPeter Wemm 	}
3187f911abeSJohn Baldwin 	return (_amd64_vatop(kd, va, pa));
319f95a0250SRodney W. Grimes }
3207f911abeSJohn Baldwin 
3217f911abeSJohn Baldwin int
322881b0edbSEnji Cooper _amd64_native(kvm_t *kd __unused)
3237f911abeSJohn Baldwin {
3247f911abeSJohn Baldwin 
3257f911abeSJohn Baldwin #ifdef __amd64__
3267f911abeSJohn Baldwin 	return (1);
3277f911abeSJohn Baldwin #else
3287f911abeSJohn Baldwin 	return (0);
3297f911abeSJohn Baldwin #endif
3307f911abeSJohn Baldwin }
3317f911abeSJohn Baldwin 
332881b0edbSEnji Cooper static struct kvm_arch kvm_amd64 = {
3337f911abeSJohn Baldwin 	.ka_probe = _amd64_probe,
3347f911abeSJohn Baldwin 	.ka_initvtop = _amd64_initvtop,
3357f911abeSJohn Baldwin 	.ka_freevtop = _amd64_freevtop,
3367f911abeSJohn Baldwin 	.ka_kvatop = _amd64_kvatop,
3377f911abeSJohn Baldwin 	.ka_native = _amd64_native,
3387f911abeSJohn Baldwin };
3397f911abeSJohn Baldwin 
3407f911abeSJohn Baldwin KVM_ARCH(kvm_amd64);
341