Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libkvm/kvm_vnet.c
Show All 37 Lines | |||||
#include <sys/_mutex.h> | #include <sys/_mutex.h> | ||||
#include <sys/_task.h> | #include <sys/_task.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <nlist.h> | |||||
#include <kvm.h> | #include <kvm.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "kvm_private.h" | #include "kvm_private.h" | ||||
/* | /* | ||||
* Set up libkvm to handle virtual network stack symbols by selecting a | * Set up libkvm to handle virtual network stack symbols by selecting a | ||||
* starting pid. | * starting pid. | ||||
*/ | */ | ||||
int | int | ||||
_kvm_vnet_selectpid(kvm_t *kd, pid_t pid) | _kvm_vnet_selectpid(kvm_t *kd, pid_t pid) | ||||
{ | { | ||||
struct proc proc; | struct proc proc; | ||||
struct ucred cred; | struct ucred cred; | ||||
struct prison prison; | struct prison prison; | ||||
struct vnet vnet; | struct vnet vnet; | ||||
struct nlist nl[] = { | struct kvm_nlist nl[] = { | ||||
/* | /* | ||||
* Note: kvm_nlist strips the first '_' so add an extra one | * Note: kvm_nlist strips the first '_' so add an extra one | ||||
* here to __{start,stop}_set_vnet. | * here to __{start,stop}_set_vnet. | ||||
*/ | */ | ||||
#define NLIST_START_VNET 0 | #define NLIST_START_VNET 0 | ||||
{ .n_name = "___start_" VNET_SETNAME }, | { .n_name = "___start_" VNET_SETNAME }, | ||||
#define NLIST_STOP_VNET 1 | #define NLIST_STOP_VNET 1 | ||||
{ .n_name = "___stop_" VNET_SETNAME }, | { .n_name = "___stop_" VNET_SETNAME }, | ||||
Show All 11 Lines | |||||
#define VMCORE_VNET_OF_PROC0 | #define VMCORE_VNET_OF_PROC0 | ||||
#ifndef VMCORE_VNET_OF_PROC0 | #ifndef VMCORE_VNET_OF_PROC0 | ||||
struct thread td; | struct thread td; | ||||
uintptr_t tdp; | uintptr_t tdp; | ||||
#endif | #endif | ||||
lwpid_t dumptid; | lwpid_t dumptid; | ||||
/* | /* | ||||
* XXX: This only works for native kernels for now. | |||||
*/ | |||||
if (!kvm_native(kd)) | |||||
return (-1); | |||||
/* | |||||
* Locate and cache locations of important symbols | * Locate and cache locations of important symbols | ||||
* using the internal version of _kvm_nlist, turning | * using the internal version of _kvm_nlist, turning | ||||
* off initialization to avoid recursion in case of | * off initialization to avoid recursion in case of | ||||
* unresolveable symbols. | * unresolveable symbols. | ||||
*/ | */ | ||||
if (_kvm_nlist(kd, nl, 0) != 0) { | if (_kvm_nlist(kd, nl, 0) != 0) { | ||||
/* | /* | ||||
* XXX-BZ: ___start_/___stop_VNET_SETNAME may fail. | * XXX-BZ: ___start_/___stop_VNET_SETNAME may fail. | ||||
▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | #endif | ||||
kd->vnet_stop = nl[NLIST_STOP_VNET].n_value; | kd->vnet_stop = nl[NLIST_STOP_VNET].n_value; | ||||
kd->vnet_current = (uintptr_t)prison.pr_vnet; | kd->vnet_current = (uintptr_t)prison.pr_vnet; | ||||
kd->vnet_base = vnet.vnet_data_base; | kd->vnet_base = vnet.vnet_data_base; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Check whether the vnet module has been initialized sucessfully | * Check whether the vnet module has been initialized sucessfully | ||||
* or not, intialize it if permitted. | * or not, initialize it if permitted. | ||||
*/ | */ | ||||
int | int | ||||
_kvm_vnet_initialized(kvm_t *kd, int intialize) | _kvm_vnet_initialized(kvm_t *kd, int intialize) | ||||
{ | { | ||||
if (kd->vnet_initialized || !intialize) | if (kd->vnet_initialized || !intialize) | ||||
return (kd->vnet_initialized); | return (kd->vnet_initialized); | ||||
(void) _kvm_vnet_selectpid(kd, getpid()); | (void) _kvm_vnet_selectpid(kd, getpid()); | ||||
return (kd->vnet_initialized); | return (kd->vnet_initialized); | ||||
} | } | ||||
/* | /* | ||||
* Check whether the value is within the vnet symbol range and | * Check whether the value is within the vnet symbol range and | ||||
* only if so adjust the offset relative to the current base. | * only if so adjust the offset relative to the current base. | ||||
*/ | */ | ||||
uintptr_t | kvaddr_t | ||||
_kvm_vnet_validaddr(kvm_t *kd, uintptr_t value) | _kvm_vnet_validaddr(kvm_t *kd, kvaddr_t value) | ||||
{ | { | ||||
if (value == 0) | if (value == 0) | ||||
return (value); | return (value); | ||||
if (!kd->vnet_initialized) | if (!kd->vnet_initialized) | ||||
return (value); | return (value); | ||||
if (value < kd->vnet_start || value >= kd->vnet_stop) | if (value < kd->vnet_start || value >= kd->vnet_stop) | ||||
return (value); | return (value); | ||||
return (kd->vnet_base + value); | return (kd->vnet_base + value); | ||||
} | } |