This commit is contained in:
emellor@leeni.uk.xensource.com committed 2006-03-03 15:56:34 +01:00
commit 39dbaabab7
27 files changed
+491 -460

No files matched your search

+97
View File
@@ -1059,6 +1059,21 @@ This path contains:
\item[domain] the name of the frontend
\end{description}
\end{description}
\item[vtpm/] a directory containin vtpm backends
\begin{description}
\item[$<$domid$>$/] a directory containing vtpm's for domid
\begin{description}
\item[$<$vtpm number$>$/] a directory for each vtpm
\item[frontend-id] the domain id of the frontend
\item[frontend] the path to the frontend
\item[instance] the instance of the virtual TPM that is used
\item[pref{\textunderscore}instance] the instance number as given in the VM configuration file;
may be different from {\bf instance}
\item[domain] the name of the domain of the frontend
\end{description}
\end{description}
\end{description}
\item[device/] a directory containing the frontend devices for the
@@ -1094,6 +1109,18 @@ This path contains:
\item[event-channel] the event channel used for the two ring queues
\end{description}
\end{description}
\item[vtpm/] a directory containing the vtpm frontend device for the
domain
\begin{description}
\item[$<$id$>$] a directory for vtpm id frontend device for the domain
\begin{description}
\item[backend-id] the backend domain id
\item[backend] a path to the backend's store entry
\item[ring-ref] the grant table reference for the tx/rx ring
\item[event-channel] the event channel used for the ring
\end{description}
\end{description}
\item[device-misc/] miscellanous information for devices
\begin{description}
@@ -1450,6 +1477,76 @@ The fields are as follows:
value of {\tt first\_sect}.
\end{description}
\section{Virtual TPM}
Virtual TPM (VTPM) support provides TPM functionality to each virtual
machine that requests this functionality in its configuration file.
The interface enables domains to access therr own private TPM like it
was a hardware TPM built into the machine.
The virtual TPM interface is implemented as a split driver,
similar to the network and block interfaces described above.
The user domain hosting the frontend exports a character device /dev/tpm0
to user-level applications for communicating with the virtual TPM.
This is the same device interface that is also offered if a hardware TPM
is available in the system. The backend provides a single interface
/dev/vtpm where the virtual TPM is waiting for commands from all domains
that have located their backend in a given domain.
\subsection{Data Transfer}
A single shared memory ring is used between the frontend and backend
drivers. TPM requests and responses are sent in pages where a pointer
to those pages and other information is placed into the ring such that
the backend can map the pages into its memory space using the grant
table mechanism.
The backend driver has been implemented to only accept well-formed
TPM requests. To meet this requirement, the length inidicator in the
TPM request must correctly indicate the length of the request.
Otherwise an error message is automatically sent back by the device driver.
The virtual TPM implementation listenes for TPM request on /dev/vtpm. Since
it must be able to apply the TPM request packet to the virtual TPM instance
associated with the virtual machine, a 4-byte virtual TPM instance
identifier is prepended to each packet by the backend driver (in network
byte order) for internal routing of the request.
\subsection{Virtual TPM ring interface}
The TPM protocol is a strict request/response protocol and therefore
only one ring is used to send requests from the frontend to the backend
and responses on the reverse path.
The request/response structure is defined as follows:
\scriptsize
\begin{verbatim}
typedef struct {
unsigned long addr; /* Machine address of packet. */
grant_ref_t ref; /* grant table access reference. */
uint16_t unused; /* unused */
uint16_t size; /* Packet size in bytes. */
} tpmif_tx_request_t;
\end{verbatim}
\normalsize
The fields are as follows:
\begin{description}
\item[addr] The machine address of the page asscoiated with the TPM
request/response; a request/response may span multiple
pages
\item[ref] The grant table reference associated with the address.
\item[size] The size of the remaining packet; up to
PAGE{\textunderscore}SIZE bytes can be found in the
page referenced by 'addr'
\end{description}
The frontend initially allocates several pages whose addresses
are stored in the ring. Only these pages are used for exchange of
requests and responses.
\chapter{Further Information}
@@ -61,8 +61,8 @@ static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
int ret;
op.cmd = PHYSDEVOP_APIC_READ;
op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
op.u.apic_op.offset = reg;
op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
op.u.apic_op.reg = reg;
ret = HYPERVISOR_physdev_op(&op);
if (ret)
return ret;
@@ -74,8 +74,8 @@ static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsign
physdev_op_t op;
op.cmd = PHYSDEVOP_APIC_WRITE;
op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
op.u.apic_op.offset = reg;
op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
op.u.apic_op.reg = reg;
op.u.apic_op.value = value;
HYPERVISOR_physdev_op(&op);
}
@@ -108,8 +108,8 @@ static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
int ret;
op.cmd = PHYSDEVOP_APIC_READ;
op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
op.u.apic_op.offset = reg;
op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
op.u.apic_op.reg = reg;
ret = HYPERVISOR_physdev_op(&op);
if (ret)
return ret;
@@ -121,8 +121,8 @@ static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsign
physdev_op_t op;
op.cmd = PHYSDEVOP_APIC_WRITE;
op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid;
op.u.apic_op.offset = reg;
op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
op.u.apic_op.reg = reg;
op.u.apic_op.value = value;
HYPERVISOR_physdev_op(&op);
}
@@ -19,8 +19,7 @@ int num_frontends = 0;
LIST_HEAD(tpmif_list);
tpmif_t *
alloc_tpmif(domid_t domid, long int instance)
static tpmif_t *alloc_tpmif(domid_t domid, long int instance)
{
struct page *page;
tpmif_t *tpmif;
@@ -45,16 +44,14 @@ alloc_tpmif(domid_t domid, long int instance)
return tpmif;
}
void
free_tpmif(tpmif_t * tpmif)
static void free_tpmif(tpmif_t * tpmif)
{
num_frontends--;
list_del(&tpmif->tpmif_list);
kmem_cache_free(tpmif_cachep, tpmif);
}
tpmif_t *
tpmif_find(domid_t domid, long int instance)
tpmif_t *tpmif_find(domid_t domid, long int instance)
{
tpmif_t *tpmif;
@@ -72,8 +69,7 @@ tpmif_find(domid_t domid, long int instance)
return alloc_tpmif(domid, instance);
}
static int
map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
{
int ret;
struct gnttab_map_grant_ref op = {
@@ -99,8 +95,7 @@ map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
return 0;
}
static void
unmap_frontend_page(tpmif_t *tpmif)
static void unmap_frontend_page(tpmif_t *tpmif)
{
struct gnttab_unmap_grant_ref op;
int ret;
@@ -115,14 +110,14 @@ unmap_frontend_page(tpmif_t *tpmif)
BUG_ON(ret);
}
int
tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
{
int err;
evtchn_op_t op = {
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.remote_dom = tpmif->domid,
.u.bind_interdomain.remote_port = evtchn };
.u.bind_interdomain.remote_port = evtchn,
};
if (tpmif->irq) {
return 0;
@@ -156,8 +151,7 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
return 0;
}
static void
__tpmif_disconnect_complete(void *arg)
static void __tpmif_disconnect_complete(void *arg)
{
tpmif_t *tpmif = (tpmif_t *) arg;
@@ -172,22 +166,19 @@ __tpmif_disconnect_complete(void *arg)
free_tpmif(tpmif);
}
void
tpmif_disconnect_complete(tpmif_t * tpmif)
void tpmif_disconnect_complete(tpmif_t * tpmif)
{
INIT_WORK(&tpmif->work, __tpmif_disconnect_complete, (void *)tpmif);
schedule_work(&tpmif->work);
}
void __init
tpmif_interface_init(void)
void __init tpmif_interface_init(void)
{
tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
0, 0, NULL, NULL);
}
void __init
tpmif_interface_exit(void)
void __init tpmif_interface_exit(void)
{
kmem_cache_destroy(tpmif_cachep);
}
File diff suppressed because it is too large. Load diff
@@ -602,7 +602,6 @@ tpm_xmit(struct tpm_private *tp,
tx = &tp->tx->ring[i].req;
tx->id = i;
tx->addr = virt_to_machine(txb->data);
tx->size = txb->len;
+7 -3
View File
@@ -1,7 +1,9 @@
#!/bin/sh
[ "$GDB_MIRROR" ] || GDB_MIRROR="ftp://ftp.gnu.org/gnu/gdb/"
rm -rf gdb-6.2.1 gdb-6.2.1-linux-i386-xen
[ -a gdb-6.2.1.tar.bz2 ] || wget -c ftp://ftp.gnu.org/gnu/gdb/gdb-6.2.1.tar.bz2
[ -a gdb-6.2.1.tar.bz2 ] || wget -c "$GDB_MIRROR/gdb-6.2.1.tar.bz2"
tar xjf gdb-6.2.1.tar.bz2
cd gdb-6.2.1-xen-sparse
@@ -12,8 +14,10 @@ mkdir gdb-6.2.1-linux-i386-xen
cd gdb-6.2.1-linux-i386-xen
../gdb-6.2.1/configure
# some people don't have gmake
if which gmake ; then
# Use $MAKE if set, else use gmake if present, otherwise use make
if [ "$MAKE" ]; then
$MAKE
elif which gmake ; then
gmake -j4
else
make -j4
+3
View File
@@ -18,6 +18,9 @@
# Place - Suite 330, Boston, MA 02111-1307 USA.
#
# External CFLAGS can do more harm than good.
CFLAGS :=
XEN_ROOT = ../../..
include $(XEN_ROOT)/Config.mk
+3
View File
@@ -18,6 +18,9 @@
# Place - Suite 330, Boston, MA 02111-1307 USA.
#
# External CFLAGS can do more harm than good.
CFLAGS :=
XEN_ROOT = ../../..
include $(XEN_ROOT)/Config.mk
+4
View File
@@ -274,6 +274,10 @@ class HVMImageHandler(ImageHandler):
uname = sxp.child_value(info, 'uname')
typedev = sxp.child_value(info, 'dev')
(_, vbdparam) = string.split(uname, ':', 1)
if 'file:' in uname and not os.path.isfile(vbdparam):
raise VmError('Disk image does not exist: %s' % vbdparam)
if 'ioemu:' in typedev:
(emtype, vbddev) = string.split(typedev, ':', 1)
else:
+7 -5
View File
@@ -42,10 +42,6 @@ class BlkifController(DevController):
"""@see DevController.getDeviceDetails"""
dev = sxp.child_value(config, 'dev')
if 'ioemu:' in dev:
return (None,{},{})
devid = blkif.blkdev_name_to_number(dev)
(typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
back = { 'dev' : dev,
@@ -54,7 +50,13 @@ class BlkifController(DevController):
'mode' : sxp.child_value(config, 'mode', 'r')
}
front = { 'virtual-device' : "%i" % devid }
if 'ioemu:' in dev:
(dummy, dev1) = string.split(dev, ':', 1)
devid = blkif.blkdev_name_to_number(dev1)
front = {}
else:
devid = blkif.blkdev_name_to_number(dev)
front = { 'virtual-device' : "%i" % devid }
return (devid, back, front)
+8 -1
View File
@@ -74,7 +74,13 @@ TPM_RESULT close_dmi( VTPM_DMI_RESOURCE *dmi_res) {
close(dmi_res->guest_tx_fh); dmi_res->guest_tx_fh = -1;
close(dmi_res->vtpm_tx_fh); dmi_res->vtpm_tx_fh = -1;
vtpm_globals->connected_dmis--;
if (vtpm_globals->connected_dmis == 0) {
// No more DMI's connected. Close fifo to prevent a broken pipe.
close(vtpm_globals->guest_rx_fh);
vtpm_globals->guest_rx_fh = -1;
}
#ifndef MANUAL_DM_LAUNCH
if (dmi_res->dmi_id != VTPM_CTL_DM) {
if (dmi_res->dmi_pid != 0) {
@@ -118,6 +124,7 @@ TPM_RESULT VTPM_Handle_New_DMI( const buffer_t *param_buf) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
} else {
vtpm_globals->connected_dmis++; // Put this here so we don't count Dom0
BSG_UnpackList( param_buf->bytes, 3,
BSG_TYPE_BYTE, &type,
BSG_TYPE_UINT32, &domain_id,
+7 -6
View File
@@ -307,8 +307,8 @@ TPM_RESULT VTPM_SaveService(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, dmis=-1;
BYTE *flat_boot_key, *flat_dmis, *flat_enc;
buffer_t clear_flat_global, enc_flat_global;
BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL;
buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF;
UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
@@ -328,12 +328,9 @@ TPM_RESULT VTPM_SaveService(void) {
sizeof(UINT32) +// storagekeysize
storageKeySize, NULL) ); // storage key
flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
(sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
flat_boot_key = (BYTE *) malloc( boot_key_size );
flat_enc = (BYTE *) malloc( sizeof(UINT32) );
flat_dmis = (BYTE *) malloc( flat_dmis_size );
boot_key_size = BSG_PackList(flat_boot_key, 1,
BSG_TPM_SIZE32_DATA, &boot_key_pack);
@@ -349,9 +346,13 @@ TPM_RESULT VTPM_SaveService(void) {
BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
// Per DMI values to be saved
// Per DMI values to be saved (if any exit)
if (hashtable_count(vtpm_globals->dmi_map) > 0) {
flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
(sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
flat_dmis = (BYTE *) malloc( flat_dmis_size );
dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
@@ -754,6 +754,7 @@ TPM_RESULT VTPM_Init_Service() {
#ifndef VTPM_MULTI_VM
vtpm_globals->vtpm_rx_fh = -1;
vtpm_globals->guest_rx_fh = -1;
vtpm_globals->connected_dmis = 0;
#endif
if ((vtpm_globals->dmi_map = create_hashtable(10, hashfunc32, equals32)) == NULL){
status = TPM_FAIL;
+1
View File
@@ -98,6 +98,7 @@ typedef struct tdVTPM_GLOBALS {
#ifndef VTPM_MULTI_VM
int vtpm_rx_fh;
int guest_rx_fh;
int connected_dmis; // Used to close guest_rx when no dmis are connected
pid_t master_pid;
#endif
+3 -1
View File
@@ -12,7 +12,7 @@
#include <xen/sched.h>
#include <xen/mm.h>
#include <public/version.h>
//#include <xen/delay.h>
#include <xen/gdbstub.h>
#include <xen/compile.h>
#include <xen/console.h>
#include <xen/serial.h>
@@ -360,6 +360,8 @@ printk("About to call __cpu_up(%d)\n",i);
smp_cpus_done(max_cpus);
#endif
initialise_gdb(); /* could be moved earlier */
do_initcalls();
printk("About to call sort_main_extable()\n");
sort_main_extable();
+13 -15
View File
@@ -52,20 +52,6 @@ static void ioapic_enable(hvm_vioapic_t *s, uint8_t enable)
s->flags &= ~IOAPIC_ENABLE_FLAG;
}
static void ioapic_dump_redir(hvm_vioapic_t *s, uint8_t entry)
{
RedirStatus redir = s->redirtbl[entry];
printk("ioapic_dump_redir entry %x vector %x "
"deliver_mod %x destmode %x delivestatus %x "
"polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
entry, redir.RedirForm.vector, redir.RedirForm.deliver_mode,
redir.RedirForm.destmode, redir.RedirForm.delivestatus,
redir.RedirForm.polarity, redir.RedirForm.remoteirr,
redir.RedirForm.trigmod, redir.RedirForm.mask,
redir.RedirForm.dest_id);
}
#ifdef HVM_DOMAIN_SAVE_RESTORE
void ioapic_save(QEMUFile* f, void* opaque)
{
@@ -534,7 +520,19 @@ void hvm_vioapic_set_irq(struct domain *d, int irq, int level)
if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
return;
ioapic_dump_redir(s, irq);
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_set_irq entry %x "
"vector %x deliver_mod %x destmode %x delivestatus %x "
"polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
irq,
s->redirtbl[irq].RedirForm.vector,
s->redirtbl[irq].RedirForm.deliver_mode,
s->redirtbl[irq].RedirForm.destmode,
s->redirtbl[irq].RedirForm.delivestatus,
s->redirtbl[irq].RedirForm.polarity,
s->redirtbl[irq].RedirForm.remoteirr,
s->redirtbl[irq].RedirForm.trigmod,
s->redirtbl[irq].RedirForm.mask,
s->redirtbl[irq].RedirForm.dest_id);
if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
uint32_t bit = 1 << irq;
+29 -45
View File
@@ -1548,8 +1548,9 @@ static inline void check_timer(void)
*/
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);
timer_ack = 1;
enable_8259A_irq(0);
/* XEN: Ripped out the legacy missed-tick logic, so below is not needed. */
/*timer_ack = 1;*/
/*enable_8259A_irq(0);*/
pin1 = find_isa_irq_pin(0, mp_INT);
apic1 = find_isa_irq_apic(0, mp_INT);
@@ -1617,7 +1618,7 @@ static inline void check_timer(void)
printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
timer_ack = 0;
/*timer_ack = 0;*/
init_8259A(0);
make_8259A_irq(0);
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
@@ -1633,16 +1634,6 @@ static inline void check_timer(void)
"report. Then try booting with the 'noapic' option");
}
#define NR_IOAPIC_BIOSIDS 256
static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS];
static void store_ioapic_biosid_mapping(void)
{
u8 apic;
memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS);
for ( apic = 0; apic < nr_ioapics; apic++ )
ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic;
}
/*
*
* IRQ's that are handled by the PIC in the MPS IOAPIC case.
@@ -1654,8 +1645,6 @@ static void store_ioapic_biosid_mapping(void)
void __init setup_IO_APIC(void)
{
store_ioapic_biosid_mapping();
enable_IO_APIC();
if (acpi_ioapic)
@@ -1839,50 +1828,45 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
#endif /*CONFIG_ACPI_BOOT*/
int ioapic_guest_read(int apicid, int address, u32 *pval)
static int ioapic_physbase_to_id(unsigned long physbase)
{
u32 val;
int apicenum;
union IO_APIC_reg_00 reg_00;
int apic;
for ( apic = 0; apic < nr_ioapics; apic++ )
if ( mp_ioapics[apic].mpc_apicaddr == physbase )
return apic;
return -EINVAL;
}
int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
{
int apic;
unsigned long flags;
if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
return -EINVAL;
if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
return apic;
spin_lock_irqsave(&ioapic_lock, flags);
val = io_apic_read(apicenum, address);
*pval = io_apic_read(apic, reg);
spin_unlock_irqrestore(&ioapic_lock, flags);
/* Rewrite APIC ID to what the BIOS originally specified. */
if ( address == 0 )
{
reg_00.raw = val;
reg_00.bits.ID = apicid;
val = reg_00.raw;
}
*pval = val;
return 0;
}
int ioapic_guest_write(int apicid, int address, u32 val)
int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
{
int apicenum, pin, irq;
int apic, pin, irq;
struct IO_APIC_route_entry rte = { 0 };
struct irq_pin_list *entry;
unsigned long flags;
if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
return -EINVAL;
if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
return apic;
/* Only write to the first half of a route entry. */
if ( (address < 0x10) || (address & 1) )
if ( (reg < 0x10) || (reg & 1) )
return 0;
pin = (address - 0x10) >> 1;
pin = (reg - 0x10) >> 1;
*(u32 *)&rte = val;
rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
@@ -1898,7 +1882,7 @@ int ioapic_guest_write(int apicid, int address, u32 val)
if ( rte.delivery_mode > dest_LowestPrio )
{
printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
printk(" APIC=%d/%d, lo-reg=%x\n", apicid, pin, val);
printk(" APIC=%d/%d, lo-reg=%x\n", apic, pin, val);
return -EINVAL;
}
@@ -1923,19 +1907,19 @@ int ioapic_guest_write(int apicid, int address, u32 val)
/* Record the pin<->irq mapping. */
for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] )
{
if ( (entry->apic == apicenum) && (entry->pin == pin) )
if ( (entry->apic == apic) && (entry->pin == pin) )
break;
if ( !entry->next )
{
add_pin_to_irq(irq, apicenum, pin);
add_pin_to_irq(irq, apic, pin);
break;
}
}
}
spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0));
io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1));
io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
+12 -4
View File
@@ -11,8 +11,12 @@
#include <public/xen.h>
#include <public/physdev.h>
extern int ioapic_guest_read(int apicid, int address, u32 *pval);
extern int ioapic_guest_write(int apicid, int address, u32 pval);
extern int
ioapic_guest_read(
unsigned long physbase, unsigned int reg, u32 *pval);
extern int
ioapic_guest_write(
unsigned long physbase, unsigned int reg, u32 pval);
/*
* Demuxing hypercall.
@@ -49,7 +53,9 @@ long do_physdev_op(struct physdev_op *uop)
if ( !IS_PRIV(current->domain) )
break;
ret = ioapic_guest_read(
op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value);
op.u.apic_op.apic_physbase,
op.u.apic_op.reg,
&op.u.apic_op.value);
break;
case PHYSDEVOP_APIC_WRITE:
@@ -57,7 +63,9 @@ long do_physdev_op(struct physdev_op *uop)
if ( !IS_PRIV(current->domain) )
break;
ret = ioapic_guest_write(
op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value);
op.u.apic_op.apic_physbase,
op.u.apic_op.reg,
op.u.apic_op.value);
break;
case PHYSDEVOP_ASSIGN_VECTOR:
+3
View File
@@ -13,6 +13,7 @@
#include <xen/multiboot.h>
#include <xen/domain_page.h>
#include <xen/compile.h>
#include <xen/gdbstub.h>
#include <public/version.h>
#include <asm/bitops.h>
#include <asm/smp.h>
@@ -479,6 +480,8 @@ void __init __start_xen(multiboot_info_t *mbi)
printk("Brought up %ld CPUs\n", (long)num_online_cpus());
smp_cpus_done(max_cpus);
initialise_gdb(); /* could be moved earlier */
do_initcalls();
schedulers_start();
-11
View File
@@ -41,7 +41,6 @@ boolean_param("hpet_force", opt_hpet_force);
unsigned long cpu_khz; /* CPU clock frequency in kHz. */
unsigned long hpet_address;
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
int timer_ack = 0;
unsigned long volatile jiffies;
static u32 wc_sec, wc_nsec; /* UTC time at last 'time update'. */
static spinlock_t wc_lock = SPIN_LOCK_UNLOCKED;
@@ -148,16 +147,6 @@ void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
{
ASSERT(local_irq_is_enabled());
if ( timer_ack )
{
extern spinlock_t i8259A_lock;
spin_lock_irq(&i8259A_lock);
outb(0x0c, 0x20);
/* Ack the IRQ; AEOI will end it automatically. */
inb(0x20);
spin_unlock_irq(&i8259A_lock);
}
/* Update jiffies counter. */
(*(unsigned long *)&jiffies)++;
+7 -3
View File
@@ -1410,7 +1410,13 @@ long do_set_trap_table(struct trap_info *traps)
struct trap_info *dst = current->arch.guest_context.trap_ctxt;
long rc = 0;
LOCK_BIGLOCK(current->domain);
/* If no table is presented then clear the entire virtual IDT. */
if ( traps == NULL )
{
memset(dst, 0, 256 * sizeof(*dst));
init_int80_direct_trap(current);
return 0;
}
for ( ; ; )
{
@@ -1440,8 +1446,6 @@ long do_set_trap_table(struct trap_info *traps)
traps++;
}
UNLOCK_BIGLOCK(current->domain);
return rc;
}
+7 -27
View File
@@ -376,7 +376,6 @@ process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
break;
case 'g': /* Read registers */
gdb_arch_read_reg_array(regs, ctx);
ASSERT(!local_irq_is_enabled());
break;
case 'G': /* Write registers */
gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
@@ -395,7 +394,6 @@ process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
return 0;
}
gdb_cmd_read_mem(addr, length, ctx);
ASSERT(!local_irq_is_enabled());
break;
case 'M': /* Write memory */
addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
@@ -477,7 +475,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
{
int resume = 0;
int r;
unsigned flags;
unsigned long flags;
if ( gdb_ctx->serhnd < 0 )
{
@@ -506,7 +504,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
if ( !gdb_ctx->connected )
{
printk("GDB connection activated\n");
printk("GDB connection activated.\n");
gdb_arch_print_state(regs);
gdb_ctx->connected = 1;
}
@@ -522,7 +520,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
/* Shouldn't really do this, but otherwise we stop for no
obvious reason, which is Bad */
printk("Waiting for GDB to attach to Gdb\n");
printk("Waiting for GDB to attach...\n");
gdb_arch_enter(regs);
gdb_ctx->signum = gdb_arch_signal_num(regs, cookie);
@@ -535,9 +533,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
while ( resume == 0 )
{
ASSERT(!local_irq_is_enabled());
r = receive_command(gdb_ctx);
ASSERT(!local_irq_is_enabled());
if ( r < 0 )
{
dbg_printk("GDB disappeared, trying to resume Xen...\n");
@@ -545,9 +541,7 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
}
else
{
ASSERT(!local_irq_is_enabled());
resume = process_command(regs, gdb_ctx);
ASSERT(!local_irq_is_enabled());
}
}
@@ -561,28 +555,14 @@ __trap_to_gdb(struct cpu_user_regs *regs, unsigned long cookie)
return 0;
}
/*
* initialization
* XXX TODO
* This should be an explicit call from architecture code.
* initcall is far too late for some early debugging, and only the
* architecture code knows when this call can be made.
*/
static int
initialize_gdb(void)
void
initialise_gdb(void)
{
if ( !strcmp(opt_gdb, "none") )
return 0;
gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
if ( gdb_ctx->serhnd == -1 )
panic("Can't parse %s as GDB serial info.\n", opt_gdb);
printk("Gdb initialised.\n");
return 0;
if ( gdb_ctx->serhnd != -1 )
printk("GDB stub initialised.\n");
}
__initcall(initialize_gdb);
/*
* Local variables:
* mode: C
-2
View File
@@ -4,8 +4,6 @@
#include <asm/msr.h>
extern int timer_ack;
extern void calibrate_tsc_bp(void);
extern void calibrate_tsc_ap(void);
+1 -1
View File
@@ -21,7 +21,7 @@
typedef struct {
unsigned long addr; /* Machine address of packet. */
grant_ref_t ref; /* grant table access reference */
uint16_t id; /* Echoed in response message. */
uint16_t unused;
uint16_t size; /* Packet size in bytes. */
} tpmif_tx_request_t;
+2 -2
View File
@@ -33,8 +33,8 @@ typedef struct physdevop_set_iobitmap {
typedef struct physdevop_apic {
/* IN */
uint32_t apic;
uint32_t offset;
unsigned long apic_physbase;
uint32_t reg;
/* IN or OUT */
uint32_t value;
} physdevop_apic_t;
+10
View File
@@ -21,6 +21,8 @@
#ifndef __XEN_GDBSTUB_H__
#define __XEN_GDBSTUB_H__
#ifdef CRASH_DEBUG
/* value <-> char (de)serialzers for arch specific gdb backends */
char hex2char(unsigned long x);
int char2hex(unsigned char c);
@@ -84,6 +86,14 @@ void gdb_arch_exit(struct cpu_user_regs *regs);
#define SIGALRM 14
#define SIGTERM 15
void initialise_gdb(void);
#else
#define initialise_gdb() ((void)0)
#endif
#endif /* __XEN_GDBSTUB_H__ */
/*
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.