From 05620f85e930b0ac3dc22fdf8e4c390fa11afdeb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 16 Sep 2015 14:26:59 +0200 Subject: Revert "rcu: init rcu_registry_lock after fork" This reverts commit 5243722376873a48e9852a58b91f4d4101ee66e4. The patch forgot about rcu_sync_lock and was committed by mistake. Reported-by: Laszlo Ersek Signed-off-by: Paolo Bonzini --- util/rcu.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/util/rcu.c b/util/rcu.c index 47c2bceac8..8ba304dc44 100644 --- a/util/rcu.c +++ b/util/rcu.c @@ -335,11 +335,6 @@ static void rcu_init_unlock(void) qemu_mutex_unlock(&rcu_registry_lock); qemu_mutex_unlock(&rcu_sync_lock); } - -static void rcu_init_child(void) -{ - qemu_mutex_init(&rcu_registry_lock); -} #endif void rcu_after_fork(void) @@ -351,7 +346,7 @@ void rcu_after_fork(void) static void __attribute__((__constructor__)) rcu_init(void) { #ifdef CONFIG_POSIX - pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_child); + pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_unlock); #endif rcu_init_complete(); } -- cgit v1.2.3-55-g7522 From 84090bbce91a386ae6e5f61b26f36783196712d2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 10 Sep 2015 11:31:12 +0200 Subject: pci: remove Link Training error from AER error list The spec says: Undefined – The value read from this bit is undefined. In previous versions of this specification, this bit was used to indicate a Link Training Error. System software must ignore the value read from this bit. System software is permitted to write any value to this bit. Do not allow injecting it. Suggested-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Signed-off-by: Paolo Bonzini --- hw/pci/pcie_aer.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index f1847ac210..46e0ad8a93 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -827,10 +827,6 @@ typedef struct PCIEAERErrorName { */ static const struct PCIEAERErrorName pcie_aer_error_list[] = { { - .name = "TRAIN", - .val = PCI_ERR_UNC_TRAIN, - .correctable = false, - }, { .name = "DLP", .val = PCI_ERR_UNC_DLP, .correctable = false, -- cgit v1.2.3-55-g7522 From 120758fba4c52d1ccf3a8ae1fe3b7495f2b584d8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 14:50:17 +0200 Subject: update Linux headers to 4.3-rc1 The update to 4.2 was reviewed by Michael S. Tsirkin and Cornelia Huck. The further update to 4.3-rc1 only touches KVM files. Signed-off-by: Paolo Bonzini --- include/standard-headers/linux/pci_regs.h | 381 ++++++++++++++++++++------- include/standard-headers/linux/virtio_ring.h | 3 +- linux-headers/asm-x86/hyperv.h | 4 + linux-headers/asm-x86/kvm.h | 4 +- linux-headers/linux/kvm.h | 2 + scripts/update-linux-headers.sh | 1 + 6 files changed, 296 insertions(+), 99 deletions(-) diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index 57e8c80c30..413417f370 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -13,10 +13,10 @@ * PCI to PCI Bridge Specification * PCI System Design Guide * - * For hypertransport information, please consult the following manuals - * from http://www.hypertransport.org + * For HyperTransport information, please consult the following manuals + * from http://www.hypertransport.org * - * The Hypertransport I/O Link Specification + * The HyperTransport I/O Link Specification */ #ifndef LINUX_PCI_REGS_H @@ -26,6 +26,7 @@ * Under PCI, each device has 256 bytes of configuration address space, * of which the first 64 bytes are standardized as follows: */ +#define PCI_STD_HEADER_SIZEOF 64 #define PCI_VENDOR_ID 0x00 /* 16 bits */ #define PCI_DEVICE_ID 0x02 /* 16 bits */ #define PCI_COMMAND 0x04 /* 16 bits */ @@ -36,7 +37,7 @@ #define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ #define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ #define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ -#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ #define PCI_COMMAND_SERR 0x100 /* Enable SERR */ #define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ #define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ @@ -44,7 +45,7 @@ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_INTERRUPT 0x08 /* Interrupt status */ #define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ -#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 MHz PCI 2.1 bus */ #define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */ #define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ #define PCI_STATUS_PARITY 0x100 /* Detected parity error */ @@ -125,7 +126,8 @@ #define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */ #define PCI_IO_RANGE_TYPE_16 0x00 #define PCI_IO_RANGE_TYPE_32 0x01 -#define PCI_IO_RANGE_MASK (~0x0fUL) +#define PCI_IO_RANGE_MASK (~0x0fUL) /* Standard 4K I/O windows */ +#define PCI_IO_1K_RANGE_MASK (~0x03UL) /* Intel 1K I/O windows */ #define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */ #define PCI_MEMORY_BASE 0x20 /* Memory range behind */ #define PCI_MEMORY_LIMIT 0x22 @@ -203,16 +205,18 @@ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_CAP_ID_HT 0x08 /* HyperTransport */ -#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific */ +#define PCI_CAP_ID_VNDR 0x09 /* Vendor-Specific */ #define PCI_CAP_ID_DBG 0x0A /* Debug port */ #define PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */ -#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ +#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ #define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ -#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ +#define PCI_CAP_ID_SECDEV 0x0F /* Secure Device */ +#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -#define PCI_CAP_ID_SATA 0x12 /* Serial ATA */ +#define PCI_CAP_ID_SATA 0x12 /* SATA Data/Index Conf. */ #define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ +#define PCI_CAP_ID_MAX PCI_CAP_ID_AF #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ #define PCI_CAP_SIZEOF 4 @@ -264,8 +268,8 @@ #define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */ #define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */ #define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */ -#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */ -#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */ +#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */ +#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */ #define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */ #define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */ #define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */ @@ -277,6 +281,7 @@ #define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ #define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ #define PCI_VPD_DATA 4 /* 32-bits of data returned here */ +#define PCI_CAP_VPD_SIZEOF 8 /* Slot Identification */ @@ -287,32 +292,37 @@ /* Message Signalled Interrupts registers */ -#define PCI_MSI_FLAGS 2 /* Various flags */ -#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */ -#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */ -#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */ -#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */ -#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */ +#define PCI_MSI_FLAGS 2 /* Message Control */ +#define PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */ +#define PCI_MSI_FLAGS_QMASK 0x000e /* Maximum queue size available */ +#define PCI_MSI_FLAGS_QSIZE 0x0070 /* Message queue size configured */ +#define PCI_MSI_FLAGS_64BIT 0x0080 /* 64-bit addresses allowed */ +#define PCI_MSI_FLAGS_MASKBIT 0x0100 /* Per-vector masking capable */ #define PCI_MSI_RFU 3 /* Rest of capability flags */ #define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */ #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ #define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */ -#define PCI_MSI_PENDING_32 16 /* Pending bits register for 32-bit devices */ +#define PCI_MSI_PENDING_32 16 /* Pending intrs for 32-bit devices */ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */ -#define PCI_MSI_PENDING_64 20 /* Pending bits register for 32-bit devices */ +#define PCI_MSI_PENDING_64 20 /* Pending intrs for 64-bit devices */ /* MSI-X registers */ -#define PCI_MSIX_FLAGS 2 -#define PCI_MSIX_FLAGS_QSIZE 0x7FF -#define PCI_MSIX_FLAGS_ENABLE (1 << 15) -#define PCI_MSIX_FLAGS_MASKALL (1 << 14) -#define PCI_MSIX_TABLE 4 -#define PCI_MSIX_PBA 8 -#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) - -/* MSI-X entry's format */ +#define PCI_MSIX_FLAGS 2 /* Message Control */ +#define PCI_MSIX_FLAGS_QSIZE 0x07FF /* Table size */ +#define PCI_MSIX_FLAGS_MASKALL 0x4000 /* Mask all vectors for this function */ +#define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */ +#define PCI_MSIX_TABLE 4 /* Table offset */ +#define PCI_MSIX_TABLE_BIR 0x00000007 /* BAR index */ +#define PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* Offset into specified BAR */ +#define PCI_MSIX_PBA 8 /* Pending Bit Array offset */ +#define PCI_MSIX_PBA_BIR 0x00000007 /* BAR index */ +#define PCI_MSIX_PBA_OFFSET 0xfffffff8 /* Offset into specified BAR */ +#define PCI_MSIX_FLAGS_BIRMASK PCI_MSIX_PBA_BIR /* deprecated */ +#define PCI_CAP_MSIX_SIZEOF 12 /* size of MSIX registers */ + +/* MSI-X Table entry format */ #define PCI_MSIX_ENTRY_SIZE 16 #define PCI_MSIX_ENTRY_LOWER_ADDR 0 #define PCI_MSIX_ENTRY_UPPER_ADDR 4 @@ -341,8 +351,9 @@ #define PCI_AF_CTRL_FLR 0x01 #define PCI_AF_STATUS 5 #define PCI_AF_STATUS_TP 0x01 +#define PCI_CAP_AF_SIZEOF 6 /* size of AF registers */ -/* PCI-X registers */ +/* PCI-X registers (Type 0 (non-bridge) devices) */ #define PCI_X_CMD 2 /* Modes & Features */ #define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ @@ -362,7 +373,7 @@ #define PCI_X_CMD_SPLIT_16 0x0060 /* Max 16 */ #define PCI_X_CMD_SPLIT_32 0x0070 /* Max 32 */ #define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ -#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ +#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ #define PCI_X_STATUS 4 /* PCI-X capabilities */ #define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */ #define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */ @@ -377,11 +388,28 @@ #define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ +#define PCI_X_ECC_CSR 8 /* ECC control and status */ +#define PCI_CAP_PCIX_SIZEOF_V0 8 /* size of registers for Version 0 */ +#define PCI_CAP_PCIX_SIZEOF_V1 24 /* size for Version 1 */ +#define PCI_CAP_PCIX_SIZEOF_V2 PCI_CAP_PCIX_SIZEOF_V1 /* Same for v2 */ + +/* PCI-X registers (Type 1 (bridge) devices) */ + +#define PCI_X_BRIDGE_SSTATUS 2 /* Secondary Status */ +#define PCI_X_SSTATUS_64BIT 0x0001 /* Secondary AD interface is 64 bits */ +#define PCI_X_SSTATUS_133MHZ 0x0002 /* 133 MHz capable */ +#define PCI_X_SSTATUS_FREQ 0x03c0 /* Secondary Bus Mode and Frequency */ +#define PCI_X_SSTATUS_VERS 0x3000 /* PCI-X Capability Version */ +#define PCI_X_SSTATUS_V1 0x1000 /* Mode 2, not Mode 1 */ +#define PCI_X_SSTATUS_V2 0x2000 /* Mode 1 or Modes 1 and 2 */ +#define PCI_X_SSTATUS_266MHZ 0x4000 /* 266 MHz capable */ +#define PCI_X_SSTATUS_533MHZ 0x8000 /* 533 MHz capable */ +#define PCI_X_BRIDGE_STATUS 4 /* Bridge Status */ /* PCI Bridge Subsystem ID registers */ -#define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */ -#define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */ +#define PCI_SSVID_VENDOR_ID 4 /* PCI Bridge subsystem vendor ID */ +#define PCI_SSVID_DEVICE_ID 6 /* PCI Bridge subsystem device ID */ /* PCI Express capability registers */ @@ -393,24 +421,24 @@ #define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ #define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ #define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ -#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ -#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIE Bridge */ +#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCIe to PCI/PCI-X Bridge */ +#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIe Bridge */ #define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */ -#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ +#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ #define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ #define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */ #define PCI_EXP_DEVCAP 4 /* Device capabilities */ -#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ -#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ -#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ -#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ -#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ -#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ -#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ -#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ -#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ -#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ -#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ +#define PCI_EXP_DEVCAP_PAYLOAD 0x00000007 /* Max_Payload_Size */ +#define PCI_EXP_DEVCAP_PHANTOM 0x00000018 /* Phantom functions */ +#define PCI_EXP_DEVCAP_EXT_TAG 0x00000020 /* Extended tags */ +#define PCI_EXP_DEVCAP_L0S 0x000001c0 /* L0s Acceptable Latency */ +#define PCI_EXP_DEVCAP_L1 0x00000e00 /* L1 Acceptable Latency */ +#define PCI_EXP_DEVCAP_ATN_BUT 0x00001000 /* Attention Button Present */ +#define PCI_EXP_DEVCAP_ATN_IND 0x00002000 /* Attention Indicator Present */ +#define PCI_EXP_DEVCAP_PWR_IND 0x00004000 /* Power Indicator Present */ +#define PCI_EXP_DEVCAP_RBER 0x00008000 /* Role-Based Error Reporting */ +#define PCI_EXP_DEVCAP_PWR_VAL 0x03fc0000 /* Slot Power Limit Value */ +#define PCI_EXP_DEVCAP_PWR_SCL 0x0c000000 /* Slot Power Limit Scale */ #define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ @@ -424,47 +452,61 @@ #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ +#define PCI_EXP_DEVCTL_READRQ_128B 0x0000 /* 128 Bytes */ +#define PCI_EXP_DEVCTL_READRQ_256B 0x1000 /* 256 Bytes */ +#define PCI_EXP_DEVCTL_READRQ_512B 0x2000 /* 512 Bytes */ +#define PCI_EXP_DEVCTL_READRQ_1024B 0x3000 /* 1024 Bytes */ #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ #define PCI_EXP_DEVSTA 10 /* Device Status */ -#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ -#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ -#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ -#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ -#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ -#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ +#define PCI_EXP_DEVSTA_CED 0x0001 /* Correctable Error Detected */ +#define PCI_EXP_DEVSTA_NFED 0x0002 /* Non-Fatal Error Detected */ +#define PCI_EXP_DEVSTA_FED 0x0004 /* Fatal Error Detected */ +#define PCI_EXP_DEVSTA_URD 0x0008 /* Unsupported Request Detected */ +#define PCI_EXP_DEVSTA_AUXPD 0x0010 /* AUX Power Detected */ +#define PCI_EXP_DEVSTA_TRPND 0x0020 /* Transactions Pending */ #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ +#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ +#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ #define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */ -#define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */ +#define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* Clock Power Management */ #define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */ #define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ #define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */ #define PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */ #define PCI_EXP_LNKCTL 16 /* Link Control */ #define PCI_EXP_LNKCTL_ASPMC 0x0003 /* ASPM Control */ +#define PCI_EXP_LNKCTL_ASPM_L0S 0x0001 /* L0s Enable */ +#define PCI_EXP_LNKCTL_ASPM_L1 0x0002 /* L1 Enable */ #define PCI_EXP_LNKCTL_RCB 0x0008 /* Read Completion Boundary */ #define PCI_EXP_LNKCTL_LD 0x0010 /* Link Disable */ #define PCI_EXP_LNKCTL_RL 0x0020 /* Retrain Link */ #define PCI_EXP_LNKCTL_CCC 0x0040 /* Common Clock Configuration */ #define PCI_EXP_LNKCTL_ES 0x0080 /* Extended Synch */ -#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ +#define PCI_EXP_LNKCTL_CLKREQ_EN 0x0100 /* Enable clkreq */ #define PCI_EXP_LNKCTL_HAWD 0x0200 /* Hardware Autonomous Width Disable */ #define PCI_EXP_LNKCTL_LBMIE 0x0400 /* Link Bandwidth Management Interrupt Enable */ -#define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */ +#define PCI_EXP_LNKCTL_LABIE 0x0800 /* Link Autonomous Bandwidth Interrupt Enable */ #define PCI_EXP_LNKSTA 18 /* Link Status */ #define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */ -#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ -#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ -#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */ +#define PCI_EXP_LNKSTA_CLS_2_5GB 0x0001 /* Current Link Speed 2.5GT/s */ +#define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002 /* Current Link Speed 5.0GT/s */ +#define PCI_EXP_LNKSTA_CLS_8_0GB 0x0003 /* Current Link Speed 8.0GT/s */ +#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Negotiated Link Width */ +#define PCI_EXP_LNKSTA_NLW_X1 0x0010 /* Current Link Width x1 */ +#define PCI_EXP_LNKSTA_NLW_X2 0x0020 /* Current Link Width x2 */ +#define PCI_EXP_LNKSTA_NLW_X4 0x0040 /* Current Link Width x4 */ +#define PCI_EXP_LNKSTA_NLW_X8 0x0080 /* Current Link Width x8 */ #define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */ #define PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */ #define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */ #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */ #define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */ #define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20 /* v1 endpoints end here */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */ #define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */ @@ -486,8 +528,16 @@ #define PCI_EXP_SLTCTL_CCIE 0x0010 /* Command Completed Interrupt Enable */ #define PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */ #define PCI_EXP_SLTCTL_AIC 0x00c0 /* Attention Indicator Control */ +#define PCI_EXP_SLTCTL_ATTN_IND_ON 0x0040 /* Attention Indicator on */ +#define PCI_EXP_SLTCTL_ATTN_IND_BLINK 0x0080 /* Attention Indicator blinking */ +#define PCI_EXP_SLTCTL_ATTN_IND_OFF 0x00c0 /* Attention Indicator off */ #define PCI_EXP_SLTCTL_PIC 0x0300 /* Power Indicator Control */ +#define PCI_EXP_SLTCTL_PWR_IND_ON 0x0100 /* Power Indicator on */ +#define PCI_EXP_SLTCTL_PWR_IND_BLINK 0x0200 /* Power Indicator blinking */ +#define PCI_EXP_SLTCTL_PWR_IND_OFF 0x0300 /* Power Indicator off */ #define PCI_EXP_SLTCTL_PCC 0x0400 /* Power Controller Control */ +#define PCI_EXP_SLTCTL_PWR_ON 0x0000 /* Power On */ +#define PCI_EXP_SLTCTL_PWR_OFF 0x0400 /* Power Off */ #define PCI_EXP_SLTCTL_EIC 0x0800 /* Electromechanical Interlock Control */ #define PCI_EXP_SLTCTL_DLLSCE 0x1000 /* Data Link Layer State Changed Enable */ #define PCI_EXP_SLTSTA 26 /* Slot Status */ @@ -501,52 +551,94 @@ #define PCI_EXP_SLTSTA_EIS 0x0080 /* Electromechanical Interlock Status */ #define PCI_EXP_SLTSTA_DLLSC 0x0100 /* Data Link Layer State Changed */ #define PCI_EXP_RTCTL 28 /* Root Control */ -#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */ -#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */ -#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */ -#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */ -#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ +#define PCI_EXP_RTCTL_SECEE 0x0001 /* System Error on Correctable Error */ +#define PCI_EXP_RTCTL_SENFEE 0x0002 /* System Error on Non-Fatal Error */ +#define PCI_EXP_RTCTL_SEFEE 0x0004 /* System Error on Fatal Error */ +#define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */ +#define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ +#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ #define PCI_EXP_RTSTA 32 /* Root Status */ -#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ -#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ +#define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ +#define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ +/* + * The Device Capabilities 2, Device Status 2, Device Control 2, + * Link Capabilities 2, Link Status 2, Link Control 2, + * Slot Capabilities 2, Slot Status 2, and Slot Control 2 registers + * are only present on devices with PCIe Capability version 2. + * Use pcie_capability_read_word() and similar interfaces to use them + * safely. + */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ -#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ -#define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */ -#define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */ -#define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */ -#define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */ +#define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ +#define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ +#define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ +#define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ -#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ -#define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */ -#define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */ -#define PCI_EXP_LTR_EN 0x400 /* Latency tolerance reporting */ -#define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */ -#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */ -#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ +#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */ +#define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x0100 /* Allow IDO for requests */ +#define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x0200 /* Allow IDO for completions */ +#define PCI_EXP_DEVCTL2_LTR_EN 0x0400 /* Enable LTR mechanism */ +#define PCI_EXP_DEVCTL2_OBFF_MSGA_EN 0x2000 /* Enable OBFF Message type A */ +#define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000 /* Enable OBFF Message type B */ +#define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */ +#define PCI_EXP_DEVSTA2 42 /* Device Status 2 */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44 /* v2 endpoints end here */ +#define PCI_EXP_LNKCAP2 44 /* Link Capabilities 2 */ +#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ +#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5.0GT/s */ +#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8.0GT/s */ +#define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100 /* Crosslink supported */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ +#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ +#define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ +#define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ /* Extended Capabilities (PCI-X 2.0 and Express) */ #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) #define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) -#define PCI_EXT_CAP_ID_ERR 1 -#define PCI_EXT_CAP_ID_VC 2 -#define PCI_EXT_CAP_ID_DSN 3 -#define PCI_EXT_CAP_ID_PWR 4 -#define PCI_EXT_CAP_ID_VNDR 11 -#define PCI_EXT_CAP_ID_ACS 13 -#define PCI_EXT_CAP_ID_ARI 14 -#define PCI_EXT_CAP_ID_ATS 15 -#define PCI_EXT_CAP_ID_SRIOV 16 -#define PCI_EXT_CAP_ID_LTR 24 +#define PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */ +#define PCI_EXT_CAP_ID_VC 0x02 /* Virtual Channel Capability */ +#define PCI_EXT_CAP_ID_DSN 0x03 /* Device Serial Number */ +#define PCI_EXT_CAP_ID_PWR 0x04 /* Power Budgeting */ +#define PCI_EXT_CAP_ID_RCLD 0x05 /* Root Complex Link Declaration */ +#define PCI_EXT_CAP_ID_RCILC 0x06 /* Root Complex Internal Link Control */ +#define PCI_EXT_CAP_ID_RCEC 0x07 /* Root Complex Event Collector */ +#define PCI_EXT_CAP_ID_MFVC 0x08 /* Multi-Function VC Capability */ +#define PCI_EXT_CAP_ID_VC9 0x09 /* same as _VC */ +#define PCI_EXT_CAP_ID_RCRB 0x0A /* Root Complex RB? */ +#define PCI_EXT_CAP_ID_VNDR 0x0B /* Vendor-Specific */ +#define PCI_EXT_CAP_ID_CAC 0x0C /* Config Access - obsolete */ +#define PCI_EXT_CAP_ID_ACS 0x0D /* Access Control Services */ +#define PCI_EXT_CAP_ID_ARI 0x0E /* Alternate Routing ID */ +#define PCI_EXT_CAP_ID_ATS 0x0F /* Address Translation Services */ +#define PCI_EXT_CAP_ID_SRIOV 0x10 /* Single Root I/O Virtualization */ +#define PCI_EXT_CAP_ID_MRIOV 0x11 /* Multi Root I/O Virtualization */ +#define PCI_EXT_CAP_ID_MCAST 0x12 /* Multicast */ +#define PCI_EXT_CAP_ID_PRI 0x13 /* Page Request Interface */ +#define PCI_EXT_CAP_ID_AMD_XXX 0x14 /* Reserved for AMD */ +#define PCI_EXT_CAP_ID_REBAR 0x15 /* Resizable BAR */ +#define PCI_EXT_CAP_ID_DPA 0x16 /* Dynamic Power Allocation */ +#define PCI_EXT_CAP_ID_TPH 0x17 /* TPH Requester */ +#define PCI_EXT_CAP_ID_LTR 0x18 /* Latency Tolerance Reporting */ +#define PCI_EXT_CAP_ID_SECPCI 0x19 /* Secondary PCIe Capability */ +#define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ +#define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PASID + +#define PCI_EXT_CAP_DSN_SIZEOF 12 +#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ -#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ +#define PCI_ERR_UNC_UND 0x00000001 /* Undefined */ #define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ +#define PCI_ERR_UNC_SURPDN 0x00000020 /* Surprise Down */ #define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ #define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ #define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ @@ -556,6 +648,11 @@ #define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ #define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ #define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ +#define PCI_ERR_UNC_ACSV 0x00200000 /* ACS Violation */ +#define PCI_ERR_UNC_INTN 0x00400000 /* internal error */ +#define PCI_ERR_UNC_MCBTLP 0x00800000 /* MC blocked TLP */ +#define PCI_ERR_UNC_ATOMEG 0x01000000 /* Atomic egress blocked */ +#define PCI_ERR_UNC_TLPPRE 0x02000000 /* TLP prefix blocked */ #define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ /* Same bits as above */ #define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ @@ -566,6 +663,9 @@ #define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ #define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ #define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ +#define PCI_ERR_COR_ADV_NFAT 0x00002000 /* Advisory Non-Fatal */ +#define PCI_ERR_COR_INTERNAL 0x00004000 /* Corrected Internal */ +#define PCI_ERR_COR_LOG_OVER 0x00008000 /* Header Log Overflow */ #define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ /* Same bits as above */ #define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ @@ -586,9 +686,9 @@ #define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ /* Multi ERR_COR Received */ #define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 -/* ERR_FATAL/NONFATAL Recevied */ +/* ERR_FATAL/NONFATAL Received */ #define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 -/* Multi ERR_FATAL/NONFATAL Recevied */ +/* Multi ERR_FATAL/NONFATAL Received */ #define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ @@ -596,13 +696,36 @@ #define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ /* Virtual Channel */ -#define PCI_VC_PORT_REG1 4 -#define PCI_VC_PORT_REG2 8 +#define PCI_VC_PORT_CAP1 4 +#define PCI_VC_CAP1_EVCC 0x00000007 /* extended VC count */ +#define PCI_VC_CAP1_LPEVCC 0x00000070 /* low prio extended VC count */ +#define PCI_VC_CAP1_ARB_SIZE 0x00000c00 +#define PCI_VC_PORT_CAP2 8 +#define PCI_VC_CAP2_32_PHASE 0x00000002 +#define PCI_VC_CAP2_64_PHASE 0x00000004 +#define PCI_VC_CAP2_128_PHASE 0x00000008 +#define PCI_VC_CAP2_ARB_OFF 0xff000000 #define PCI_VC_PORT_CTRL 12 +#define PCI_VC_PORT_CTRL_LOAD_TABLE 0x00000001 #define PCI_VC_PORT_STATUS 14 +#define PCI_VC_PORT_STATUS_TABLE 0x00000001 #define PCI_VC_RES_CAP 16 +#define PCI_VC_RES_CAP_32_PHASE 0x00000002 +#define PCI_VC_RES_CAP_64_PHASE 0x00000004 +#define PCI_VC_RES_CAP_128_PHASE 0x00000008 +#define PCI_VC_RES_CAP_128_PHASE_TB 0x00000010 +#define PCI_VC_RES_CAP_256_PHASE 0x00000020 +#define PCI_VC_RES_CAP_ARB_OFF 0xff000000 #define PCI_VC_RES_CTRL 20 +#define PCI_VC_RES_CTRL_LOAD_TABLE 0x00010000 +#define PCI_VC_RES_CTRL_ARB_SELECT 0x000e0000 +#define PCI_VC_RES_CTRL_ID 0x07000000 +#define PCI_VC_RES_CTRL_ENABLE 0x80000000 #define PCI_VC_RES_STATUS 26 +#define PCI_VC_RES_STATUS_TABLE 0x00000001 +#define PCI_VC_RES_STATUS_NEGO 0x00000002 +#define PCI_CAP_VC_BASE_SIZEOF 0x10 +#define PCI_CAP_VC_PER_VC_SIZEOF 0x0C /* Power Budgeting */ #define PCI_PWR_DSR 4 /* Data Select Register */ @@ -615,9 +738,16 @@ #define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ #define PCI_PWR_CAP 12 /* Capability */ #define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ +#define PCI_EXT_CAP_PWR_SIZEOF 16 + +/* Vendor-Specific (VSEC, PCI_EXT_CAP_ID_VNDR) */ +#define PCI_VNDR_HEADER 4 /* Vendor-Specific Header */ +#define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff) +#define PCI_VNDR_HEADER_REV(x) (((x) >> 16) & 0xf) +#define PCI_VNDR_HEADER_LEN(x) (((x) >> 20) & 0xfff) /* - * Hypertransport sub capability types + * HyperTransport sub capability types * * Unfortunately there are both 3 bit and 5 bit capability types defined * in the HT spec, catering for that is a little messy. You probably don't @@ -645,8 +775,10 @@ #define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */ #define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */ #define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */ -#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ -#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ +#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 HyperTransport configuration */ +#define HT_CAPTYPE_PM 0xE0 /* HyperTransport power management configuration */ +#define HT_CAP_SIZEOF_LONG 28 /* slave & primary */ +#define HT_CAP_SIZEOF_SHORT 24 /* host & secondary */ /* Alternative Routing-ID Interpretation */ #define PCI_ARI_CAP 0x04 /* ARI Capability Register */ @@ -657,6 +789,7 @@ #define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ #define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ #define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ +#define PCI_EXT_CAP_ARI_SIZEOF 8 /* Address Translation Service */ #define PCI_ATS_CAP 0x04 /* ATS Capability Register */ @@ -666,6 +799,29 @@ #define PCI_ATS_CTRL_ENABLE 0x8000 /* ATS Enable */ #define PCI_ATS_CTRL_STU(x) ((x) & 0x1f) /* Smallest Translation Unit */ #define PCI_ATS_MIN_STU 12 /* shift of minimum STU block */ +#define PCI_EXT_CAP_ATS_SIZEOF 8 + +/* Page Request Interface */ +#define PCI_PRI_CTRL 0x04 /* PRI control register */ +#define PCI_PRI_CTRL_ENABLE 0x01 /* Enable */ +#define PCI_PRI_CTRL_RESET 0x02 /* Reset */ +#define PCI_PRI_STATUS 0x06 /* PRI status register */ +#define PCI_PRI_STATUS_RF 0x001 /* Response Failure */ +#define PCI_PRI_STATUS_UPRGI 0x002 /* Unexpected PRG index */ +#define PCI_PRI_STATUS_STOPPED 0x100 /* PRI Stopped */ +#define PCI_PRI_MAX_REQ 0x08 /* PRI max reqs supported */ +#define PCI_PRI_ALLOC_REQ 0x0c /* PRI max reqs allowed */ +#define PCI_EXT_CAP_PRI_SIZEOF 16 + +/* Process Address Space ID */ +#define PCI_PASID_CAP 0x04 /* PASID feature register */ +#define PCI_PASID_CAP_EXEC 0x02 /* Exec permissions Supported */ +#define PCI_PASID_CAP_PRIV 0x04 /* Privilege Mode Supported */ +#define PCI_PASID_CTRL 0x06 /* PASID control register */ +#define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */ +#define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */ +#define PCI_PASID_CTRL_PRIV 0x04 /* Privilege Mode Enable */ +#define PCI_EXT_CAP_PASID_SIZEOF 8 /* Single Root I/O Virtualization */ #define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */ @@ -697,12 +853,14 @@ #define PCI_SRIOV_VFM_MI 0x1 /* Dormant.MigrateIn */ #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ +#define PCI_EXT_CAP_SRIOV_SIZEOF 64 #define PCI_LTR_MAX_SNOOP_LAT 0x4 #define PCI_LTR_MAX_NOSNOOP_LAT 0x6 #define PCI_LTR_VALUE_MASK 0x000003ff #define PCI_LTR_SCALE_MASK 0x00001c00 #define PCI_LTR_SCALE_SHIFT 10 +#define PCI_EXT_CAP_LTR_SIZEOF 8 /* Access Control Service */ #define PCI_ACS_CAP 0x04 /* ACS Capability Register */ @@ -713,7 +871,38 @@ #define PCI_ACS_UF 0x10 /* Upstream Forwarding */ #define PCI_ACS_EC 0x20 /* P2P Egress Control */ #define PCI_ACS_DT 0x40 /* Direct Translated P2P */ +#define PCI_ACS_EGRESS_BITS 0x05 /* ACS Egress Control Vector Size */ #define PCI_ACS_CTRL 0x06 /* ACS Control Register */ #define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */ +#define PCI_VSEC_HDR 4 /* extended cap - vendor-specific */ +#define PCI_VSEC_HDR_LEN_SHIFT 20 /* shift for length field */ + +/* SATA capability */ +#define PCI_SATA_REGS 4 /* SATA REGs specifier */ +#define PCI_SATA_REGS_MASK 0xF /* location - BAR#/inline */ +#define PCI_SATA_REGS_INLINE 0xF /* REGS in config space */ +#define PCI_SATA_SIZEOF_SHORT 8 +#define PCI_SATA_SIZEOF_LONG 16 + +/* Resizable BARs */ +#define PCI_REBAR_CTRL 8 /* control register */ +#define PCI_REBAR_CTRL_NBAR_MASK (7 << 5) /* mask for # bars */ +#define PCI_REBAR_CTRL_NBAR_SHIFT 5 /* shift for # bars */ + +/* Dynamic Power Allocation */ +#define PCI_DPA_CAP 4 /* capability register */ +#define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */ +#define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */ + +/* TPH Requester */ +#define PCI_TPH_CAP 4 /* capability register */ +#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */ +#define PCI_TPH_LOC_NONE 0x000 /* no location */ +#define PCI_TPH_LOC_CAP 0x200 /* in capability */ +#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */ +#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* st table mask */ +#define PCI_TPH_CAP_ST_SHIFT 16 /* st table shift */ +#define PCI_TPH_BASE_SIZEOF 12 /* size with no st table */ + #endif /* LINUX_PCI_REGS_H */ diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h index 6fe276fafb..023c6db041 100644 --- a/include/standard-headers/linux/virtio_ring.h +++ b/include/standard-headers/linux/virtio_ring.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. * * Copyright Rusty Russell IBM Corporation 2007. */ +#include #include "standard-headers/linux/types.h" #include "standard-headers/linux/virtio_types.h" @@ -143,7 +144,7 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p, vr->num = num; vr->desc = p; vr->avail = p + num*sizeof(struct vring_desc); - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16) + vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(__virtio16) + align-1) & ~(align - 1)); } diff --git a/linux-headers/asm-x86/hyperv.h b/linux-headers/asm-x86/hyperv.h index 8fba544e9c..f0412c50c4 100644 --- a/linux-headers/asm-x86/hyperv.h +++ b/linux-headers/asm-x86/hyperv.h @@ -27,6 +27,8 @@ #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) +/* Partition reference TSC MSR is available */ +#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) /* A partition's reference time stamp counter (TSC) page */ #define HV_X64_MSR_REFERENCE_TSC 0x40000021 @@ -108,6 +110,8 @@ #define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4) /* Support for a virtual guest idle state is available */ #define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5) +/* Guest crash data handler available */ +#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10) /* * Implementation recommendations. Indicates which behaviors the hypervisor diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index a4ae82eb82..cd54147cb3 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -354,7 +354,7 @@ struct kvm_xcrs { struct kvm_sync_regs { }; -#define KVM_QUIRK_LINT0_REENABLED (1 << 0) -#define KVM_QUIRK_CD_NW_CLEARED (1 << 1) +#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) +#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) #endif /* _ASM_X86_KVM_H */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 3bac8736d8..683f713e91 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -317,6 +317,7 @@ struct kvm_run { struct { #define KVM_SYSTEM_EVENT_SHUTDOWN 1 #define KVM_SYSTEM_EVENT_RESET 2 +#define KVM_SYSTEM_EVENT_CRASH 3 __u32 type; __u64 flags; } system_event; @@ -481,6 +482,7 @@ struct kvm_s390_psw { ((ai) << 26)) #define KVM_S390_INT_IO_MIN 0x00000000u #define KVM_S390_INT_IO_MAX 0xfffdffffu +#define KVM_S390_INT_IO_AI_MASK 0x04000000u struct kvm_s390_interrupt { diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index f0e830c2d6..7f7b592e8b 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -39,6 +39,7 @@ cp_virtio() { if grep '#include' "$f" | grep -v -e 'linux/virtio' \ -e 'linux/types' \ + -e 'stdint' \ -e 'linux/if_ether' \ -e 'sys/' \ > /dev/null -- cgit v1.2.3-55-g7522 From eddb4de3cc1403546b29e260068c4c1397cbd62d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 15:25:52 +0200 Subject: update-linux-headers: copy standard-headers files one by one cp_virtio is called for both the asm-s390/ and linux/ directories, so it looks for pci_regs.h and input.h files in asm-s390/ too. This makes little sense. In the next patch we will have the opposite problem; we want to add asm-x86/hyperv.h, and there's also a linux/hyperv.h file with unwanted dependencies on additional Linux uapi headers. We do not want to copy linux/hyperv.h. The solution is to make cp_virtio (now renamed to cp_portable) copy one file only, instead of using the "find" command, and call it multiple times. The new function is really just a reindentation of the old one. Reviewed-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- scripts/update-linux-headers.sh | 69 +++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 7f7b592e8b..6a75678884 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -28,39 +28,32 @@ if [ -z "$output" ]; then output="$PWD" fi -cp_virtio() { - from=$1 +cp_portable() { + f=$1 to=$2 - virtio=$(find "$from" -name '*virtio*h' -o -name "input.h" -o -name "pci_regs.h") - if [ "$virtio" ]; then - rm -rf "$to" - mkdir -p "$to" - for f in $virtio; do - if - grep '#include' "$f" | grep -v -e 'linux/virtio' \ - -e 'linux/types' \ - -e 'stdint' \ - -e 'linux/if_ether' \ - -e 'sys/' \ - > /dev/null - then - echo "Unexpected #include in input file $f". - exit 2 - fi - - header=$(basename "$f"); - sed -e 's/__u\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/__s\([0-9][0-9]*\)/int\1_t/g' \ - -e 's/__le\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ - -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ - -e 's/__bitwise__//' \ - -e 's/__attribute__((packed))/QEMU_PACKED/' \ - -e 's/__inline__/inline/' \ - -e '/sys\/ioctl.h/d' \ - "$f" > "$to/$header"; - done + if + grep '#include' "$f" | grep -v -e 'linux/virtio' \ + -e 'linux/types' \ + -e 'stdint' \ + -e 'linux/if_ether' \ + -e 'sys/' \ + > /dev/null + then + echo "Unexpected #include in input file $f". + exit 2 fi + + header=$(basename "$f"); + sed -e 's/__u\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/__s\([0-9][0-9]*\)/int\1_t/g' \ + -e 's/__le\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ + -e 's/__bitwise__//' \ + -e 's/__attribute__((packed))/QEMU_PACKED/' \ + -e 's/__inline__/inline/' \ + -e '/sys\/ioctl.h/d' \ + "$f" > "$to/$header"; } # This will pick up non-directories too (eg "Kconfig") but we will @@ -93,7 +86,12 @@ for arch in $ARCHLIST; do cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/" fi - cp_virtio "$tmpdir/include/asm" "$output/include/standard-headers/asm-$arch" + rm -rf "$output/include/standard-headers/asm-$arch" + mkdir -p "$output/include/standard-headers/asm-$arch" + if [ $arch = s390 ]; then + cp_portable "$tmpdir/include/asm/kvm_virtio.h" "$output/include/standard-headers/asm-s390/" + cp_portable "$tmpdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" + fi done rm -rf "$output/linux-headers/linux" @@ -120,7 +118,12 @@ cat <$output/linux-headers/linux/virtio_ring.h #include "standard-headers/linux/virtio_ring.h" EOF -cp_virtio "$tmpdir/include/linux/" "$output/include/standard-headers/linux" +rm -rf "$output/include/standard-headers/linux" +mkdir -p "$output/include/standard-headers/linux" +for i in "$tmpdir"/include/linux/*virtio*.h "$tmpdir/include/linux/input.h" \ + "$tmpdir/include/linux/pci_regs.h"; do + cp_portable "$i" "$output/include/standard-headers/linux" +done cat <$output/include/standard-headers/linux/types.h #include -- cgit v1.2.3-55-g7522 From 73aa529a48b4ed7fce21fc74e62fb24db526af5f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 15:25:52 +0200 Subject: target-i386: move asm-x86/hyperv.h to standard-headers The Hyper-V definitions are an industry standard and can be used from code that is not KVM-specific. Reviewed-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck Signed-off-by: Paolo Bonzini --- include/standard-headers/asm-x86/hyperv.h | 254 +++++++++++++++++++++++++++++ linux-headers/asm-x86/hyperv.h | 255 +----------------------------- scripts/update-linux-headers.sh | 9 +- target-i386/kvm.c | 2 +- 4 files changed, 262 insertions(+), 258 deletions(-) create mode 100644 include/standard-headers/asm-x86/hyperv.h diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h new file mode 100644 index 0000000000..99d311e4ad --- /dev/null +++ b/include/standard-headers/asm-x86/hyperv.h @@ -0,0 +1,254 @@ +#ifndef _ASM_X86_HYPERV_H +#define _ASM_X86_HYPERV_H + +#include "standard-headers/linux/types.h" + +/* + * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent + * is set by CPUID(HvCpuIdFunctionVersionAndFeatures). + */ +#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000 +#define HYPERV_CPUID_INTERFACE 0x40000001 +#define HYPERV_CPUID_VERSION 0x40000002 +#define HYPERV_CPUID_FEATURES 0x40000003 +#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004 +#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005 + +#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 +#define HYPERV_CPUID_MIN 0x40000005 +#define HYPERV_CPUID_MAX 0x4000ffff + +/* + * Feature identification. EAX indicates which features are available + * to the partition based upon the current partition privileges. + */ + +/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */ +#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) +/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ +#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) +/* Partition reference TSC MSR is available */ +#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) + +/* A partition's reference time stamp counter (TSC) page */ +#define HV_X64_MSR_REFERENCE_TSC 0x40000021 + +/* + * There is a single feature flag that signifies the presence of the MSR + * that can be used to retrieve both the local APIC Timer frequency as + * well as the TSC frequency. + */ + +/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ +#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) + +/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ +#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) + +/* + * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM + * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available + */ +#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2) +/* + * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through + * HV_X64_MSR_STIMER3_COUNT) available + */ +#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3) +/* + * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) + * are available + */ +#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4) +/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/ +#define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5) +/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/ +#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6) +/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/ +#define HV_X64_MSR_RESET_AVAILABLE (1 << 7) + /* + * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE, + * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE, + * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available + */ +#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) + +/* + * Feature identification: EBX indicates which flags were specified at + * partition creation. The format is the same as the partition creation + * flag structure defined in section Partition Creation Flags. + */ +#define HV_X64_CREATE_PARTITIONS (1 << 0) +#define HV_X64_ACCESS_PARTITION_ID (1 << 1) +#define HV_X64_ACCESS_MEMORY_POOL (1 << 2) +#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3) +#define HV_X64_POST_MESSAGES (1 << 4) +#define HV_X64_SIGNAL_EVENTS (1 << 5) +#define HV_X64_CREATE_PORT (1 << 6) +#define HV_X64_CONNECT_PORT (1 << 7) +#define HV_X64_ACCESS_STATS (1 << 8) +#define HV_X64_DEBUGGING (1 << 11) +#define HV_X64_CPU_POWER_MANAGEMENT (1 << 12) +#define HV_X64_CONFIGURE_PROFILER (1 << 13) + +/* + * Feature identification. EDX indicates which miscellaneous features + * are available to the partition. + */ +/* The MWAIT instruction is available (per section MONITOR / MWAIT) */ +#define HV_X64_MWAIT_AVAILABLE (1 << 0) +/* Guest debugging support is available */ +#define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1) +/* Performance Monitor support is available*/ +#define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2) +/* Support for physical CPU dynamic partitioning events is available*/ +#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3) +/* + * Support for passing hypercall input parameter block via XMM + * registers is available + */ +#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4) +/* Support for a virtual guest idle state is available */ +#define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5) +/* Guest crash data handler available */ +#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10) + +/* + * Implementation recommendations. Indicates which behaviors the hypervisor + * recommends the OS implement for optimal performance. + */ + /* + * Recommend using hypercall for address space switches rather + * than MOV to CR3 instruction + */ +#define HV_X64_MWAIT_RECOMMENDED (1 << 0) +/* Recommend using hypercall for local TLB flushes rather + * than INVLPG or MOV to CR3 instructions */ +#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1) +/* + * Recommend using hypercall for remote TLB flushes rather + * than inter-processor interrupts + */ +#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2) +/* + * Recommend using MSRs for accessing APIC registers + * EOI, ICR and TPR rather than their memory-mapped counterparts + */ +#define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3) +/* Recommend using the hypervisor-provided MSR to initiate a system RESET */ +#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4) +/* + * Recommend using relaxed timing for this partition. If used, + * the VM should disable any watchdog timeouts that rely on the + * timely delivery of external interrupts + */ +#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5) + +/* MSR used to identify the guest OS. */ +#define HV_X64_MSR_GUEST_OS_ID 0x40000000 + +/* MSR used to setup pages used to communicate with the hypervisor. */ +#define HV_X64_MSR_HYPERCALL 0x40000001 + +/* MSR used to provide vcpu index */ +#define HV_X64_MSR_VP_INDEX 0x40000002 + +/* MSR used to read the per-partition time reference counter */ +#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 + +/* MSR used to retrieve the TSC frequency */ +#define HV_X64_MSR_TSC_FREQUENCY 0x40000022 + +/* MSR used to retrieve the local APIC timer frequency */ +#define HV_X64_MSR_APIC_FREQUENCY 0x40000023 + +/* Define the virtual APIC registers */ +#define HV_X64_MSR_EOI 0x40000070 +#define HV_X64_MSR_ICR 0x40000071 +#define HV_X64_MSR_TPR 0x40000072 +#define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073 + +/* Define synthetic interrupt controller model specific registers. */ +#define HV_X64_MSR_SCONTROL 0x40000080 +#define HV_X64_MSR_SVERSION 0x40000081 +#define HV_X64_MSR_SIEFP 0x40000082 +#define HV_X64_MSR_SIMP 0x40000083 +#define HV_X64_MSR_EOM 0x40000084 +#define HV_X64_MSR_SINT0 0x40000090 +#define HV_X64_MSR_SINT1 0x40000091 +#define HV_X64_MSR_SINT2 0x40000092 +#define HV_X64_MSR_SINT3 0x40000093 +#define HV_X64_MSR_SINT4 0x40000094 +#define HV_X64_MSR_SINT5 0x40000095 +#define HV_X64_MSR_SINT6 0x40000096 +#define HV_X64_MSR_SINT7 0x40000097 +#define HV_X64_MSR_SINT8 0x40000098 +#define HV_X64_MSR_SINT9 0x40000099 +#define HV_X64_MSR_SINT10 0x4000009A +#define HV_X64_MSR_SINT11 0x4000009B +#define HV_X64_MSR_SINT12 0x4000009C +#define HV_X64_MSR_SINT13 0x4000009D +#define HV_X64_MSR_SINT14 0x4000009E +#define HV_X64_MSR_SINT15 0x4000009F + +/* + * Synthetic Timer MSRs. Four timers per vcpu. + */ +#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0 +#define HV_X64_MSR_STIMER0_COUNT 0x400000B1 +#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2 +#define HV_X64_MSR_STIMER1_COUNT 0x400000B3 +#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4 +#define HV_X64_MSR_STIMER2_COUNT 0x400000B5 +#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 +#define HV_X64_MSR_STIMER3_COUNT 0x400000B7 + +/* Hyper-V guest crash notification MSR's */ +#define HV_X64_MSR_CRASH_P0 0x40000100 +#define HV_X64_MSR_CRASH_P1 0x40000101 +#define HV_X64_MSR_CRASH_P2 0x40000102 +#define HV_X64_MSR_CRASH_P3 0x40000103 +#define HV_X64_MSR_CRASH_P4 0x40000104 +#define HV_X64_MSR_CRASH_CTL 0x40000105 +#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63) +#define HV_X64_MSR_CRASH_PARAMS \ + (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0)) + +#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 +#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12 +#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \ + (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1)) + +/* Declare the various hypercall operations. */ +#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008 + +#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001 +#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12 +#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \ + (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1)) + +#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001 +#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12 + +#define HV_PROCESSOR_POWER_STATE_C0 0 +#define HV_PROCESSOR_POWER_STATE_C1 1 +#define HV_PROCESSOR_POWER_STATE_C2 2 +#define HV_PROCESSOR_POWER_STATE_C3 3 + +/* hypercall status code */ +#define HV_STATUS_SUCCESS 0 +#define HV_STATUS_INVALID_HYPERCALL_CODE 2 +#define HV_STATUS_INVALID_HYPERCALL_INPUT 3 +#define HV_STATUS_INVALID_ALIGNMENT 4 +#define HV_STATUS_INSUFFICIENT_MEMORY 11 +#define HV_STATUS_INVALID_CONNECTION_ID 18 +#define HV_STATUS_INSUFFICIENT_BUFFERS 19 + +typedef struct _HV_REFERENCE_TSC_PAGE { + uint32_t tsc_sequence; + uint32_t res1; + uint64_t tsc_scale; + int64_t tsc_offset; +} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE; + +#endif diff --git a/linux-headers/asm-x86/hyperv.h b/linux-headers/asm-x86/hyperv.h index f0412c50c4..01af4d8593 100644 --- a/linux-headers/asm-x86/hyperv.h +++ b/linux-headers/asm-x86/hyperv.h @@ -1,254 +1 @@ -#ifndef _ASM_X86_HYPERV_H -#define _ASM_X86_HYPERV_H - -#include - -/* - * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent - * is set by CPUID(HvCpuIdFunctionVersionAndFeatures). - */ -#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000 -#define HYPERV_CPUID_INTERFACE 0x40000001 -#define HYPERV_CPUID_VERSION 0x40000002 -#define HYPERV_CPUID_FEATURES 0x40000003 -#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004 -#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005 - -#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 -#define HYPERV_CPUID_MIN 0x40000005 -#define HYPERV_CPUID_MAX 0x4000ffff - -/* - * Feature identification. EAX indicates which features are available - * to the partition based upon the current partition privileges. - */ - -/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */ -#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) -/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ -#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) -/* Partition reference TSC MSR is available */ -#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) - -/* A partition's reference time stamp counter (TSC) page */ -#define HV_X64_MSR_REFERENCE_TSC 0x40000021 - -/* - * There is a single feature flag that signifies the presence of the MSR - * that can be used to retrieve both the local APIC Timer frequency as - * well as the TSC frequency. - */ - -/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */ -#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11) - -/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */ -#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11) - -/* - * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM - * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available - */ -#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2) -/* - * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through - * HV_X64_MSR_STIMER3_COUNT) available - */ -#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3) -/* - * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) - * are available - */ -#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4) -/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/ -#define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5) -/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/ -#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6) -/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/ -#define HV_X64_MSR_RESET_AVAILABLE (1 << 7) - /* - * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE, - * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE, - * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available - */ -#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) - -/* - * Feature identification: EBX indicates which flags were specified at - * partition creation. The format is the same as the partition creation - * flag structure defined in section Partition Creation Flags. - */ -#define HV_X64_CREATE_PARTITIONS (1 << 0) -#define HV_X64_ACCESS_PARTITION_ID (1 << 1) -#define HV_X64_ACCESS_MEMORY_POOL (1 << 2) -#define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3) -#define HV_X64_POST_MESSAGES (1 << 4) -#define HV_X64_SIGNAL_EVENTS (1 << 5) -#define HV_X64_CREATE_PORT (1 << 6) -#define HV_X64_CONNECT_PORT (1 << 7) -#define HV_X64_ACCESS_STATS (1 << 8) -#define HV_X64_DEBUGGING (1 << 11) -#define HV_X64_CPU_POWER_MANAGEMENT (1 << 12) -#define HV_X64_CONFIGURE_PROFILER (1 << 13) - -/* - * Feature identification. EDX indicates which miscellaneous features - * are available to the partition. - */ -/* The MWAIT instruction is available (per section MONITOR / MWAIT) */ -#define HV_X64_MWAIT_AVAILABLE (1 << 0) -/* Guest debugging support is available */ -#define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1) -/* Performance Monitor support is available*/ -#define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2) -/* Support for physical CPU dynamic partitioning events is available*/ -#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3) -/* - * Support for passing hypercall input parameter block via XMM - * registers is available - */ -#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4) -/* Support for a virtual guest idle state is available */ -#define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5) -/* Guest crash data handler available */ -#define HV_X64_GUEST_CRASH_MSR_AVAILABLE (1 << 10) - -/* - * Implementation recommendations. Indicates which behaviors the hypervisor - * recommends the OS implement for optimal performance. - */ - /* - * Recommend using hypercall for address space switches rather - * than MOV to CR3 instruction - */ -#define HV_X64_MWAIT_RECOMMENDED (1 << 0) -/* Recommend using hypercall for local TLB flushes rather - * than INVLPG or MOV to CR3 instructions */ -#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1) -/* - * Recommend using hypercall for remote TLB flushes rather - * than inter-processor interrupts - */ -#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2) -/* - * Recommend using MSRs for accessing APIC registers - * EOI, ICR and TPR rather than their memory-mapped counterparts - */ -#define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3) -/* Recommend using the hypervisor-provided MSR to initiate a system RESET */ -#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4) -/* - * Recommend using relaxed timing for this partition. If used, - * the VM should disable any watchdog timeouts that rely on the - * timely delivery of external interrupts - */ -#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5) - -/* MSR used to identify the guest OS. */ -#define HV_X64_MSR_GUEST_OS_ID 0x40000000 - -/* MSR used to setup pages used to communicate with the hypervisor. */ -#define HV_X64_MSR_HYPERCALL 0x40000001 - -/* MSR used to provide vcpu index */ -#define HV_X64_MSR_VP_INDEX 0x40000002 - -/* MSR used to read the per-partition time reference counter */ -#define HV_X64_MSR_TIME_REF_COUNT 0x40000020 - -/* MSR used to retrieve the TSC frequency */ -#define HV_X64_MSR_TSC_FREQUENCY 0x40000022 - -/* MSR used to retrieve the local APIC timer frequency */ -#define HV_X64_MSR_APIC_FREQUENCY 0x40000023 - -/* Define the virtual APIC registers */ -#define HV_X64_MSR_EOI 0x40000070 -#define HV_X64_MSR_ICR 0x40000071 -#define HV_X64_MSR_TPR 0x40000072 -#define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073 - -/* Define synthetic interrupt controller model specific registers. */ -#define HV_X64_MSR_SCONTROL 0x40000080 -#define HV_X64_MSR_SVERSION 0x40000081 -#define HV_X64_MSR_SIEFP 0x40000082 -#define HV_X64_MSR_SIMP 0x40000083 -#define HV_X64_MSR_EOM 0x40000084 -#define HV_X64_MSR_SINT0 0x40000090 -#define HV_X64_MSR_SINT1 0x40000091 -#define HV_X64_MSR_SINT2 0x40000092 -#define HV_X64_MSR_SINT3 0x40000093 -#define HV_X64_MSR_SINT4 0x40000094 -#define HV_X64_MSR_SINT5 0x40000095 -#define HV_X64_MSR_SINT6 0x40000096 -#define HV_X64_MSR_SINT7 0x40000097 -#define HV_X64_MSR_SINT8 0x40000098 -#define HV_X64_MSR_SINT9 0x40000099 -#define HV_X64_MSR_SINT10 0x4000009A -#define HV_X64_MSR_SINT11 0x4000009B -#define HV_X64_MSR_SINT12 0x4000009C -#define HV_X64_MSR_SINT13 0x4000009D -#define HV_X64_MSR_SINT14 0x4000009E -#define HV_X64_MSR_SINT15 0x4000009F - -/* - * Synthetic Timer MSRs. Four timers per vcpu. - */ -#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0 -#define HV_X64_MSR_STIMER0_COUNT 0x400000B1 -#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2 -#define HV_X64_MSR_STIMER1_COUNT 0x400000B3 -#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4 -#define HV_X64_MSR_STIMER2_COUNT 0x400000B5 -#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 -#define HV_X64_MSR_STIMER3_COUNT 0x400000B7 - -/* Hyper-V guest crash notification MSR's */ -#define HV_X64_MSR_CRASH_P0 0x40000100 -#define HV_X64_MSR_CRASH_P1 0x40000101 -#define HV_X64_MSR_CRASH_P2 0x40000102 -#define HV_X64_MSR_CRASH_P3 0x40000103 -#define HV_X64_MSR_CRASH_P4 0x40000104 -#define HV_X64_MSR_CRASH_CTL 0x40000105 -#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63) -#define HV_X64_MSR_CRASH_PARAMS \ - (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0)) - -#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 -#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12 -#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \ - (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1)) - -/* Declare the various hypercall operations. */ -#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008 - -#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001 -#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12 -#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \ - (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1)) - -#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001 -#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12 - -#define HV_PROCESSOR_POWER_STATE_C0 0 -#define HV_PROCESSOR_POWER_STATE_C1 1 -#define HV_PROCESSOR_POWER_STATE_C2 2 -#define HV_PROCESSOR_POWER_STATE_C3 3 - -/* hypercall status code */ -#define HV_STATUS_SUCCESS 0 -#define HV_STATUS_INVALID_HYPERCALL_CODE 2 -#define HV_STATUS_INVALID_HYPERCALL_INPUT 3 -#define HV_STATUS_INVALID_ALIGNMENT 4 -#define HV_STATUS_INSUFFICIENT_MEMORY 11 -#define HV_STATUS_INVALID_CONNECTION_ID 18 -#define HV_STATUS_INSUFFICIENT_BUFFERS 19 - -typedef struct _HV_REFERENCE_TSC_PAGE { - __u32 tsc_sequence; - __u32 res1; - __u64 tsc_scale; - __s64 tsc_offset; -} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE; - -#endif +#include "standard-headers/asm-x86/hyperv.h" diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 6a75678884..1107619121 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -79,9 +79,6 @@ for arch in $ARCHLIST; do for header in kvm.h kvm_para.h; do cp "$tmpdir/include/asm/$header" "$output/linux-headers/asm-$arch" done - if [ $arch = x86 ]; then - cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86" - fi if [ $arch = powerpc ]; then cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/" fi @@ -92,6 +89,9 @@ for arch in $ARCHLIST; do cp_portable "$tmpdir/include/asm/kvm_virtio.h" "$output/include/standard-headers/asm-s390/" cp_portable "$tmpdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" fi + if [ $arch = x86 ]; then + cp_portable "$tmpdir/include/asm/hyperv.h" "$output/include/standard-headers/asm-x86/" + fi done rm -rf "$output/linux-headers/linux" @@ -111,6 +111,9 @@ else cp "$linux/COPYING" "$output/linux-headers" fi +cat <$output/linux-headers/asm-x86/hyperv.h +#include "standard-headers/asm-x86/hyperv.h" +EOF cat <$output/linux-headers/linux/virtio_config.h #include "standard-headers/linux/virtio_config.h" EOF diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 066d03d99e..d8a11be57a 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -33,7 +33,7 @@ #include "hw/i386/apic_internal.h" #include "hw/i386/apic-msidef.h" #include "exec/ioport.h" -#include +#include "standard-headers/asm-x86/hyperv.h" #include "hw/pci/pci.h" #include "migration/migration.h" #include "exec/memattrs.h" -- cgit v1.2.3-55-g7522 From bac05aa9a77af1ca7972c8dc07560f4daa7c2dfc Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Fri, 3 Jul 2015 15:01:44 +0300 Subject: cpu: Add crash_occurred flag into CPUState CPUState::crash_occurred field inside CPUState marks that guest crash occurred. This value is added into cpu common migration subsection. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Andreas Färber Message-Id: <1435924905-8926-12-git-send-email-den@openvz.org> [Document the new field. - Paolo] Signed-off-by: Paolo Bonzini --- exec.c | 19 +++++++++++++++++++ include/qom/cpu.h | 2 ++ qom/cpu.c | 1 + vl.c | 3 +++ 4 files changed, 25 insertions(+) diff --git a/exec.c b/exec.c index b61126cb76..07dfeae4d8 100644 --- a/exec.c +++ b/exec.c @@ -478,6 +478,24 @@ static const VMStateDescription vmstate_cpu_common_exception_index = { } }; +static bool cpu_common_crash_occurred_needed(void *opaque) +{ + CPUState *cpu = opaque; + + return cpu->crash_occurred; +} + +static const VMStateDescription vmstate_cpu_common_crash_occurred = { + .name = "cpu_common/crash_occurred", + .version_id = 1, + .minimum_version_id = 1, + .needed = cpu_common_crash_occurred_needed, + .fields = (VMStateField[]) { + VMSTATE_BOOL(crash_occurred, CPUState), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_cpu_common = { .name = "cpu_common", .version_id = 1, @@ -491,6 +509,7 @@ const VMStateDescription vmstate_cpu_common = { }, .subsections = (const VMStateDescription*[]) { &vmstate_cpu_common_exception_index, + &vmstate_cpu_common_crash_occurred, NULL } }; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index c3d610b988..302673dbad 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -223,6 +223,7 @@ struct kvm_run; * @halted: Nonzero if the CPU is in suspended state. * @stop: Indicates a pending stop request. * @stopped: Indicates the CPU has been artificially stopped. + * @crash_occurred: Indicates the OS reported a crash (panic) for this CPU * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this * CPU and return to its top level loop. * @singlestep_enabled: Flags for single-stepping. @@ -269,6 +270,7 @@ struct CPUState { bool created; bool stop; bool stopped; + bool crash_occurred; bool exit_request; uint32_t interrupt_request; int singlestep_enabled; diff --git a/qom/cpu.c b/qom/cpu.c index 3841f0de5b..fb80d13a3f 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -251,6 +251,7 @@ static void cpu_common_reset(CPUState *cpu) cpu->icount_decr.u32 = 0; cpu->can_do_io = 1; cpu->exception_index = -1; + cpu->crash_occurred = false; memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *)); } diff --git a/vl.c b/vl.c index 066a080db5..3c6480dadf 100644 --- a/vl.c +++ b/vl.c @@ -1747,6 +1747,9 @@ void qemu_system_reset(bool report) void qemu_system_guest_panicked(void) { + if (current_cpu) { + current_cpu->crash_occurred = true; + } qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort); vm_stop(RUN_STATE_GUEST_PANICKED); } -- cgit v1.2.3-55-g7522 From 7c207b90465bc16a39b9fb8d9194f161059f69bf Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Fri, 3 Jul 2015 15:01:43 +0300 Subject: kvm: Add kvm system event crash handler KVM kernel can send guest crash events into userspace. Appropriate guest crash handler is called when kernel guest crash event received. Guest crash event recognized by a KVM_SYSTEM_EVENT_CRASH type of system event. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Andreas Färber Message-Id: <1435924905-8926-11-git-send-email-den@openvz.org> [Rebase: add lock/unlock iothread around qemu_system_guest_panicked - Paolo] Signed-off-by: Paolo Bonzini --- kvm-all.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kvm-all.c b/kvm-all.c index c6f5128756..de1924c467 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1889,6 +1889,12 @@ int kvm_cpu_exec(CPUState *cpu) qemu_system_reset_request(); ret = EXCP_INTERRUPT; break; + case KVM_SYSTEM_EVENT_CRASH: + qemu_mutex_lock_iothread(); + qemu_system_guest_panicked(); + qemu_mutex_unlock_iothread(); + ret = 0; + break; default: DPRINTF("kvm_arch_handle_exit\n"); ret = kvm_arch_handle_exit(cpu, run); -- cgit v1.2.3-55-g7522 From f2a53c9e05a24352a0f9740db0539ce5aeed22ca Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 9 Sep 2015 14:41:30 +0200 Subject: i386/kvm: Hyper-v crash msrs set/get'ers and migration KVM Hyper-V based guests can notify hypervisor about occurred guest crash by writing into Hyper-V crash MSR's. This patch does handling and migration of HV_X64_MSR_CRASH_P0-P4, HV_X64_MSR_CRASH_CTL msrs. User can enable these MSR's by 'hv-crash' option. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Andreas Färber Message-Id: <1435924905-8926-13-git-send-email-den@openvz.org> [Folks, stop abrviating variable names!!! Also fix compilation on non-Linux/x86. - Paolo] Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/cpu.h | 2 ++ target-i386/kvm.c | 32 +++++++++++++++++++++++++++++++- target-i386/machine.c | 27 +++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 7a4fddd85f..c35b624c9d 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -89,6 +89,7 @@ typedef struct X86CPU { bool hyperv_relaxed_timing; int hyperv_spinlock_attempts; bool hyperv_time; + bool hyperv_crash; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index cfb8aa7e4e..7c52714014 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3121,6 +3121,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false), DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false), DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false), + DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target-i386/cpu.h b/target-i386/cpu.h index af977726d1..5d515f69c8 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -21,6 +21,7 @@ #include "config.h" #include "qemu-common.h" +#include "standard-headers/asm-x86/hyperv.h" #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64 @@ -908,6 +909,7 @@ typedef struct CPUX86State { uint64_t msr_hv_guest_os_id; uint64_t msr_hv_vapic; uint64_t msr_hv_tsc; + uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS]; /* exception/interrupt handling */ int error_code; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index d8a11be57a..7b0ba179cc 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -80,6 +80,7 @@ static int lm_capable_kernel; static bool has_msr_hv_hypercall; static bool has_msr_hv_vapic; static bool has_msr_hv_tsc; +static bool has_msr_hv_crash; static bool has_msr_mtrr; static bool has_msr_xss; @@ -457,7 +458,8 @@ static bool hyperv_enabled(X86CPU *cpu) return kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV) > 0 && (hyperv_hypercall_available(cpu) || cpu->hyperv_time || - cpu->hyperv_relaxed_timing); + cpu->hyperv_relaxed_timing || + cpu->hyperv_crash); } static Error *invtsc_mig_blocker; @@ -523,6 +525,10 @@ int kvm_arch_init_vcpu(CPUState *cs) c->eax |= 0x200; has_msr_hv_tsc = true; } + if (cpu->hyperv_crash && has_msr_hv_crash) { + c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE; + } + c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -843,6 +849,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_xss = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_CRASH_CTL) { + has_msr_hv_crash = true; + continue; + } } } @@ -1375,6 +1385,16 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc); } + if (has_msr_hv_crash) { + int j; + + for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) + kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_P0 + j, + env->msr_hv_crash_params[j]); + + kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL, + HV_X64_MSR_CRASH_CTL_NOTIFY); + } if (has_msr_mtrr) { kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_set(&msrs[n++], @@ -1730,6 +1750,13 @@ static int kvm_get_msrs(X86CPU *cpu) if (has_msr_hv_tsc) { msrs[n++].index = HV_X64_MSR_REFERENCE_TSC; } + if (has_msr_hv_crash) { + int j; + + for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) { + msrs[n++].index = HV_X64_MSR_CRASH_P0 + j; + } + } if (has_msr_mtrr) { msrs[n++].index = MSR_MTRRdefType; msrs[n++].index = MSR_MTRRfix64K_00000; @@ -1877,6 +1904,9 @@ static int kvm_get_msrs(X86CPU *cpu) case HV_X64_MSR_REFERENCE_TSC: env->msr_hv_tsc = msrs[i].data; break; + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: + env->msr_hv_crash_params[index - HV_X64_MSR_CRASH_P0] = msrs[i].data; + break; case MSR_MTRRdefType: env->mtrr_deftype = msrs[i].data; break; diff --git a/target-i386/machine.c b/target-i386/machine.c index a0df64b577..9fa056341a 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -661,6 +661,32 @@ static const VMStateDescription vmstate_msr_hyperv_time = { } }; +static bool hyperv_crash_enable_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + int i; + + for (i = 0; i < HV_X64_MSR_CRASH_PARAMS; i++) { + if (env->msr_hv_crash_params[i]) { + return true; + } + } + return false; +} + +static const VMStateDescription vmstate_msr_hyperv_crash = { + .name = "cpu/msr_hyperv_crash", + .version_id = 1, + .minimum_version_id = 1, + .needed = hyperv_crash_enable_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params, + X86CPU, HV_X64_MSR_CRASH_PARAMS), + VMSTATE_END_OF_LIST() + } +}; + static bool avx512_needed(void *opaque) { X86CPU *cpu = opaque; @@ -842,6 +868,7 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_hypercall_hypercall, &vmstate_msr_hyperv_vapic, &vmstate_msr_hyperv_time, + &vmstate_msr_hyperv_crash, &vmstate_avx512, &vmstate_xss, NULL -- cgit v1.2.3-55-g7522 From da76ee76f78b9705e2a91e3c964aef28fecededb Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:38:58 +0300 Subject: hmp-commands-info: move info_cmds content out of monitor.c For moving target- and device-specific code from monitor.c, to beginning we move info_cmds content to hmp-commands-info.hx Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Peter Maydell Message-Id: <1441899541-1856-2-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- Makefile.target | 5 +- hmp-commands-info.hx | 741 +++++++++++++++++++++++++++++++++++++++++++++++++++ monitor.c | 389 +-------------------------- 3 files changed, 747 insertions(+), 388 deletions(-) create mode 100644 hmp-commands-info.hx diff --git a/Makefile.target b/Makefile.target index dc322942f4..92cff906ad 100644 --- a/Makefile.target +++ b/Makefile.target @@ -151,7 +151,7 @@ else obj-y += hw/$(TARGET_BASE_ARCH)/ endif -GENERATED_HEADERS += hmp-commands.h qmp-commands-old.h +GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h qmp-commands-old.h endif # CONFIG_SOFTMMU @@ -193,6 +193,9 @@ gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") +hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx + $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") + qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx new file mode 100644 index 0000000000..1d0906a1cd --- /dev/null +++ b/hmp-commands-info.hx @@ -0,0 +1,741 @@ +HXCOMM Use DEFHEADING() to define headings in both help text and texi +HXCOMM Text between STEXI and ETEXI are copied to texi version and +HXCOMM discarded from C version +HXCOMM DEF(command, args, callback, arg_string, help) is used to construct +HXCOMM monitor info commands +HXCOMM HXCOMM can be used for comments, discarded from both texi and C + +STEXI +@table @option +ETEXI + + { + .name = "version", + .args_type = "", + .params = "", + .help = "show the version of QEMU", + .mhandler.cmd = hmp_info_version, + }, + +STEXI +@item info version +@findex version +Show the version of QEMU. +ETEXI + + { + .name = "network", + .args_type = "", + .params = "", + .help = "show the network state", + .mhandler.cmd = hmp_info_network, + }, + +STEXI +@item info network +@findex network +Show the network state. +ETEXI + + { + .name = "chardev", + .args_type = "", + .params = "", + .help = "show the character devices", + .mhandler.cmd = hmp_info_chardev, + }, + +STEXI +@item info chardev +@findex chardev +Show the character devices. +ETEXI + + { + .name = "block", + .args_type = "nodes:-n,verbose:-v,device:B?", + .params = "[-n] [-v] [device]", + .help = "show info of one block device or all block devices " + "(-n: show named nodes; -v: show details)", + .mhandler.cmd = hmp_info_block, + }, + +STEXI +@item info block +@findex block +Show info of one block device or all block devices. +ETEXI + + { + .name = "blockstats", + .args_type = "", + .params = "", + .help = "show block device statistics", + .mhandler.cmd = hmp_info_blockstats, + }, + +STEXI +@item info blockstats +@findex blockstats +Show block device statistics. +ETEXI + + { + .name = "block-jobs", + .args_type = "", + .params = "", + .help = "show progress of ongoing block device operations", + .mhandler.cmd = hmp_info_block_jobs, + }, + +STEXI +@item info block-jobs +@findex block-jobs +Show progress of ongoing block device operations. +ETEXI + + { + .name = "registers", + .args_type = "", + .params = "", + .help = "show the cpu registers", + .mhandler.cmd = hmp_info_registers, + }, + +STEXI +@item info registers +@findex registers +Show the cpu registers. +ETEXI + + { + .name = "cpus", + .args_type = "", + .params = "", + .help = "show infos for each CPU", + .mhandler.cmd = hmp_info_cpus, + }, + +STEXI +@item info cpus +@findex cpus +Show infos for each CPU. +ETEXI + + { + .name = "history", + .args_type = "", + .params = "", + .help = "show the command line history", + .mhandler.cmd = hmp_info_history, + }, + +STEXI +@item info history +@findex history +Show the command line history. +ETEXI + +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \ + defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64)) + { + .name = "irq", + .args_type = "", + .params = "", + .help = "show the interrupts statistics (if available)", +#ifdef TARGET_SPARC + .mhandler.cmd = sun4m_hmp_info_irq, +#elif defined(TARGET_LM32) + .mhandler.cmd = lm32_hmp_info_irq, +#else + .mhandler.cmd = hmp_info_irq, +#endif + }, + +STEXI +@item info irq +@findex irq +Show the interrupts statistics (if available). +ETEXI + + { + .name = "pic", + .args_type = "", + .params = "", + .help = "show i8259 (PIC) state", +#ifdef TARGET_SPARC + .mhandler.cmd = sun4m_hmp_info_pic, +#elif defined(TARGET_LM32) + .mhandler.cmd = lm32_hmp_info_pic, +#else + .mhandler.cmd = hmp_info_pic, +#endif + }, +#endif + +STEXI +@item info pic +@findex pic +Show i8259 (PIC) state. +ETEXI + +#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ + defined(TARGET_PPC) || defined(TARGET_XTENSA) + { + .name = "tlb", + .args_type = "", + .params = "", + .help = "show virtual to physical memory mappings", + .mhandler.cmd = hmp_info_tlb, + }, +#endif + +STEXI +@item info tlb +@findex tlb +Show virtual to physical memory mappings. +ETEXI + +#if defined(TARGET_I386) + { + .name = "mem", + .args_type = "", + .params = "", + .help = "show the active virtual memory mappings", + .mhandler.cmd = hmp_info_mem, + }, +#endif + +STEXI +@item info mem +@findex mem +Show the active virtual memory mappings. +ETEXI + + { + .name = "mtree", + .args_type = "", + .params = "", + .help = "show memory tree", + .mhandler.cmd = hmp_info_mtree, + }, + +STEXI +@item info mtree +@findex mtree +Show memory tree. +ETEXI + + { + .name = "jit", + .args_type = "", + .params = "", + .help = "show dynamic compiler info", + .mhandler.cmd = hmp_info_jit, + }, + +STEXI +@item info jit +@findex jit +Show dynamic compiler info. +ETEXI + + { + .name = "opcount", + .args_type = "", + .params = "", + .help = "show dynamic compiler opcode counters", + .mhandler.cmd = hmp_info_opcount, + }, + +STEXI +@item info opcount +@findex opcount +Show dynamic compiler opcode counters +ETEXI + + { + .name = "kvm", + .args_type = "", + .params = "", + .help = "show KVM information", + .mhandler.cmd = hmp_info_kvm, + }, + +STEXI +@item info kvm +@findex kvm +Show KVM information. +ETEXI + + { + .name = "numa", + .args_type = "", + .params = "", + .help = "show NUMA information", + .mhandler.cmd = hmp_info_numa, + }, + +STEXI +@item info numa +@findex numa +Show NUMA information. +ETEXI + + { + .name = "usb", + .args_type = "", + .params = "", + .help = "show guest USB devices", + .mhandler.cmd = hmp_info_usb, + }, + +STEXI +@item info usb +@findex usb +Show guest USB devices. +ETEXI + + { + .name = "usbhost", + .args_type = "", + .params = "", + .help = "show host USB devices", + .mhandler.cmd = hmp_info_usbhost, + }, + +STEXI +@item info usbhost +@findex usbhost +Show host USB devices. +ETEXI + + { + .name = "profile", + .args_type = "", + .params = "", + .help = "show profiling information", + .mhandler.cmd = hmp_info_profile, + }, + +STEXI +@item info profile +@findex profile +Show profiling information. +ETEXI + + { + .name = "capture", + .args_type = "", + .params = "", + .help = "show capture information", + .mhandler.cmd = hmp_info_capture, + }, + +STEXI +@item info capture +@findex capture +Show capture information. +ETEXI + + { + .name = "snapshots", + .args_type = "", + .params = "", + .help = "show the currently saved VM snapshots", + .mhandler.cmd = hmp_info_snapshots, + }, + +STEXI +@item info snapshots +@findex snapshots +Show the currently saved VM snapshots. +ETEXI + + { + .name = "status", + .args_type = "", + .params = "", + .help = "show the current VM status (running|paused)", + .mhandler.cmd = hmp_info_status, + }, + +STEXI +@item info status +@findex status +Show the current VM status (running|paused). +ETEXI + + { + .name = "mice", + .args_type = "", + .params = "", + .help = "show which guest mouse is receiving events", + .mhandler.cmd = hmp_info_mice, + }, + +STEXI +@item info mice +@findex mice +Show which guest mouse is receiving events. +ETEXI + + { + .name = "vnc", + .args_type = "", + .params = "", + .help = "show the vnc server status", + .mhandler.cmd = hmp_info_vnc, + }, + +STEXI +@item info vnc +@findex vnc +Show the vnc server status. +ETEXI + +#if defined(CONFIG_SPICE) + { + .name = "spice", + .args_type = "", + .params = "", + .help = "show the spice server status", + .mhandler.cmd = hmp_info_spice, + }, +#endif + +STEXI +@item info spice +@findex spice +Show the spice server status. +ETEXI + + { + .name = "name", + .args_type = "", + .params = "", + .help = "show the current VM name", + .mhandler.cmd = hmp_info_name, + }, + +STEXI +@item info name +@findex name +Show the current VM name. +ETEXI + + { + .name = "uuid", + .args_type = "", + .params = "", + .help = "show the current VM UUID", + .mhandler.cmd = hmp_info_uuid, + }, + +STEXI +@item info uuid +@findex uuid +Show the current VM UUID. +ETEXI + + { + .name = "cpustats", + .args_type = "", + .params = "", + .help = "show CPU statistics", + .mhandler.cmd = hmp_info_cpustats, + }, + +STEXI +@item info cpustats +@findex cpustats +Show CPU statistics. +ETEXI + +#if defined(CONFIG_SLIRP) + { + .name = "usernet", + .args_type = "", + .params = "", + .help = "show user network stack connection states", + .mhandler.cmd = hmp_info_usernet, + }, +#endif + +STEXI +@item info usernet +@findex usernet +Show user network stack connection states. +ETEXI + + { + .name = "migrate", + .args_type = "", + .params = "", + .help = "show migration status", + .mhandler.cmd = hmp_info_migrate, + }, + +STEXI +@item info migrate +@findex migrate +Show migration status. +ETEXI + + { + .name = "migrate_capabilities", + .args_type = "", + .params = "", + .help = "show current migration capabilities", + .mhandler.cmd = hmp_info_migrate_capabilities, + }, + +STEXI +@item info migrate_capabilities +@findex migrate_capabilities +Show current migration capabilities. +ETEXI + + { + .name = "migrate_parameters", + .args_type = "", + .params = "", + .help = "show current migration parameters", + .mhandler.cmd = hmp_info_migrate_parameters, + }, + +STEXI +@item info migrate_parameters +@findex migrate_parameters +Show current migration parameters. +ETEXI + + { + .name = "migrate_cache_size", + .args_type = "", + .params = "", + .help = "show current migration xbzrle cache size", + .mhandler.cmd = hmp_info_migrate_cache_size, + }, + +STEXI +@item info migrate_cache_size +@findex migrate_cache_size +Show current migration xbzrle cache size. +ETEXI + + { + .name = "balloon", + .args_type = "", + .params = "", + .help = "show balloon information", + .mhandler.cmd = hmp_info_balloon, + }, + +STEXI +@item info balloon +@findex balloon +Show balloon information. +ETEXI + + { + .name = "qtree", + .args_type = "", + .params = "", + .help = "show device tree", + .mhandler.cmd = hmp_info_qtree, + }, + +STEXI +@item info qtree +@findex qtree +Show device tree. +ETEXI + + { + .name = "qdm", + .args_type = "", + .params = "", + .help = "show qdev device model list", + .mhandler.cmd = hmp_info_qdm, + }, + +STEXI +@item info qdm +@findex qdm +Show qdev device model list. +ETEXI + + { + .name = "qom-tree", + .args_type = "path:s?", + .params = "[path]", + .help = "show QOM composition tree", + .mhandler.cmd = hmp_info_qom_tree, + }, + +STEXI +@item info qom-tree +@findex qom-tree +Show QOM composition tree. +ETEXI + + { + .name = "roms", + .args_type = "", + .params = "", + .help = "show roms", + .mhandler.cmd = hmp_info_roms, + }, + +STEXI +@item info roms +@findex roms +Show roms. +ETEXI + + { + .name = "trace-events", + .args_type = "", + .params = "", + .help = "show available trace-events & their state", + .mhandler.cmd = hmp_info_trace_events, + }, + +STEXI +@item info trace-events +@findex trace-events +Show available trace-events & their state. +ETEXI + + { + .name = "tpm", + .args_type = "", + .params = "", + .help = "show the TPM device", + .mhandler.cmd = hmp_info_tpm, + }, + +STEXI +@item info tpm +@findex tpm +Show the TPM device. +ETEXI + + { + .name = "memdev", + .args_type = "", + .params = "", + .help = "show memory backends", + .mhandler.cmd = hmp_info_memdev, + }, + +STEXI +@item info memdev +@findex memdev +Show memory backends +ETEXI + + { + .name = "memory-devices", + .args_type = "", + .params = "", + .help = "show memory devices", + .mhandler.cmd = hmp_info_memory_devices, + }, + +STEXI +@item info memory-devices +@findex memory-devices +Show memory devices. +ETEXI + + { + .name = "iothreads", + .args_type = "", + .params = "", + .help = "show iothreads", + .mhandler.cmd = hmp_info_iothreads, + }, + +STEXI +@item info iothreads +@findex iothreads +Show iothread's identifiers. +ETEXI + + { + .name = "rocker", + .args_type = "name:s", + .params = "name", + .help = "Show rocker switch", + .mhandler.cmd = hmp_rocker, + }, + +STEXI +@item info rocker @var{name} +@findex rocker +Show rocker switch. +ETEXI + + { + .name = "rocker-ports", + .args_type = "name:s", + .params = "name", + .help = "Show rocker ports", + .mhandler.cmd = hmp_rocker_ports, + }, + +STEXI +@item info rocker_ports @var{name}-ports +@findex ocker-ports +Show rocker ports. +ETEXI + + { + .name = "rocker-of-dpa-flows", + .args_type = "name:s,tbl_id:i?", + .params = "name [tbl_id]", + .help = "Show rocker OF-DPA flow tables", + .mhandler.cmd = hmp_rocker_of_dpa_flows, + }, + +STEXI +@item info rocker_of_dpa_flows @var{name} [@var{tbl_id}] +@findex rocker-of-dpa-flows +Show rocker OF-DPA flow tables. +ETEXI + + { + .name = "rocker-of-dpa-groups", + .args_type = "name:s,type:i?", + .params = "name [type]", + .help = "Show rocker OF-DPA groups", + .mhandler.cmd = hmp_rocker_of_dpa_groups, + }, + +STEXI +@item info rocker-of-dpa-groups @var{name} [@var{type}] +@findex rocker-of-dpa-groups +Show rocker OF-DPA groups. +ETEXI + +#if defined(TARGET_S390X) + { + .name = "skeys", + .args_type = "addr:l", + .params = "address", + .help = "Display the value of a storage key", + .mhandler.cmd = hmp_info_skeys, + }, +#endif + +STEXI +@item info skeys @var{address} +@findex skeys +Display the value of a storage key (s390 only) +ETEXI + +STEXI +@end table +ETEXI diff --git a/monitor.c b/monitor.c index 5455ab9de0..f25b128c4d 100644 --- a/monitor.c +++ b/monitor.c @@ -2513,393 +2513,8 @@ int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp) /* Please update hmp-commands.hx when adding or changing commands */ static mon_cmd_t info_cmds[] = { - { - .name = "version", - .args_type = "", - .params = "", - .help = "show the version of QEMU", - .mhandler.cmd = hmp_info_version, - }, - { - .name = "network", - .args_type = "", - .params = "", - .help = "show the network state", - .mhandler.cmd = hmp_info_network, - }, - { - .name = "chardev", - .args_type = "", - .params = "", - .help = "show the character devices", - .mhandler.cmd = hmp_info_chardev, - }, - { - .name = "block", - .args_type = "nodes:-n,verbose:-v,device:B?", - .params = "[-n] [-v] [device]", - .help = "show info of one block device or all block devices " - "(-n: show named nodes; -v: show details)", - .mhandler.cmd = hmp_info_block, - }, - { - .name = "blockstats", - .args_type = "", - .params = "", - .help = "show block device statistics", - .mhandler.cmd = hmp_info_blockstats, - }, - { - .name = "block-jobs", - .args_type = "", - .params = "", - .help = "show progress of ongoing block device operations", - .mhandler.cmd = hmp_info_block_jobs, - }, - { - .name = "registers", - .args_type = "", - .params = "", - .help = "show the cpu registers", - .mhandler.cmd = hmp_info_registers, - }, - { - .name = "cpus", - .args_type = "", - .params = "", - .help = "show infos for each CPU", - .mhandler.cmd = hmp_info_cpus, - }, - { - .name = "history", - .args_type = "", - .params = "", - .help = "show the command line history", - .mhandler.cmd = hmp_info_history, - }, -#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \ - defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64)) - { - .name = "irq", - .args_type = "", - .params = "", - .help = "show the interrupts statistics (if available)", -#ifdef TARGET_SPARC - .mhandler.cmd = sun4m_hmp_info_irq, -#elif defined(TARGET_LM32) - .mhandler.cmd = lm32_hmp_info_irq, -#else - .mhandler.cmd = hmp_info_irq, -#endif - }, - { - .name = "pic", - .args_type = "", - .params = "", - .help = "show i8259 (PIC) state", -#ifdef TARGET_SPARC - .mhandler.cmd = sun4m_hmp_info_pic, -#elif defined(TARGET_LM32) - .mhandler.cmd = lm32_hmp_info_pic, -#else - .mhandler.cmd = hmp_info_pic, -#endif - }, -#endif - { - .name = "pci", - .args_type = "", - .params = "", - .help = "show PCI info", - .mhandler.cmd = hmp_info_pci, - }, -#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ - defined(TARGET_PPC) || defined(TARGET_XTENSA) - { - .name = "tlb", - .args_type = "", - .params = "", - .help = "show virtual to physical memory mappings", - .mhandler.cmd = hmp_info_tlb, - }, -#endif -#if defined(TARGET_I386) - { - .name = "mem", - .args_type = "", - .params = "", - .help = "show the active virtual memory mappings", - .mhandler.cmd = hmp_info_mem, - }, -#endif - { - .name = "mtree", - .args_type = "", - .params = "", - .help = "show memory tree", - .mhandler.cmd = hmp_info_mtree, - }, - { - .name = "jit", - .args_type = "", - .params = "", - .help = "show dynamic compiler info", - .mhandler.cmd = hmp_info_jit, - }, - { - .name = "opcount", - .args_type = "", - .params = "", - .help = "show dynamic compiler opcode counters", - .mhandler.cmd = hmp_info_opcount, - }, - { - .name = "kvm", - .args_type = "", - .params = "", - .help = "show KVM information", - .mhandler.cmd = hmp_info_kvm, - }, - { - .name = "numa", - .args_type = "", - .params = "", - .help = "show NUMA information", - .mhandler.cmd = hmp_info_numa, - }, - { - .name = "usb", - .args_type = "", - .params = "", - .help = "show guest USB devices", - .mhandler.cmd = hmp_info_usb, - }, - { - .name = "usbhost", - .args_type = "", - .params = "", - .help = "show host USB devices", - .mhandler.cmd = hmp_info_usbhost, - }, - { - .name = "profile", - .args_type = "", - .params = "", - .help = "show profiling information", - .mhandler.cmd = hmp_info_profile, - }, - { - .name = "capture", - .args_type = "", - .params = "", - .help = "show capture information", - .mhandler.cmd = hmp_info_capture, - }, - { - .name = "snapshots", - .args_type = "", - .params = "", - .help = "show the currently saved VM snapshots", - .mhandler.cmd = hmp_info_snapshots, - }, - { - .name = "status", - .args_type = "", - .params = "", - .help = "show the current VM status (running|paused)", - .mhandler.cmd = hmp_info_status, - }, - { - .name = "mice", - .args_type = "", - .params = "", - .help = "show which guest mouse is receiving events", - .mhandler.cmd = hmp_info_mice, - }, - { - .name = "vnc", - .args_type = "", - .params = "", - .help = "show the vnc server status", - .mhandler.cmd = hmp_info_vnc, - }, -#if defined(CONFIG_SPICE) - { - .name = "spice", - .args_type = "", - .params = "", - .help = "show the spice server status", - .mhandler.cmd = hmp_info_spice, - }, -#endif - { - .name = "name", - .args_type = "", - .params = "", - .help = "show the current VM name", - .mhandler.cmd = hmp_info_name, - }, - { - .name = "uuid", - .args_type = "", - .params = "", - .help = "show the current VM UUID", - .mhandler.cmd = hmp_info_uuid, - }, - { - .name = "cpustats", - .args_type = "", - .params = "", - .help = "show CPU statistics", - .mhandler.cmd = hmp_info_cpustats, - }, -#if defined(CONFIG_SLIRP) - { - .name = "usernet", - .args_type = "", - .params = "", - .help = "show user network stack connection states", - .mhandler.cmd = hmp_info_usernet, - }, -#endif - { - .name = "migrate", - .args_type = "", - .params = "", - .help = "show migration status", - .mhandler.cmd = hmp_info_migrate, - }, - { - .name = "migrate_capabilities", - .args_type = "", - .params = "", - .help = "show current migration capabilities", - .mhandler.cmd = hmp_info_migrate_capabilities, - }, - { - .name = "migrate_parameters", - .args_type = "", - .params = "", - .help = "show current migration parameters", - .mhandler.cmd = hmp_info_migrate_parameters, - }, - { - .name = "migrate_cache_size", - .args_type = "", - .params = "", - .help = "show current migration xbzrle cache size", - .mhandler.cmd = hmp_info_migrate_cache_size, - }, - { - .name = "balloon", - .args_type = "", - .params = "", - .help = "show balloon information", - .mhandler.cmd = hmp_info_balloon, - }, - { - .name = "qtree", - .args_type = "", - .params = "", - .help = "show device tree", - .mhandler.cmd = hmp_info_qtree, - }, - { - .name = "qdm", - .args_type = "", - .params = "", - .help = "show qdev device model list", - .mhandler.cmd = hmp_info_qdm, - }, - { - .name = "qom-tree", - .args_type = "path:s?", - .params = "[path]", - .help = "show QOM composition tree", - .mhandler.cmd = hmp_info_qom_tree, - }, - { - .name = "roms", - .args_type = "", - .params = "", - .help = "show roms", - .mhandler.cmd = hmp_info_roms, - }, - { - .name = "trace-events", - .args_type = "", - .params = "", - .help = "show available trace-events & their state", - .mhandler.cmd = hmp_info_trace_events, - }, - { - .name = "tpm", - .args_type = "", - .params = "", - .help = "show the TPM device", - .mhandler.cmd = hmp_info_tpm, - }, - { - .name = "memdev", - .args_type = "", - .params = "", - .help = "show memory backends", - .mhandler.cmd = hmp_info_memdev, - }, - { - .name = "memory-devices", - .args_type = "", - .params = "", - .help = "show memory devices", - .mhandler.cmd = hmp_info_memory_devices, - }, - { - .name = "iothreads", - .args_type = "", - .params = "", - .help = "show iothreads", - .mhandler.cmd = hmp_info_iothreads, - }, - { - .name = "rocker", - .args_type = "name:s", - .params = "name", - .help = "Show rocker switch", - .mhandler.cmd = hmp_rocker, - }, - { - .name = "rocker-ports", - .args_type = "name:s", - .params = "name", - .help = "Show rocker ports", - .mhandler.cmd = hmp_rocker_ports, - }, - { - .name = "rocker-of-dpa-flows", - .args_type = "name:s,tbl_id:i?", - .params = "name [tbl_id]", - .help = "Show rocker OF-DPA flow tables", - .mhandler.cmd = hmp_rocker_of_dpa_flows, - }, - { - .name = "rocker-of-dpa-groups", - .args_type = "name:s,type:i?", - .params = "name [type]", - .help = "Show rocker OF-DPA groups", - .mhandler.cmd = hmp_rocker_of_dpa_groups, - }, -#if defined(TARGET_S390X) - { - .name = "skeys", - .args_type = "addr:l", - .params = "address", - .help = "Display the value of a storage key", - .mhandler.cmd = hmp_info_skeys, - }, -#endif - { - .name = NULL, - }, +#include "hmp-commands-info.h" + { NULL, NULL, }, }; /* mon_cmds and info_cmds would be sorted at runtime */ -- cgit v1.2.3-55-g7522 From bf957284006b6325e6ed64fd839c237c15b42029 Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:38:59 +0300 Subject: monitor: remove target-specific code from monitor.c Move target-specific code out of /monitor.c to /target-*/monitor.c, this will avoid code cluttering and using random ifdeffery. The solution is quite simple, but solves the issue of the separation of target-specific code from monitor. Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Peter Maydell Message-Id: <1441899541-1856-3-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- include/monitor/hmp-target.h | 45 +++ include/qemu/typedefs.h | 1 + monitor.c | 860 +------------------------------------------ stubs/Makefile.objs | 1 + stubs/target-monitor-defs.c | 9 + target-i386/Makefile.objs | 2 +- target-i386/monitor.c | 494 +++++++++++++++++++++++++ target-ppc/Makefile.objs | 2 +- target-ppc/monitor.c | 255 +++++++++++++ target-sh4/Makefile.objs | 1 + target-sh4/monitor.c | 52 +++ target-sparc/Makefile.objs | 2 +- target-sparc/monitor.c | 158 ++++++++ target-xtensa/Makefile.objs | 1 + target-xtensa/monitor.c | 34 ++ 15 files changed, 1062 insertions(+), 855 deletions(-) create mode 100644 include/monitor/hmp-target.h create mode 100644 stubs/target-monitor-defs.c create mode 100644 target-i386/monitor.c create mode 100644 target-ppc/monitor.c create mode 100644 target-sh4/monitor.c create mode 100644 target-sparc/monitor.c create mode 100644 target-xtensa/monitor.c diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h new file mode 100644 index 0000000000..611541d1cb --- /dev/null +++ b/include/monitor/hmp-target.h @@ -0,0 +1,45 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MONITOR_COMMON_H +#define MONITOR_COMMON_H + +#define MD_TLONG 0 +#define MD_I32 1 + +struct MonitorDef { + const char *name; + int offset; + target_long (*get_value)(const struct MonitorDef *md, int val); + int type; +}; + +const MonitorDef *target_monitor_defs(void); + +CPUArchState *mon_get_cpu_env(void); + +void hmp_info_mem(Monitor *mon, const QDict *qdict); +void hmp_info_tlb(Monitor *mon, const QDict *qdict); +void hmp_mce(Monitor *mon, const QDict *qdict); + +#endif /* MONITOR_COMMON */ diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index f8a9dd6f10..97ac727476 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -80,5 +80,6 @@ typedef struct SSIBus SSIBus; typedef struct uWireSlave uWireSlave; typedef struct VirtIODevice VirtIODevice; typedef struct Visitor Visitor; +typedef struct MonitorDef MonitorDef; #endif /* QEMU_TYPEDEFS_H */ diff --git a/monitor.c b/monitor.c index f25b128c4d..b4578cb8ea 100644 --- a/monitor.c +++ b/monitor.c @@ -63,6 +63,7 @@ #include "cpu.h" #include "trace.h" #include "trace/control.h" +#include "monitor/hmp-target.h" #ifdef CONFIG_TRACE_SIMPLE #include "trace/simple.h" #endif @@ -950,7 +951,7 @@ static CPUState *mon_get_cpu(void) return cur_mon->mon_cpu; } -static CPUArchState *mon_get_cpu_env(void) +CPUArchState *mon_get_cpu_env(void) { return mon_get_cpu()->env_ptr; } @@ -1424,442 +1425,6 @@ static void hmp_boot_set(Monitor *mon, const QDict *qdict) } } -#if defined(TARGET_I386) -static void print_pte(Monitor *mon, hwaddr addr, - hwaddr pte, - hwaddr mask) -{ -#ifdef TARGET_X86_64 - if (addr & (1ULL << 47)) { - addr |= -1LL << 48; - } -#endif - monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx - " %c%c%c%c%c%c%c%c%c\n", - addr, - pte & mask, - pte & PG_NX_MASK ? 'X' : '-', - pte & PG_GLOBAL_MASK ? 'G' : '-', - pte & PG_PSE_MASK ? 'P' : '-', - pte & PG_DIRTY_MASK ? 'D' : '-', - pte & PG_ACCESSED_MASK ? 'A' : '-', - pte & PG_PCD_MASK ? 'C' : '-', - pte & PG_PWT_MASK ? 'T' : '-', - pte & PG_USER_MASK ? 'U' : '-', - pte & PG_RW_MASK ? 'W' : '-'); -} - -static void tlb_info_32(Monitor *mon, CPUArchState *env) -{ - unsigned int l1, l2; - uint32_t pgd, pde, pte; - - pgd = env->cr[3] & ~0xfff; - for(l1 = 0; l1 < 1024; l1++) { - cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); - pde = le32_to_cpu(pde); - if (pde & PG_PRESENT_MASK) { - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { - /* 4M pages */ - print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1)); - } else { - for(l2 = 0; l2 < 1024; l2++) { - cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); - pte = le32_to_cpu(pte); - if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 22) + (l2 << 12), - pte & ~PG_PSE_MASK, - ~0xfff); - } - } - } - } - } -} - -static void tlb_info_pae32(Monitor *mon, CPUArchState *env) -{ - unsigned int l1, l2, l3; - uint64_t pdpe, pde, pte; - uint64_t pdp_addr, pd_addr, pt_addr; - - pdp_addr = env->cr[3] & ~0x1f; - for (l1 = 0; l1 < 4; l1++) { - cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); - pdpe = le64_to_cpu(pdpe); - if (pdpe & PG_PRESENT_MASK) { - pd_addr = pdpe & 0x3fffffffff000ULL; - for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); - pde = le64_to_cpu(pde); - if (pde & PG_PRESENT_MASK) { - if (pde & PG_PSE_MASK) { - /* 2M pages with PAE, CR4.PSE is ignored */ - print_pte(mon, (l1 << 30 ) + (l2 << 21), pde, - ~((hwaddr)(1 << 20) - 1)); - } else { - pt_addr = pde & 0x3fffffffff000ULL; - for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); - pte = le64_to_cpu(pte); - if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 30 ) + (l2 << 21) - + (l3 << 12), - pte & ~PG_PSE_MASK, - ~(hwaddr)0xfff); - } - } - } - } - } - } - } -} - -#ifdef TARGET_X86_64 -static void tlb_info_64(Monitor *mon, CPUArchState *env) -{ - uint64_t l1, l2, l3, l4; - uint64_t pml4e, pdpe, pde, pte; - uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr; - - pml4_addr = env->cr[3] & 0x3fffffffff000ULL; - for (l1 = 0; l1 < 512; l1++) { - cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); - pml4e = le64_to_cpu(pml4e); - if (pml4e & PG_PRESENT_MASK) { - pdp_addr = pml4e & 0x3fffffffff000ULL; - for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); - pdpe = le64_to_cpu(pdpe); - if (pdpe & PG_PRESENT_MASK) { - if (pdpe & PG_PSE_MASK) { - /* 1G pages, CR4.PSE is ignored */ - print_pte(mon, (l1 << 39) + (l2 << 30), pdpe, - 0x3ffffc0000000ULL); - } else { - pd_addr = pdpe & 0x3fffffffff000ULL; - for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); - pde = le64_to_cpu(pde); - if (pde & PG_PRESENT_MASK) { - if (pde & PG_PSE_MASK) { - /* 2M pages, CR4.PSE is ignored */ - print_pte(mon, (l1 << 39) + (l2 << 30) + - (l3 << 21), pde, - 0x3ffffffe00000ULL); - } else { - pt_addr = pde & 0x3fffffffff000ULL; - for (l4 = 0; l4 < 512; l4++) { - cpu_physical_memory_read(pt_addr - + l4 * 8, - &pte, 8); - pte = le64_to_cpu(pte); - if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 39) + - (l2 << 30) + - (l3 << 21) + (l4 << 12), - pte & ~PG_PSE_MASK, - 0x3fffffffff000ULL); - } - } - } - } - } - } - } - } - } - } -} -#endif - -static void hmp_info_tlb(Monitor *mon, const QDict *qdict) -{ - CPUArchState *env; - - env = mon_get_cpu_env(); - - if (!(env->cr[0] & CR0_PG_MASK)) { - monitor_printf(mon, "PG disabled\n"); - return; - } - if (env->cr[4] & CR4_PAE_MASK) { -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - tlb_info_64(mon, env); - } else -#endif - { - tlb_info_pae32(mon, env); - } - } else { - tlb_info_32(mon, env); - } -} - -static void mem_print(Monitor *mon, hwaddr *pstart, - int *plast_prot, - hwaddr end, int prot) -{ - int prot1; - prot1 = *plast_prot; - if (prot != prot1) { - if (*pstart != -1) { - monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " " - TARGET_FMT_plx " %c%c%c\n", - *pstart, end, end - *pstart, - prot1 & PG_USER_MASK ? 'u' : '-', - 'r', - prot1 & PG_RW_MASK ? 'w' : '-'); - } - if (prot != 0) - *pstart = end; - else - *pstart = -1; - *plast_prot = prot; - } -} - -static void mem_info_32(Monitor *mon, CPUArchState *env) -{ - unsigned int l1, l2; - int prot, last_prot; - uint32_t pgd, pde, pte; - hwaddr start, end; - - pgd = env->cr[3] & ~0xfff; - last_prot = 0; - start = -1; - for(l1 = 0; l1 < 1024; l1++) { - cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); - pde = le32_to_cpu(pde); - end = l1 << 22; - if (pde & PG_PRESENT_MASK) { - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { - prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); - mem_print(mon, &start, &last_prot, end, prot); - } else { - for(l2 = 0; l2 < 1024; l2++) { - cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); - pte = le32_to_cpu(pte); - end = (l1 << 22) + (l2 << 12); - if (pte & PG_PRESENT_MASK) { - prot = pte & pde & - (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); - } else { - prot = 0; - } - mem_print(mon, &start, &last_prot, end, prot); - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - /* Flush last range */ - mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0); -} - -static void mem_info_pae32(Monitor *mon, CPUArchState *env) -{ - unsigned int l1, l2, l3; - int prot, last_prot; - uint64_t pdpe, pde, pte; - uint64_t pdp_addr, pd_addr, pt_addr; - hwaddr start, end; - - pdp_addr = env->cr[3] & ~0x1f; - last_prot = 0; - start = -1; - for (l1 = 0; l1 < 4; l1++) { - cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); - pdpe = le64_to_cpu(pdpe); - end = l1 << 30; - if (pdpe & PG_PRESENT_MASK) { - pd_addr = pdpe & 0x3fffffffff000ULL; - for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); - pde = le64_to_cpu(pde); - end = (l1 << 30) + (l2 << 21); - if (pde & PG_PRESENT_MASK) { - if (pde & PG_PSE_MASK) { - prot = pde & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); - mem_print(mon, &start, &last_prot, end, prot); - } else { - pt_addr = pde & 0x3fffffffff000ULL; - for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); - pte = le64_to_cpu(pte); - end = (l1 << 30) + (l2 << 21) + (l3 << 12); - if (pte & PG_PRESENT_MASK) { - prot = pte & pde & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); - } else { - prot = 0; - } - mem_print(mon, &start, &last_prot, end, prot); - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - /* Flush last range */ - mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0); -} - - -#ifdef TARGET_X86_64 -static void mem_info_64(Monitor *mon, CPUArchState *env) -{ - int prot, last_prot; - uint64_t l1, l2, l3, l4; - uint64_t pml4e, pdpe, pde, pte; - uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end; - - pml4_addr = env->cr[3] & 0x3fffffffff000ULL; - last_prot = 0; - start = -1; - for (l1 = 0; l1 < 512; l1++) { - cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); - pml4e = le64_to_cpu(pml4e); - end = l1 << 39; - if (pml4e & PG_PRESENT_MASK) { - pdp_addr = pml4e & 0x3fffffffff000ULL; - for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); - pdpe = le64_to_cpu(pdpe); - end = (l1 << 39) + (l2 << 30); - if (pdpe & PG_PRESENT_MASK) { - if (pdpe & PG_PSE_MASK) { - prot = pdpe & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); - prot &= pml4e; - mem_print(mon, &start, &last_prot, end, prot); - } else { - pd_addr = pdpe & 0x3fffffffff000ULL; - for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); - pde = le64_to_cpu(pde); - end = (l1 << 39) + (l2 << 30) + (l3 << 21); - if (pde & PG_PRESENT_MASK) { - if (pde & PG_PSE_MASK) { - prot = pde & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); - prot &= pml4e & pdpe; - mem_print(mon, &start, &last_prot, end, prot); - } else { - pt_addr = pde & 0x3fffffffff000ULL; - for (l4 = 0; l4 < 512; l4++) { - cpu_physical_memory_read(pt_addr - + l4 * 8, - &pte, 8); - pte = le64_to_cpu(pte); - end = (l1 << 39) + (l2 << 30) + - (l3 << 21) + (l4 << 12); - if (pte & PG_PRESENT_MASK) { - prot = pte & (PG_USER_MASK | PG_RW_MASK | - PG_PRESENT_MASK); - prot &= pml4e & pdpe & pde; - } else { - prot = 0; - } - mem_print(mon, &start, &last_prot, end, prot); - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - } else { - prot = 0; - mem_print(mon, &start, &last_prot, end, prot); - } - } - /* Flush last range */ - mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0); -} -#endif - -static void hmp_info_mem(Monitor *mon, const QDict *qdict) -{ - CPUArchState *env; - - env = mon_get_cpu_env(); - - if (!(env->cr[0] & CR0_PG_MASK)) { - monitor_printf(mon, "PG disabled\n"); - return; - } - if (env->cr[4] & CR4_PAE_MASK) { -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - mem_info_64(mon, env); - } else -#endif - { - mem_info_pae32(mon, env); - } - } else { - mem_info_32(mon, env); - } -} -#endif - -#if defined(TARGET_SH4) - -static void print_tlb(Monitor *mon, int idx, tlb_t *tlb) -{ - monitor_printf(mon, " tlb%i:\t" - "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t" - "v=%hhu shared=%hhu cached=%hhu prot=%hhu " - "dirty=%hhu writethrough=%hhu\n", - idx, - tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size, - tlb->v, tlb->sh, tlb->c, tlb->pr, - tlb->d, tlb->wt); -} - -static void hmp_info_tlb(Monitor *mon, const QDict *qdict) -{ - CPUArchState *env = mon_get_cpu_env(); - int i; - - monitor_printf (mon, "ITLB:\n"); - for (i = 0 ; i < ITLB_SIZE ; i++) - print_tlb (mon, i, &env->itlb[i]); - monitor_printf (mon, "UTLB:\n"); - for (i = 0 ; i < UTLB_SIZE ; i++) - print_tlb (mon, i, &env->utlb[i]); -} - -#endif - -#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA) -static void hmp_info_tlb(Monitor *mon, const QDict *qdict) -{ - CPUArchState *env1 = mon_get_cpu_env(); - - dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1); -} -#endif - static void hmp_info_mtree(Monitor *mon, const QDict *qdict) { mtree_info((fprintf_function)monitor_printf, mon); @@ -2070,31 +1635,6 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict) } } -#if defined(TARGET_I386) -static void hmp_mce(Monitor *mon, const QDict *qdict) -{ - X86CPU *cpu; - CPUState *cs; - int cpu_index = qdict_get_int(qdict, "cpu_index"); - int bank = qdict_get_int(qdict, "bank"); - uint64_t status = qdict_get_int(qdict, "status"); - uint64_t mcg_status = qdict_get_int(qdict, "mcg_status"); - uint64_t addr = qdict_get_int(qdict, "addr"); - uint64_t misc = qdict_get_int(qdict, "misc"); - int flags = MCE_INJECT_UNCOND_AO; - - if (qdict_get_try_bool(qdict, "broadcast", false)) { - flags |= MCE_INJECT_BROADCAST; - } - cs = qemu_get_cpu(cpu_index); - if (cs != NULL) { - cpu = X86_CPU(cs); - cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc, - flags); - } -} -#endif - void qmp_getfd(const char *fdname, Error **errp) { mon_fd_t *monfd; @@ -2533,394 +2073,6 @@ static const mon_cmd_t qmp_cmds[] = { static const char *pch; static sigjmp_buf expr_env; -#define MD_TLONG 0 -#define MD_I32 1 - -typedef struct MonitorDef { - const char *name; - int offset; - target_long (*get_value)(const struct MonitorDef *md, int val); - int type; -} MonitorDef; - -#if defined(TARGET_I386) -static target_long monitor_get_pc (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return env->eip + env->segs[R_CS].base; -} -#endif - -#if defined(TARGET_PPC) -static target_long monitor_get_ccr (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - unsigned int u; - int i; - - u = 0; - for (i = 0; i < 8; i++) - u |= env->crf[i] << (32 - (4 * (i + 1))); - - return u; -} - -static target_long monitor_get_msr (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return env->msr; -} - -static target_long monitor_get_xer (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return env->xer; -} - -static target_long monitor_get_decr (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return cpu_ppc_load_decr(env); -} - -static target_long monitor_get_tbu (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return cpu_ppc_load_tbu(env); -} - -static target_long monitor_get_tbl (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return cpu_ppc_load_tbl(env); -} -#endif - -#if defined(TARGET_SPARC) -#ifndef TARGET_SPARC64 -static target_long monitor_get_psr (const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - - return cpu_get_psr(env); -} -#endif - -static target_long monitor_get_reg(const struct MonitorDef *md, int val) -{ - CPUArchState *env = mon_get_cpu_env(); - return env->regwptr[val]; -} -#endif - -static const MonitorDef monitor_defs[] = { -#ifdef TARGET_I386 - -#define SEG(name, seg) \ - { name, offsetof(CPUX86State, segs[seg].selector), NULL, MD_I32 },\ - { name ".base", offsetof(CPUX86State, segs[seg].base) },\ - { name ".limit", offsetof(CPUX86State, segs[seg].limit), NULL, MD_I32 }, - - { "eax", offsetof(CPUX86State, regs[0]) }, - { "ecx", offsetof(CPUX86State, regs[1]) }, - { "edx", offsetof(CPUX86State, regs[2]) }, - { "ebx", offsetof(CPUX86State, regs[3]) }, - { "esp|sp", offsetof(CPUX86State, regs[4]) }, - { "ebp|fp", offsetof(CPUX86State, regs[5]) }, - { "esi", offsetof(CPUX86State, regs[6]) }, - { "edi", offsetof(CPUX86State, regs[7]) }, -#ifdef TARGET_X86_64 - { "r8", offsetof(CPUX86State, regs[8]) }, - { "r9", offsetof(CPUX86State, regs[9]) }, - { "r10", offsetof(CPUX86State, regs[10]) }, - { "r11", offsetof(CPUX86State, regs[11]) }, - { "r12", offsetof(CPUX86State, regs[12]) }, - { "r13", offsetof(CPUX86State, regs[13]) }, - { "r14", offsetof(CPUX86State, regs[14]) }, - { "r15", offsetof(CPUX86State, regs[15]) }, -#endif - { "eflags", offsetof(CPUX86State, eflags) }, - { "eip", offsetof(CPUX86State, eip) }, - SEG("cs", R_CS) - SEG("ds", R_DS) - SEG("es", R_ES) - SEG("ss", R_SS) - SEG("fs", R_FS) - SEG("gs", R_GS) - { "pc", 0, monitor_get_pc, }, -#elif defined(TARGET_PPC) - /* General purpose registers */ - { "r0", offsetof(CPUPPCState, gpr[0]) }, - { "r1", offsetof(CPUPPCState, gpr[1]) }, - { "r2", offsetof(CPUPPCState, gpr[2]) }, - { "r3", offsetof(CPUPPCState, gpr[3]) }, - { "r4", offsetof(CPUPPCState, gpr[4]) }, - { "r5", offsetof(CPUPPCState, gpr[5]) }, - { "r6", offsetof(CPUPPCState, gpr[6]) }, - { "r7", offsetof(CPUPPCState, gpr[7]) }, - { "r8", offsetof(CPUPPCState, gpr[8]) }, - { "r9", offsetof(CPUPPCState, gpr[9]) }, - { "r10", offsetof(CPUPPCState, gpr[10]) }, - { "r11", offsetof(CPUPPCState, gpr[11]) }, - { "r12", offsetof(CPUPPCState, gpr[12]) }, - { "r13", offsetof(CPUPPCState, gpr[13]) }, - { "r14", offsetof(CPUPPCState, gpr[14]) }, - { "r15", offsetof(CPUPPCState, gpr[15]) }, - { "r16", offsetof(CPUPPCState, gpr[16]) }, - { "r17", offsetof(CPUPPCState, gpr[17]) }, - { "r18", offsetof(CPUPPCState, gpr[18]) }, - { "r19", offsetof(CPUPPCState, gpr[19]) }, - { "r20", offsetof(CPUPPCState, gpr[20]) }, - { "r21", offsetof(CPUPPCState, gpr[21]) }, - { "r22", offsetof(CPUPPCState, gpr[22]) }, - { "r23", offsetof(CPUPPCState, gpr[23]) }, - { "r24", offsetof(CPUPPCState, gpr[24]) }, - { "r25", offsetof(CPUPPCState, gpr[25]) }, - { "r26", offsetof(CPUPPCState, gpr[26]) }, - { "r27", offsetof(CPUPPCState, gpr[27]) }, - { "r28", offsetof(CPUPPCState, gpr[28]) }, - { "r29", offsetof(CPUPPCState, gpr[29]) }, - { "r30", offsetof(CPUPPCState, gpr[30]) }, - { "r31", offsetof(CPUPPCState, gpr[31]) }, - /* Floating point registers */ - { "f0", offsetof(CPUPPCState, fpr[0]) }, - { "f1", offsetof(CPUPPCState, fpr[1]) }, - { "f2", offsetof(CPUPPCState, fpr[2]) }, - { "f3", offsetof(CPUPPCState, fpr[3]) }, - { "f4", offsetof(CPUPPCState, fpr[4]) }, - { "f5", offsetof(CPUPPCState, fpr[5]) }, - { "f6", offsetof(CPUPPCState, fpr[6]) }, - { "f7", offsetof(CPUPPCState, fpr[7]) }, - { "f8", offsetof(CPUPPCState, fpr[8]) }, - { "f9", offsetof(CPUPPCState, fpr[9]) }, - { "f10", offsetof(CPUPPCState, fpr[10]) }, - { "f11", offsetof(CPUPPCState, fpr[11]) }, - { "f12", offsetof(CPUPPCState, fpr[12]) }, - { "f13", offsetof(CPUPPCState, fpr[13]) }, - { "f14", offsetof(CPUPPCState, fpr[14]) }, - { "f15", offsetof(CPUPPCState, fpr[15]) }, - { "f16", offsetof(CPUPPCState, fpr[16]) }, - { "f17", offsetof(CPUPPCState, fpr[17]) }, - { "f18", offsetof(CPUPPCState, fpr[18]) }, - { "f19", offsetof(CPUPPCState, fpr[19]) }, - { "f20", offsetof(CPUPPCState, fpr[20]) }, - { "f21", offsetof(CPUPPCState, fpr[21]) }, - { "f22", offsetof(CPUPPCState, fpr[22]) }, - { "f23", offsetof(CPUPPCState, fpr[23]) }, - { "f24", offsetof(CPUPPCState, fpr[24]) }, - { "f25", offsetof(CPUPPCState, fpr[25]) }, - { "f26", offsetof(CPUPPCState, fpr[26]) }, - { "f27", offsetof(CPUPPCState, fpr[27]) }, - { "f28", offsetof(CPUPPCState, fpr[28]) }, - { "f29", offsetof(CPUPPCState, fpr[29]) }, - { "f30", offsetof(CPUPPCState, fpr[30]) }, - { "f31", offsetof(CPUPPCState, fpr[31]) }, - { "fpscr", offsetof(CPUPPCState, fpscr) }, - /* Next instruction pointer */ - { "nip|pc", offsetof(CPUPPCState, nip) }, - { "lr", offsetof(CPUPPCState, lr) }, - { "ctr", offsetof(CPUPPCState, ctr) }, - { "decr", 0, &monitor_get_decr, }, - { "ccr", 0, &monitor_get_ccr, }, - /* Machine state register */ - { "msr", 0, &monitor_get_msr, }, - { "xer", 0, &monitor_get_xer, }, - { "tbu", 0, &monitor_get_tbu, }, - { "tbl", 0, &monitor_get_tbl, }, - /* Segment registers */ - { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) }, - { "sr0", offsetof(CPUPPCState, sr[0]) }, - { "sr1", offsetof(CPUPPCState, sr[1]) }, - { "sr2", offsetof(CPUPPCState, sr[2]) }, - { "sr3", offsetof(CPUPPCState, sr[3]) }, - { "sr4", offsetof(CPUPPCState, sr[4]) }, - { "sr5", offsetof(CPUPPCState, sr[5]) }, - { "sr6", offsetof(CPUPPCState, sr[6]) }, - { "sr7", offsetof(CPUPPCState, sr[7]) }, - { "sr8", offsetof(CPUPPCState, sr[8]) }, - { "sr9", offsetof(CPUPPCState, sr[9]) }, - { "sr10", offsetof(CPUPPCState, sr[10]) }, - { "sr11", offsetof(CPUPPCState, sr[11]) }, - { "sr12", offsetof(CPUPPCState, sr[12]) }, - { "sr13", offsetof(CPUPPCState, sr[13]) }, - { "sr14", offsetof(CPUPPCState, sr[14]) }, - { "sr15", offsetof(CPUPPCState, sr[15]) }, - /* Too lazy to put BATs... */ - { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) }, - - { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) }, - { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) }, - { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) }, - { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) }, - { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) }, - { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) }, - { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) }, - { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) }, - { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) }, - { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) }, - { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) }, - { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) }, - { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) }, - { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) }, - { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) }, - { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) }, - { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) }, - { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) }, - { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) }, - { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) }, - { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) }, - { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) }, - { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) }, - { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) }, - { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) }, - { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) }, - { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) }, - { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) }, - { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) }, - { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) }, - { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) }, - { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) }, - { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) }, - { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) }, - { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) }, - { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) }, - { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) }, - { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) }, - { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) }, - { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) }, - { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) }, - { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) }, - { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) }, - { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) }, - { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) }, - { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) }, - { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) }, - { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) }, - { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) }, - { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) }, - { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) }, - { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) }, - { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) }, - { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) }, - { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) }, - { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) }, - { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) }, - { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) }, - { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) }, - { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) }, - { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) }, - { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) }, - { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) }, - { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) }, - { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) }, - { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) }, - { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) }, - { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) }, - { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) }, - -#elif defined(TARGET_SPARC) - { "g0", offsetof(CPUSPARCState, gregs[0]) }, - { "g1", offsetof(CPUSPARCState, gregs[1]) }, - { "g2", offsetof(CPUSPARCState, gregs[2]) }, - { "g3", offsetof(CPUSPARCState, gregs[3]) }, - { "g4", offsetof(CPUSPARCState, gregs[4]) }, - { "g5", offsetof(CPUSPARCState, gregs[5]) }, - { "g6", offsetof(CPUSPARCState, gregs[6]) }, - { "g7", offsetof(CPUSPARCState, gregs[7]) }, - { "o0", 0, monitor_get_reg }, - { "o1", 1, monitor_get_reg }, - { "o2", 2, monitor_get_reg }, - { "o3", 3, monitor_get_reg }, - { "o4", 4, monitor_get_reg }, - { "o5", 5, monitor_get_reg }, - { "o6", 6, monitor_get_reg }, - { "o7", 7, monitor_get_reg }, - { "l0", 8, monitor_get_reg }, - { "l1", 9, monitor_get_reg }, - { "l2", 10, monitor_get_reg }, - { "l3", 11, monitor_get_reg }, - { "l4", 12, monitor_get_reg }, - { "l5", 13, monitor_get_reg }, - { "l6", 14, monitor_get_reg }, - { "l7", 15, monitor_get_reg }, - { "i0", 16, monitor_get_reg }, - { "i1", 17, monitor_get_reg }, - { "i2", 18, monitor_get_reg }, - { "i3", 19, monitor_get_reg }, - { "i4", 20, monitor_get_reg }, - { "i5", 21, monitor_get_reg }, - { "i6", 22, monitor_get_reg }, - { "i7", 23, monitor_get_reg }, - { "pc", offsetof(CPUSPARCState, pc) }, - { "npc", offsetof(CPUSPARCState, npc) }, - { "y", offsetof(CPUSPARCState, y) }, -#ifndef TARGET_SPARC64 - { "psr", 0, &monitor_get_psr, }, - { "wim", offsetof(CPUSPARCState, wim) }, -#endif - { "tbr", offsetof(CPUSPARCState, tbr) }, - { "fsr", offsetof(CPUSPARCState, fsr) }, - { "f0", offsetof(CPUSPARCState, fpr[0].l.upper) }, - { "f1", offsetof(CPUSPARCState, fpr[0].l.lower) }, - { "f2", offsetof(CPUSPARCState, fpr[1].l.upper) }, - { "f3", offsetof(CPUSPARCState, fpr[1].l.lower) }, - { "f4", offsetof(CPUSPARCState, fpr[2].l.upper) }, - { "f5", offsetof(CPUSPARCState, fpr[2].l.lower) }, - { "f6", offsetof(CPUSPARCState, fpr[3].l.upper) }, - { "f7", offsetof(CPUSPARCState, fpr[3].l.lower) }, - { "f8", offsetof(CPUSPARCState, fpr[4].l.upper) }, - { "f9", offsetof(CPUSPARCState, fpr[4].l.lower) }, - { "f10", offsetof(CPUSPARCState, fpr[5].l.upper) }, - { "f11", offsetof(CPUSPARCState, fpr[5].l.lower) }, - { "f12", offsetof(CPUSPARCState, fpr[6].l.upper) }, - { "f13", offsetof(CPUSPARCState, fpr[6].l.lower) }, - { "f14", offsetof(CPUSPARCState, fpr[7].l.upper) }, - { "f15", offsetof(CPUSPARCState, fpr[7].l.lower) }, - { "f16", offsetof(CPUSPARCState, fpr[8].l.upper) }, - { "f17", offsetof(CPUSPARCState, fpr[8].l.lower) }, - { "f18", offsetof(CPUSPARCState, fpr[9].l.upper) }, - { "f19", offsetof(CPUSPARCState, fpr[9].l.lower) }, - { "f20", offsetof(CPUSPARCState, fpr[10].l.upper) }, - { "f21", offsetof(CPUSPARCState, fpr[10].l.lower) }, - { "f22", offsetof(CPUSPARCState, fpr[11].l.upper) }, - { "f23", offsetof(CPUSPARCState, fpr[11].l.lower) }, - { "f24", offsetof(CPUSPARCState, fpr[12].l.upper) }, - { "f25", offsetof(CPUSPARCState, fpr[12].l.lower) }, - { "f26", offsetof(CPUSPARCState, fpr[13].l.upper) }, - { "f27", offsetof(CPUSPARCState, fpr[13].l.lower) }, - { "f28", offsetof(CPUSPARCState, fpr[14].l.upper) }, - { "f29", offsetof(CPUSPARCState, fpr[14].l.lower) }, - { "f30", offsetof(CPUSPARCState, fpr[15].l.upper) }, - { "f31", offsetof(CPUSPARCState, fpr[15].l.lower) }, -#ifdef TARGET_SPARC64 - { "f32", offsetof(CPUSPARCState, fpr[16]) }, - { "f34", offsetof(CPUSPARCState, fpr[17]) }, - { "f36", offsetof(CPUSPARCState, fpr[18]) }, - { "f38", offsetof(CPUSPARCState, fpr[19]) }, - { "f40", offsetof(CPUSPARCState, fpr[20]) }, - { "f42", offsetof(CPUSPARCState, fpr[21]) }, - { "f44", offsetof(CPUSPARCState, fpr[22]) }, - { "f46", offsetof(CPUSPARCState, fpr[23]) }, - { "f48", offsetof(CPUSPARCState, fpr[24]) }, - { "f50", offsetof(CPUSPARCState, fpr[25]) }, - { "f52", offsetof(CPUSPARCState, fpr[26]) }, - { "f54", offsetof(CPUSPARCState, fpr[27]) }, - { "f56", offsetof(CPUSPARCState, fpr[28]) }, - { "f58", offsetof(CPUSPARCState, fpr[29]) }, - { "f60", offsetof(CPUSPARCState, fpr[30]) }, - { "f62", offsetof(CPUSPARCState, fpr[31]) }, - { "asi", offsetof(CPUSPARCState, asi) }, - { "pstate", offsetof(CPUSPARCState, pstate) }, - { "cansave", offsetof(CPUSPARCState, cansave) }, - { "canrestore", offsetof(CPUSPARCState, canrestore) }, - { "otherwin", offsetof(CPUSPARCState, otherwin) }, - { "wstate", offsetof(CPUSPARCState, wstate) }, - { "cleanwin", offsetof(CPUSPARCState, cleanwin) }, - { "fprs", offsetof(CPUSPARCState, fprs) }, -#endif -#endif - { NULL }, -}; static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN expr_error(Monitor *mon, const char *fmt, ...) @@ -2936,10 +2088,14 @@ expr_error(Monitor *mon, const char *fmt, ...) /* return 0 if OK, -1 if not found */ static int get_monitor_def(target_long *pval, const char *name) { - const MonitorDef *md; + const MonitorDef *md = target_monitor_defs(); void *ptr; - for(md = monitor_defs; md->name != NULL; md++) { + if (md == NULL) { + return -1; + } + + for(; md->name != NULL; md++) { if (compare_cmd(name, md->name)) { if (md->get_value) { *pval = md->get_value(md, md->offset); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 9937a1295e..85e4e81017 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -38,3 +38,4 @@ stub-obj-$(CONFIG_WIN32) += fd-register.o stub-obj-y += cpus.o stub-obj-y += kvm.o stub-obj-y += qmp_pc_dimm_device_list.o +stub-obj-y += target-monitor-defs.o diff --git a/stubs/target-monitor-defs.c b/stubs/target-monitor-defs.c new file mode 100644 index 0000000000..7d8d182b23 --- /dev/null +++ b/stubs/target-monitor-defs.c @@ -0,0 +1,9 @@ +#include "stddef.h" +#include "qemu/typedefs.h" + +const MonitorDef *target_monitor_defs(void); + +const MonitorDef *target_monitor_defs(void) +{ + return NULL; +} diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 7a1df2c983..3da413e8bd 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -2,6 +2,6 @@ obj-y += translate.o helper.o cpu.o obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o obj-y += gdbstub.o -obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o +obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o obj-$(CONFIG_KVM) += kvm.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o diff --git a/target-i386/monitor.c b/target-i386/monitor.c new file mode 100644 index 0000000000..6ac86360e9 --- /dev/null +++ b/target-i386/monitor.c @@ -0,0 +1,494 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "cpu.h" +#include "monitor/monitor.h" +#include "monitor/hmp-target.h" +#include "hmp.h" + + +static void print_pte(Monitor *mon, hwaddr addr, + hwaddr pte, + hwaddr mask) +{ +#ifdef TARGET_X86_64 + if (addr & (1ULL << 47)) { + addr |= -1LL << 48; + } +#endif + monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx + " %c%c%c%c%c%c%c%c%c\n", + addr, + pte & mask, + pte & PG_NX_MASK ? 'X' : '-', + pte & PG_GLOBAL_MASK ? 'G' : '-', + pte & PG_PSE_MASK ? 'P' : '-', + pte & PG_DIRTY_MASK ? 'D' : '-', + pte & PG_ACCESSED_MASK ? 'A' : '-', + pte & PG_PCD_MASK ? 'C' : '-', + pte & PG_PWT_MASK ? 'T' : '-', + pte & PG_USER_MASK ? 'U' : '-', + pte & PG_RW_MASK ? 'W' : '-'); +} + +static void tlb_info_32(Monitor *mon, CPUArchState *env) +{ + unsigned int l1, l2; + uint32_t pgd, pde, pte; + + pgd = env->cr[3] & ~0xfff; + for(l1 = 0; l1 < 1024; l1++) { + cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); + pde = le32_to_cpu(pde); + if (pde & PG_PRESENT_MASK) { + if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { + /* 4M pages */ + print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1)); + } else { + for(l2 = 0; l2 < 1024; l2++) { + cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); + pte = le32_to_cpu(pte); + if (pte & PG_PRESENT_MASK) { + print_pte(mon, (l1 << 22) + (l2 << 12), + pte & ~PG_PSE_MASK, + ~0xfff); + } + } + } + } + } +} + +static void tlb_info_pae32(Monitor *mon, CPUArchState *env) +{ + unsigned int l1, l2, l3; + uint64_t pdpe, pde, pte; + uint64_t pdp_addr, pd_addr, pt_addr; + + pdp_addr = env->cr[3] & ~0x1f; + for (l1 = 0; l1 < 4; l1++) { + cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + if (pdpe & PG_PRESENT_MASK) { + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); + pde = le64_to_cpu(pde); + if (pde & PG_PRESENT_MASK) { + if (pde & PG_PSE_MASK) { + /* 2M pages with PAE, CR4.PSE is ignored */ + print_pte(mon, (l1 << 30 ) + (l2 << 21), pde, + ~((hwaddr)(1 << 20) - 1)); + } else { + pt_addr = pde & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); + pte = le64_to_cpu(pte); + if (pte & PG_PRESENT_MASK) { + print_pte(mon, (l1 << 30 ) + (l2 << 21) + + (l3 << 12), + pte & ~PG_PSE_MASK, + ~(hwaddr)0xfff); + } + } + } + } + } + } + } +} + +#ifdef TARGET_X86_64 +static void tlb_info_64(Monitor *mon, CPUArchState *env) +{ + uint64_t l1, l2, l3, l4; + uint64_t pml4e, pdpe, pde, pte; + uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr; + + pml4_addr = env->cr[3] & 0x3fffffffff000ULL; + for (l1 = 0; l1 < 512; l1++) { + cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); + pml4e = le64_to_cpu(pml4e); + if (pml4e & PG_PRESENT_MASK) { + pdp_addr = pml4e & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + if (pdpe & PG_PRESENT_MASK) { + if (pdpe & PG_PSE_MASK) { + /* 1G pages, CR4.PSE is ignored */ + print_pte(mon, (l1 << 39) + (l2 << 30), pdpe, + 0x3ffffc0000000ULL); + } else { + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); + pde = le64_to_cpu(pde); + if (pde & PG_PRESENT_MASK) { + if (pde & PG_PSE_MASK) { + /* 2M pages, CR4.PSE is ignored */ + print_pte(mon, (l1 << 39) + (l2 << 30) + + (l3 << 21), pde, + 0x3ffffffe00000ULL); + } else { + pt_addr = pde & 0x3fffffffff000ULL; + for (l4 = 0; l4 < 512; l4++) { + cpu_physical_memory_read(pt_addr + + l4 * 8, + &pte, 8); + pte = le64_to_cpu(pte); + if (pte & PG_PRESENT_MASK) { + print_pte(mon, (l1 << 39) + + (l2 << 30) + + (l3 << 21) + (l4 << 12), + pte & ~PG_PSE_MASK, + 0x3fffffffff000ULL); + } + } + } + } + } + } + } + } + } + } +} +#endif /* TARGET_X86_64 */ + +void hmp_info_tlb(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env; + + env = mon_get_cpu_env(); + + if (!(env->cr[0] & CR0_PG_MASK)) { + monitor_printf(mon, "PG disabled\n"); + return; + } + if (env->cr[4] & CR4_PAE_MASK) { +#ifdef TARGET_X86_64 + if (env->hflags & HF_LMA_MASK) { + tlb_info_64(mon, env); + } else +#endif + { + tlb_info_pae32(mon, env); + } + } else { + tlb_info_32(mon, env); + } +} + +static void mem_print(Monitor *mon, hwaddr *pstart, + int *plast_prot, + hwaddr end, int prot) +{ + int prot1; + prot1 = *plast_prot; + if (prot != prot1) { + if (*pstart != -1) { + monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " " + TARGET_FMT_plx " %c%c%c\n", + *pstart, end, end - *pstart, + prot1 & PG_USER_MASK ? 'u' : '-', + 'r', + prot1 & PG_RW_MASK ? 'w' : '-'); + } + if (prot != 0) + *pstart = end; + else + *pstart = -1; + *plast_prot = prot; + } +} + +static void mem_info_32(Monitor *mon, CPUArchState *env) +{ + unsigned int l1, l2; + int prot, last_prot; + uint32_t pgd, pde, pte; + hwaddr start, end; + + pgd = env->cr[3] & ~0xfff; + last_prot = 0; + start = -1; + for(l1 = 0; l1 < 1024; l1++) { + cpu_physical_memory_read(pgd + l1 * 4, &pde, 4); + pde = le32_to_cpu(pde); + end = l1 << 22; + if (pde & PG_PRESENT_MASK) { + if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { + prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + mem_print(mon, &start, &last_prot, end, prot); + } else { + for(l2 = 0; l2 < 1024; l2++) { + cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); + pte = le32_to_cpu(pte); + end = (l1 << 22) + (l2 << 12); + if (pte & PG_PRESENT_MASK) { + prot = pte & pde & + (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + } else { + prot = 0; + } + mem_print(mon, &start, &last_prot, end, prot); + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0); +} + +static void mem_info_pae32(Monitor *mon, CPUArchState *env) +{ + unsigned int l1, l2, l3; + int prot, last_prot; + uint64_t pdpe, pde, pte; + uint64_t pdp_addr, pd_addr, pt_addr; + hwaddr start, end; + + pdp_addr = env->cr[3] & ~0x1f; + last_prot = 0; + start = -1; + for (l1 = 0; l1 < 4; l1++) { + cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + end = l1 << 30; + if (pdpe & PG_PRESENT_MASK) { + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8); + pde = le64_to_cpu(pde); + end = (l1 << 30) + (l2 << 21); + if (pde & PG_PRESENT_MASK) { + if (pde & PG_PSE_MASK) { + prot = pde & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + mem_print(mon, &start, &last_prot, end, prot); + } else { + pt_addr = pde & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); + pte = le64_to_cpu(pte); + end = (l1 << 30) + (l2 << 21) + (l3 << 12); + if (pte & PG_PRESENT_MASK) { + prot = pte & pde & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + } else { + prot = 0; + } + mem_print(mon, &start, &last_prot, end, prot); + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0); +} + + +#ifdef TARGET_X86_64 +static void mem_info_64(Monitor *mon, CPUArchState *env) +{ + int prot, last_prot; + uint64_t l1, l2, l3, l4; + uint64_t pml4e, pdpe, pde, pte; + uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end; + + pml4_addr = env->cr[3] & 0x3fffffffff000ULL; + last_prot = 0; + start = -1; + for (l1 = 0; l1 < 512; l1++) { + cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); + pml4e = le64_to_cpu(pml4e); + end = l1 << 39; + if (pml4e & PG_PRESENT_MASK) { + pdp_addr = pml4e & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + end = (l1 << 39) + (l2 << 30); + if (pdpe & PG_PRESENT_MASK) { + if (pdpe & PG_PSE_MASK) { + prot = pdpe & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e; + mem_print(mon, &start, &last_prot, end, prot); + } else { + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); + pde = le64_to_cpu(pde); + end = (l1 << 39) + (l2 << 30) + (l3 << 21); + if (pde & PG_PRESENT_MASK) { + if (pde & PG_PSE_MASK) { + prot = pde & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e & pdpe; + mem_print(mon, &start, &last_prot, end, prot); + } else { + pt_addr = pde & 0x3fffffffff000ULL; + for (l4 = 0; l4 < 512; l4++) { + cpu_physical_memory_read(pt_addr + + l4 * 8, + &pte, 8); + pte = le64_to_cpu(pte); + end = (l1 << 39) + (l2 << 30) + + (l3 << 21) + (l4 << 12); + if (pte & PG_PRESENT_MASK) { + prot = pte & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e & pdpe & pde; + } else { + prot = 0; + } + mem_print(mon, &start, &last_prot, end, prot); + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + } else { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + } + } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0); +} +#endif /* TARGET_X86_64 */ + +void hmp_info_mem(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env; + + env = mon_get_cpu_env(); + + if (!(env->cr[0] & CR0_PG_MASK)) { + monitor_printf(mon, "PG disabled\n"); + return; + } + if (env->cr[4] & CR4_PAE_MASK) { +#ifdef TARGET_X86_64 + if (env->hflags & HF_LMA_MASK) { + mem_info_64(mon, env); + } else +#endif + { + mem_info_pae32(mon, env); + } + } else { + mem_info_32(mon, env); + } +} + +void hmp_mce(Monitor *mon, const QDict *qdict) +{ + X86CPU *cpu; + CPUState *cs; + int cpu_index = qdict_get_int(qdict, "cpu_index"); + int bank = qdict_get_int(qdict, "bank"); + uint64_t status = qdict_get_int(qdict, "status"); + uint64_t mcg_status = qdict_get_int(qdict, "mcg_status"); + uint64_t addr = qdict_get_int(qdict, "addr"); + uint64_t misc = qdict_get_int(qdict, "misc"); + int flags = MCE_INJECT_UNCOND_AO; + + if (qdict_get_try_bool(qdict, "broadcast", false)) { + flags |= MCE_INJECT_BROADCAST; + } + cs = qemu_get_cpu(cpu_index); + if (cs != NULL) { + cpu = X86_CPU(cs); + cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc, + flags); + } +} + +static target_long monitor_get_pc(const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return env->eip + env->segs[R_CS].base; +} + +const MonitorDef monitor_defs[] = { +#define SEG(name, seg) \ + { name, offsetof(CPUX86State, segs[seg].selector), NULL, MD_I32 },\ + { name ".base", offsetof(CPUX86State, segs[seg].base) },\ + { name ".limit", offsetof(CPUX86State, segs[seg].limit), NULL, MD_I32 }, + + { "eax", offsetof(CPUX86State, regs[0]) }, + { "ecx", offsetof(CPUX86State, regs[1]) }, + { "edx", offsetof(CPUX86State, regs[2]) }, + { "ebx", offsetof(CPUX86State, regs[3]) }, + { "esp|sp", offsetof(CPUX86State, regs[4]) }, + { "ebp|fp", offsetof(CPUX86State, regs[5]) }, + { "esi", offsetof(CPUX86State, regs[6]) }, + { "edi", offsetof(CPUX86State, regs[7]) }, +#ifdef TARGET_X86_64 + { "r8", offsetof(CPUX86State, regs[8]) }, + { "r9", offsetof(CPUX86State, regs[9]) }, + { "r10", offsetof(CPUX86State, regs[10]) }, + { "r11", offsetof(CPUX86State, regs[11]) }, + { "r12", offsetof(CPUX86State, regs[12]) }, + { "r13", offsetof(CPUX86State, regs[13]) }, + { "r14", offsetof(CPUX86State, regs[14]) }, + { "r15", offsetof(CPUX86State, regs[15]) }, +#endif + { "eflags", offsetof(CPUX86State, eflags) }, + { "eip", offsetof(CPUX86State, eip) }, + SEG("cs", R_CS) + SEG("ds", R_DS) + SEG("es", R_ES) + SEG("ss", R_SS) + SEG("fs", R_FS) + SEG("gs", R_GS) + { "pc", 0, monitor_get_pc, }, + { NULL }, +}; + +const MonitorDef *target_monitor_defs(void) +{ + return monitor_defs; +} diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs index a7ae392cc0..47a3e983ec 100644 --- a/target-ppc/Makefile.objs +++ b/target-ppc/Makefile.objs @@ -1,7 +1,7 @@ obj-y += cpu-models.o obj-y += translate.o ifeq ($(CONFIG_SOFTMMU),y) -obj-y += machine.o mmu_helper.o mmu-hash32.o +obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o endif obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o diff --git a/target-ppc/monitor.c b/target-ppc/monitor.c new file mode 100644 index 0000000000..9cb1fe97c9 --- /dev/null +++ b/target-ppc/monitor.c @@ -0,0 +1,255 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "cpu.h" +#include "monitor/monitor.h" +#include "monitor/hmp-target.h" +#include "hmp.h" + +static target_long monitor_get_ccr (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + unsigned int u; + int i; + + u = 0; + for (i = 0; i < 8; i++) + u |= env->crf[i] << (32 - (4 * (i + 1))); + + return u; +} + +static target_long monitor_get_msr (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return env->msr; +} + +static target_long monitor_get_xer (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return env->xer; +} + +static target_long monitor_get_decr (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return cpu_ppc_load_decr(env); +} + +static target_long monitor_get_tbu (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return cpu_ppc_load_tbu(env); +} + +static target_long monitor_get_tbl (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return cpu_ppc_load_tbl(env); +} + +void hmp_info_tlb(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env1 = mon_get_cpu_env(); + + dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1); +} + + +const MonitorDef monitor_defs[] = { + /* General purpose registers */ + { "r0", offsetof(CPUPPCState, gpr[0]) }, + { "r1", offsetof(CPUPPCState, gpr[1]) }, + { "r2", offsetof(CPUPPCState, gpr[2]) }, + { "r3", offsetof(CPUPPCState, gpr[3]) }, + { "r4", offsetof(CPUPPCState, gpr[4]) }, + { "r5", offsetof(CPUPPCState, gpr[5]) }, + { "r6", offsetof(CPUPPCState, gpr[6]) }, + { "r7", offsetof(CPUPPCState, gpr[7]) }, + { "r8", offsetof(CPUPPCState, gpr[8]) }, + { "r9", offsetof(CPUPPCState, gpr[9]) }, + { "r10", offsetof(CPUPPCState, gpr[10]) }, + { "r11", offsetof(CPUPPCState, gpr[11]) }, + { "r12", offsetof(CPUPPCState, gpr[12]) }, + { "r13", offsetof(CPUPPCState, gpr[13]) }, + { "r14", offsetof(CPUPPCState, gpr[14]) }, + { "r15", offsetof(CPUPPCState, gpr[15]) }, + { "r16", offsetof(CPUPPCState, gpr[16]) }, + { "r17", offsetof(CPUPPCState, gpr[17]) }, + { "r18", offsetof(CPUPPCState, gpr[18]) }, + { "r19", offsetof(CPUPPCState, gpr[19]) }, + { "r20", offsetof(CPUPPCState, gpr[20]) }, + { "r21", offsetof(CPUPPCState, gpr[21]) }, + { "r22", offsetof(CPUPPCState, gpr[22]) }, + { "r23", offsetof(CPUPPCState, gpr[23]) }, + { "r24", offsetof(CPUPPCState, gpr[24]) }, + { "r25", offsetof(CPUPPCState, gpr[25]) }, + { "r26", offsetof(CPUPPCState, gpr[26]) }, + { "r27", offsetof(CPUPPCState, gpr[27]) }, + { "r28", offsetof(CPUPPCState, gpr[28]) }, + { "r29", offsetof(CPUPPCState, gpr[29]) }, + { "r30", offsetof(CPUPPCState, gpr[30]) }, + { "r31", offsetof(CPUPPCState, gpr[31]) }, + /* Floating point registers */ + { "f0", offsetof(CPUPPCState, fpr[0]) }, + { "f1", offsetof(CPUPPCState, fpr[1]) }, + { "f2", offsetof(CPUPPCState, fpr[2]) }, + { "f3", offsetof(CPUPPCState, fpr[3]) }, + { "f4", offsetof(CPUPPCState, fpr[4]) }, + { "f5", offsetof(CPUPPCState, fpr[5]) }, + { "f6", offsetof(CPUPPCState, fpr[6]) }, + { "f7", offsetof(CPUPPCState, fpr[7]) }, + { "f8", offsetof(CPUPPCState, fpr[8]) }, + { "f9", offsetof(CPUPPCState, fpr[9]) }, + { "f10", offsetof(CPUPPCState, fpr[10]) }, + { "f11", offsetof(CPUPPCState, fpr[11]) }, + { "f12", offsetof(CPUPPCState, fpr[12]) }, + { "f13", offsetof(CPUPPCState, fpr[13]) }, + { "f14", offsetof(CPUPPCState, fpr[14]) }, + { "f15", offsetof(CPUPPCState, fpr[15]) }, + { "f16", offsetof(CPUPPCState, fpr[16]) }, + { "f17", offsetof(CPUPPCState, fpr[17]) }, + { "f18", offsetof(CPUPPCState, fpr[18]) }, + { "f19", offsetof(CPUPPCState, fpr[19]) }, + { "f20", offsetof(CPUPPCState, fpr[20]) }, + { "f21", offsetof(CPUPPCState, fpr[21]) }, + { "f22", offsetof(CPUPPCState, fpr[22]) }, + { "f23", offsetof(CPUPPCState, fpr[23]) }, + { "f24", offsetof(CPUPPCState, fpr[24]) }, + { "f25", offsetof(CPUPPCState, fpr[25]) }, + { "f26", offsetof(CPUPPCState, fpr[26]) }, + { "f27", offsetof(CPUPPCState, fpr[27]) }, + { "f28", offsetof(CPUPPCState, fpr[28]) }, + { "f29", offsetof(CPUPPCState, fpr[29]) }, + { "f30", offsetof(CPUPPCState, fpr[30]) }, + { "f31", offsetof(CPUPPCState, fpr[31]) }, + { "fpscr", offsetof(CPUPPCState, fpscr) }, + /* Next instruction pointer */ + { "nip|pc", offsetof(CPUPPCState, nip) }, + { "lr", offsetof(CPUPPCState, lr) }, + { "ctr", offsetof(CPUPPCState, ctr) }, + { "decr", 0, &monitor_get_decr, }, + { "ccr", 0, &monitor_get_ccr, }, + /* Machine state register */ + { "msr", 0, &monitor_get_msr, }, + { "xer", 0, &monitor_get_xer, }, + { "tbu", 0, &monitor_get_tbu, }, + { "tbl", 0, &monitor_get_tbl, }, + /* Segment registers */ + { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) }, + { "sr0", offsetof(CPUPPCState, sr[0]) }, + { "sr1", offsetof(CPUPPCState, sr[1]) }, + { "sr2", offsetof(CPUPPCState, sr[2]) }, + { "sr3", offsetof(CPUPPCState, sr[3]) }, + { "sr4", offsetof(CPUPPCState, sr[4]) }, + { "sr5", offsetof(CPUPPCState, sr[5]) }, + { "sr6", offsetof(CPUPPCState, sr[6]) }, + { "sr7", offsetof(CPUPPCState, sr[7]) }, + { "sr8", offsetof(CPUPPCState, sr[8]) }, + { "sr9", offsetof(CPUPPCState, sr[9]) }, + { "sr10", offsetof(CPUPPCState, sr[10]) }, + { "sr11", offsetof(CPUPPCState, sr[11]) }, + { "sr12", offsetof(CPUPPCState, sr[12]) }, + { "sr13", offsetof(CPUPPCState, sr[13]) }, + { "sr14", offsetof(CPUPPCState, sr[14]) }, + { "sr15", offsetof(CPUPPCState, sr[15]) }, + /* Too lazy to put BATs... */ + { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) }, + + { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) }, + { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) }, + { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) }, + { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) }, + { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) }, + { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) }, + { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) }, + { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) }, + { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) }, + { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) }, + { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) }, + { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) }, + { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) }, + { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) }, + { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) }, + { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) }, + { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) }, + { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) }, + { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) }, + { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) }, + { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) }, + { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) }, + { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) }, + { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) }, + { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) }, + { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) }, + { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) }, + { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) }, + { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) }, + { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) }, + { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) }, + { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) }, + { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) }, + { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) }, + { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) }, + { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) }, + { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) }, + { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) }, + { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) }, + { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) }, + { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) }, + { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) }, + { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) }, + { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) }, + { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) }, + { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) }, + { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) }, + { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) }, + { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) }, + { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) }, + { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) }, + { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) }, + { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) }, + { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) }, + { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) }, + { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) }, + { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) }, + { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) }, + { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) }, + { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) }, + { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) }, + { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) }, + { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) }, + { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) }, + { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) }, + { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) }, + { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) }, + { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) }, + { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) }, + { NULL }, +}; + +const MonitorDef *target_monitor_defs(void) +{ + return monitor_defs; +} diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs index a285358adf..2c25d96e65 100644 --- a/target-sh4/Makefile.objs +++ b/target-sh4/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o +obj-$(CONFIG_SOFTMMU) += monitor.o obj-y += gdbstub.o diff --git a/target-sh4/monitor.c b/target-sh4/monitor.c new file mode 100644 index 0000000000..a06f0d46d8 --- /dev/null +++ b/target-sh4/monitor.c @@ -0,0 +1,52 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "cpu.h" +#include "monitor/monitor.h" +#include "monitor/hmp-target.h" +#include "hmp.h" + +static void print_tlb(Monitor *mon, int idx, tlb_t *tlb) +{ + monitor_printf(mon, " tlb%i:\t" + "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t" + "v=%hhu shared=%hhu cached=%hhu prot=%hhu " + "dirty=%hhu writethrough=%hhu\n", + idx, + tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size, + tlb->v, tlb->sh, tlb->c, tlb->pr, + tlb->d, tlb->wt); +} + +void hmp_info_tlb(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env = mon_get_cpu_env(); + int i; + + monitor_printf (mon, "ITLB:\n"); + for (i = 0 ; i < ITLB_SIZE ; i++) + print_tlb (mon, i, &env->itlb[i]); + monitor_printf (mon, "UTLB:\n"); + for (i = 0 ; i < UTLB_SIZE ; i++) + print_tlb (mon, i, &env->utlb[i]); +} diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs index 1cd81cccc3..ec905698c5 100644 --- a/target-sparc/Makefile.objs +++ b/target-sparc/Makefile.objs @@ -1,4 +1,4 @@ -obj-$(CONFIG_SOFTMMU) += machine.o +obj-$(CONFIG_SOFTMMU) += machine.o monitor.o obj-y += translate.o helper.o cpu.o obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o obj-$(TARGET_SPARC) += int32_helper.o diff --git a/target-sparc/monitor.c b/target-sparc/monitor.c new file mode 100644 index 0000000000..ca54d72d99 --- /dev/null +++ b/target-sparc/monitor.c @@ -0,0 +1,158 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "cpu.h" +#include "monitor/monitor.h" +#include "monitor/hmp-target.h" +#include "hmp.h" + + +void hmp_info_tlb(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env1 = mon_get_cpu_env(); + + dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1); +} + +#ifndef TARGET_SPARC64 +static target_long monitor_get_psr (const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + + return cpu_get_psr(env); +} +#endif + +static target_long monitor_get_reg(const struct MonitorDef *md, int val) +{ + CPUArchState *env = mon_get_cpu_env(); + return env->regwptr[val]; +} + +const MonitorDef monitor_defs[] = { + { "g0", offsetof(CPUSPARCState, gregs[0]) }, + { "g1", offsetof(CPUSPARCState, gregs[1]) }, + { "g2", offsetof(CPUSPARCState, gregs[2]) }, + { "g3", offsetof(CPUSPARCState, gregs[3]) }, + { "g4", offsetof(CPUSPARCState, gregs[4]) }, + { "g5", offsetof(CPUSPARCState, gregs[5]) }, + { "g6", offsetof(CPUSPARCState, gregs[6]) }, + { "g7", offsetof(CPUSPARCState, gregs[7]) }, + { "o0", 0, monitor_get_reg }, + { "o1", 1, monitor_get_reg }, + { "o2", 2, monitor_get_reg }, + { "o3", 3, monitor_get_reg }, + { "o4", 4, monitor_get_reg }, + { "o5", 5, monitor_get_reg }, + { "o6", 6, monitor_get_reg }, + { "o7", 7, monitor_get_reg }, + { "l0", 8, monitor_get_reg }, + { "l1", 9, monitor_get_reg }, + { "l2", 10, monitor_get_reg }, + { "l3", 11, monitor_get_reg }, + { "l4", 12, monitor_get_reg }, + { "l5", 13, monitor_get_reg }, + { "l6", 14, monitor_get_reg }, + { "l7", 15, monitor_get_reg }, + { "i0", 16, monitor_get_reg }, + { "i1", 17, monitor_get_reg }, + { "i2", 18, monitor_get_reg }, + { "i3", 19, monitor_get_reg }, + { "i4", 20, monitor_get_reg }, + { "i5", 21, monitor_get_reg }, + { "i6", 22, monitor_get_reg }, + { "i7", 23, monitor_get_reg }, + { "pc", offsetof(CPUSPARCState, pc) }, + { "npc", offsetof(CPUSPARCState, npc) }, + { "y", offsetof(CPUSPARCState, y) }, +#ifndef TARGET_SPARC64 + { "psr", 0, &monitor_get_psr, }, + { "wim", offsetof(CPUSPARCState, wim) }, +#endif + { "tbr", offsetof(CPUSPARCState, tbr) }, + { "fsr", offsetof(CPUSPARCState, fsr) }, + { "f0", offsetof(CPUSPARCState, fpr[0].l.upper) }, + { "f1", offsetof(CPUSPARCState, fpr[0].l.lower) }, + { "f2", offsetof(CPUSPARCState, fpr[1].l.upper) }, + { "f3", offsetof(CPUSPARCState, fpr[1].l.lower) }, + { "f4", offsetof(CPUSPARCState, fpr[2].l.upper) }, + { "f5", offsetof(CPUSPARCState, fpr[2].l.lower) }, + { "f6", offsetof(CPUSPARCState, fpr[3].l.upper) }, + { "f7", offsetof(CPUSPARCState, fpr[3].l.lower) }, + { "f8", offsetof(CPUSPARCState, fpr[4].l.upper) }, + { "f9", offsetof(CPUSPARCState, fpr[4].l.lower) }, + { "f10", offsetof(CPUSPARCState, fpr[5].l.upper) }, + { "f11", offsetof(CPUSPARCState, fpr[5].l.lower) }, + { "f12", offsetof(CPUSPARCState, fpr[6].l.upper) }, + { "f13", offsetof(CPUSPARCState, fpr[6].l.lower) }, + { "f14", offsetof(CPUSPARCState, fpr[7].l.upper) }, + { "f15", offsetof(CPUSPARCState, fpr[7].l.lower) }, + { "f16", offsetof(CPUSPARCState, fpr[8].l.upper) }, + { "f17", offsetof(CPUSPARCState, fpr[8].l.lower) }, + { "f18", offsetof(CPUSPARCState, fpr[9].l.upper) }, + { "f19", offsetof(CPUSPARCState, fpr[9].l.lower) }, + { "f20", offsetof(CPUSPARCState, fpr[10].l.upper) }, + { "f21", offsetof(CPUSPARCState, fpr[10].l.lower) }, + { "f22", offsetof(CPUSPARCState, fpr[11].l.upper) }, + { "f23", offsetof(CPUSPARCState, fpr[11].l.lower) }, + { "f24", offsetof(CPUSPARCState, fpr[12].l.upper) }, + { "f25", offsetof(CPUSPARCState, fpr[12].l.lower) }, + { "f26", offsetof(CPUSPARCState, fpr[13].l.upper) }, + { "f27", offsetof(CPUSPARCState, fpr[13].l.lower) }, + { "f28", offsetof(CPUSPARCState, fpr[14].l.upper) }, + { "f29", offsetof(CPUSPARCState, fpr[14].l.lower) }, + { "f30", offsetof(CPUSPARCState, fpr[15].l.upper) }, + { "f31", offsetof(CPUSPARCState, fpr[15].l.lower) }, +#ifdef TARGET_SPARC64 + { "f32", offsetof(CPUSPARCState, fpr[16]) }, + { "f34", offsetof(CPUSPARCState, fpr[17]) }, + { "f36", offsetof(CPUSPARCState, fpr[18]) }, + { "f38", offsetof(CPUSPARCState, fpr[19]) }, + { "f40", offsetof(CPUSPARCState, fpr[20]) }, + { "f42", offsetof(CPUSPARCState, fpr[21]) }, + { "f44", offsetof(CPUSPARCState, fpr[22]) }, + { "f46", offsetof(CPUSPARCState, fpr[23]) }, + { "f48", offsetof(CPUSPARCState, fpr[24]) }, + { "f50", offsetof(CPUSPARCState, fpr[25]) }, + { "f52", offsetof(CPUSPARCState, fpr[26]) }, + { "f54", offsetof(CPUSPARCState, fpr[27]) }, + { "f56", offsetof(CPUSPARCState, fpr[28]) }, + { "f58", offsetof(CPUSPARCState, fpr[29]) }, + { "f60", offsetof(CPUSPARCState, fpr[30]) }, + { "f62", offsetof(CPUSPARCState, fpr[31]) }, + { "asi", offsetof(CPUSPARCState, asi) }, + { "pstate", offsetof(CPUSPARCState, pstate) }, + { "cansave", offsetof(CPUSPARCState, cansave) }, + { "canrestore", offsetof(CPUSPARCState, canrestore) }, + { "otherwin", offsetof(CPUSPARCState, otherwin) }, + { "wstate", offsetof(CPUSPARCState, wstate) }, + { "cleanwin", offsetof(CPUSPARCState, cleanwin) }, + { "fprs", offsetof(CPUSPARCState, fprs) }, +#endif + { NULL }, +}; + +const MonitorDef *target_monitor_defs(void) +{ + return monitor_defs; +} diff --git a/target-xtensa/Makefile.objs b/target-xtensa/Makefile.objs index 5c150a870f..481de91973 100644 --- a/target-xtensa/Makefile.objs +++ b/target-xtensa/Makefile.objs @@ -2,5 +2,6 @@ obj-y += xtensa-semi.o obj-y += core-dc232b.o obj-y += core-dc233c.o obj-y += core-fsf.o +obj-$(CONFIG_SOFTMMU) += monitor.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += gdbstub.o diff --git a/target-xtensa/monitor.c b/target-xtensa/monitor.c new file mode 100644 index 0000000000..554b2123d2 --- /dev/null +++ b/target-xtensa/monitor.c @@ -0,0 +1,34 @@ +/* + * QEMU monitor + * + * Copyright (c) 2003-2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "cpu.h" +#include "monitor/monitor.h" +#include "monitor/hmp-target.h" +#include "hmp.h" + +void hmp_info_tlb(Monitor *mon, const QDict *qdict) +{ + CPUArchState *env1 = mon_get_cpu_env(); + + dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1); +} -- cgit v1.2.3-55-g7522 From 70703344de56c2119fcb7c2e01be3fa02087fb3c Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:39:00 +0300 Subject: hmp-commands.hx: fix end of table info The table info(information about the system state) closes earlier and some of its elements are outside(trace-events, rocker, etc). This can be confusing and lead to additional bugs. Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Peter Maydell Message-Id: <1441899541-1856-4-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- hmp-commands.hx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 286dcc75aa..89fc09ffea 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1811,7 +1811,6 @@ show the memory devices Display the value of a storage key (s390 only) @item info iothreads show iothreads -@end table ETEXI STEXI @@ -1846,3 +1845,7 @@ ETEXI STEXI @end table ETEXI + +STEXI +@end table +ETEXI -- cgit v1.2.3-55-g7522 From 2cd8af2d44268ffd4d224d6c297e8c644c01fa8d Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:39:01 +0300 Subject: monitor: added generation of documentation for hmp-commands-info.hx It will be easier if you need to add info-commands to edit only hmp-commands-info.hx, before this had to edit monitor.c and hmp-commands.hx. From the build point of view all documentation is saved into qemu-monitor-info.texi which from now on is used for all user documentation building. Signed-off-by: Pavel Butsykin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Peter Maydell Message-Id: <1441899541-1856-5-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- .gitignore | 1 + Makefile | 10 +++-- hmp-commands-info.hx | 8 ++++ hmp-commands.hx | 123 --------------------------------------------------- qemu-doc.texi | 2 + 5 files changed, 18 insertions(+), 126 deletions(-) diff --git a/.gitignore b/.gitignore index cb4b8ec137..367bc706d8 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ /qemu-ga /qemu-bridge-helper /qemu-monitor.texi +/qemu-monitor-info.texi /qmp-commands.txt /vscclient /fsdev/virtfs-proxy-helper diff --git a/Makefile b/Makefile index 9ce3972d84..c540442df5 100644 --- a/Makefile +++ b/Makefile @@ -344,7 +344,7 @@ qemu-%.tar.bz2: $(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)" distclean: clean - rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi + rm -f config-host.mak config-host.h* config-host.ld $(DOCS) qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi qemu-monitor-info.texi rm -f config-all-devices.mak config-all-disas.mak config.status rm -f po/*.mo tests/qemu-iotests/common.env rm -f roms/seabios/config.mak roms/vgabios/config.mak @@ -511,13 +511,16 @@ qemu-options.texi: $(SRC_PATH)/qemu-options.hx qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") +qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx + $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") + qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@," GEN $@") qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@") -qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi +qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi $(call quiet-command, \ perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu.pod && \ $(POD2MAN) --section=1 --center=" " --release=" " qemu.pod > $@, \ @@ -560,7 +563,8 @@ pdf: qemu-doc.pdf qemu-tech.pdf qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \ qemu-img.texi qemu-nbd.texi qemu-options.texi \ - qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi + qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \ + qemu-monitor-info.texi ifdef CONFIG_WIN32 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 1d0906a1cd..9f5a15826c 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -7,6 +7,10 @@ HXCOMM HXCOMM can be used for comments, discarded from both texi and C STEXI @table @option +@item info @var{subcommand} +@findex info +Show various information about the system state. +@table @option ETEXI { @@ -739,3 +743,7 @@ ETEXI STEXI @end table ETEXI + +STEXI +@end table +ETEXI diff --git a/hmp-commands.hx b/hmp-commands.hx index 89fc09ffea..a511004434 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1723,129 +1723,6 @@ ETEXI .sub_table = info_cmds, }, -STEXI -@item info @var{subcommand} -@findex info -Show various information about the system state. - -@table @option -@item info version -show the version of QEMU -@item info network -show the various VLANs and the associated devices -@item info chardev -show the character devices -@item info block -show the block devices -@item info blockstats -show block device statistics -@item info registers -show the cpu registers -@item info cpus -show infos for each CPU -@item info history -show the command line history -@item info irq -show the interrupts statistics (if available) -@item info pic -show i8259 (PIC) state -@item info pci -show emulated PCI device info -@item info tlb -show virtual to physical memory mappings (i386, SH4, SPARC, PPC, and Xtensa only) -@item info mem -show the active virtual memory mappings (i386 only) -@item info jit -show dynamic compiler info -@item info numa -show NUMA information -@item info kvm -show KVM information -@item info usb -show USB devices plugged on the virtual USB hub -@item info usbhost -show all USB host devices -@item info profile -show profiling information -@item info capture -show information about active capturing -@item info snapshots -show list of VM snapshots -@item info status -show the current VM status (running|paused) -@item info mice -show which guest mouse is receiving events -@item info vnc -show the vnc server status -@item info name -show the current VM name -@item info uuid -show the current VM UUID -@item info cpustats -show CPU statistics -@item info usernet -show user network stack connection states -@item info migrate -show migration status -@item info migrate_capabilities -show current migration capabilities -@item info migrate_parameters -show current migration parameters -@item info migrate_cache_size -show current migration XBZRLE cache size -@item info balloon -show balloon information -@item info qtree -show device tree -@item info qdm -show qdev device model list -@item info qom-tree -show object composition tree -@item info roms -show roms -@item info tpm -show the TPM device -@item info memory-devices -show the memory devices -@item info skeys -Display the value of a storage key (s390 only) -@item info iothreads -show iothreads -ETEXI - -STEXI -@item info trace-events -show available trace events and their state -ETEXI - -STEXI -@item rocker @var{name} -@findex rocker -Show Rocker(s) -ETEXI - -STEXI -@item rocker_ports @var{name} -@findex rocker_ports -Show Rocker ports -ETEXI - -STEXI -@item rocker_of_dpa_flows @var{name} [@var{tbl_id}] -@findex rocker_of_dpa_flows -Show Rocker OF-DPA flow tables -ETEXI - -STEXI -@item rocker_of_dpa_groups @var{name} [@var{type}] -@findex rocker_of_dpa_groups -Show Rocker OF-DPA groups -ETEXI - -STEXI -@end table -ETEXI - STEXI @end table ETEXI diff --git a/qemu-doc.texi b/qemu-doc.texi index 7af441283e..5b81aa052d 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -391,6 +391,8 @@ The following commands are available: @include qemu-monitor.texi +@include qemu-monitor-info.texi + @subsection Integer expressions The monitor understands integers expressions for every integer -- cgit v1.2.3-55-g7522 From 2d528d45ecf5ee3c1a566a9f3d664464925ef830 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 14 Sep 2015 13:54:03 +0200 Subject: qemu-char: Use g_new() & friends where that makes obvious sense g_new(T, n) is neater than g_malloc(sizeof(T) * n). It's also safer, for two reasons. One, it catches multiplication overflowing size_t. Two, it returns T * rather than void *, which lets the compiler catch more type errors. This commit only touches allocations with size arguments of the form sizeof(T). Same Coccinelle semantic patch as in commit b45c03f. Signed-off-by: Markus Armbruster Message-Id: <1442231643-23630-1-git-send-email-armbru@redhat.com> Signed-off-by: Paolo Bonzini --- backends/testdev.c | 4 ++-- qemu-char.c | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/backends/testdev.c b/backends/testdev.c index eba396aeb9..1429152d05 100644 --- a/backends/testdev.c +++ b/backends/testdev.c @@ -113,8 +113,8 @@ CharDriverState *chr_testdev_init(void) TestdevCharState *testdev; CharDriverState *chr; - testdev = g_malloc0(sizeof(TestdevCharState)); - testdev->chr = chr = g_malloc0(sizeof(CharDriverState)); + testdev = g_new0(TestdevCharState, 1); + testdev->chr = chr = g_new0(CharDriverState, 1); chr->opaque = testdev; chr->chr_write = testdev_write; diff --git a/qemu-char.c b/qemu-char.c index dd83203fa2..653ea10d6f 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -685,7 +685,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) MuxDriver *d; chr = qemu_chr_alloc(); - d = g_malloc0(sizeof(MuxDriver)); + d = g_new0(MuxDriver, 1); chr->opaque = d; d->drv = drv; @@ -1064,7 +1064,7 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) FDCharDriver *s; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(FDCharDriver)); + s = g_new0(FDCharDriver, 1); s->fd_in = io_channel_from_fd(fd_in); s->fd_out = io_channel_from_fd(fd_out); qemu_set_nonblock(fd_out); @@ -1413,7 +1413,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id, fprintf(stderr, "char device redirected to %s (label %s)\n", pty_name, id); - s = g_malloc0(sizeof(PtyCharDriver)); + s = g_new0(PtyCharDriver, 1); chr->opaque = s; chr->chr_write = pty_chr_write; chr->chr_update_read_handler = pty_chr_update_read_handler; @@ -1762,7 +1762,7 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd) return NULL; } - drv = g_malloc0(sizeof(ParallelCharDriver)); + drv = g_new0(ParallelCharDriver, 1); drv->fd = fd; drv->mode = IEEE1284_MODE_COMPAT; @@ -2050,7 +2050,7 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename) WinCharState *s; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(WinCharState)); + s = g_new0(WinCharState, 1); chr->opaque = s; chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; @@ -2149,7 +2149,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) WinCharState *s; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(WinCharState)); + s = g_new0(WinCharState, 1); chr->opaque = s; chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; @@ -2168,7 +2168,7 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) WinCharState *s; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(WinCharState)); + s = g_new0(WinCharState, 1); s->hcom = fd_out; chr->opaque = s; chr->chr_write = win_chr_write; @@ -2324,7 +2324,7 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) int is_console = 0; chr = qemu_chr_alloc(); - stdio = g_malloc0(sizeof(WinStdioCharState)); + stdio = g_new0(WinStdioCharState, 1); stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (stdio->hStdIn == INVALID_HANDLE_VALUE) { @@ -2487,7 +2487,7 @@ static CharDriverState *qemu_chr_open_udp_fd(int fd) NetCharDriver *s = NULL; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(NetCharDriver)); + s = g_new0(NetCharDriver, 1); s->fd = fd; s->chan = io_channel_from_socket(s->fd); @@ -2713,7 +2713,7 @@ static int tcp_set_msgfds(CharDriverState *chr, int *fds, int num) g_free(s->write_msgfds); if (num) { - s->write_msgfds = g_malloc(num * sizeof(int)); + s->write_msgfds = g_new(int, num); memcpy(s->write_msgfds, fds, num * sizeof(int)); } @@ -4144,7 +4144,7 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock, int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; chr = qemu_chr_alloc(); - s = g_malloc0(sizeof(TCPCharDriver)); + s = g_new0(TCPCharDriver, 1); s->fd = -1; s->listen_fd = -1; -- cgit v1.2.3-55-g7522 From 5abf9495ca9ff41160260ac274115825c10545cc Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:31 -0700 Subject: cpu-exec: Migrate some generic fns to cpu-exec-common The goal is to split the functions such that cpu-exec is CPU specific content, while cpus-exec-common.c is generic code only. The function interface to cpu-exec needs to be virtualised to prepare support for multi-arch and moving these definitions out saves bloating the QOM interface. So move these definitions out of cpu-exec to a new module, cpu-exec-common. Signed-off-by: Peter Crosthwaite Message-Id: <3cefeb3fbbb33031670951a0e74de2778529da3f.1441614289.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini --- Makefile.target | 1 + cpu-exec-common.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpu-exec.c | 59 ---------------------------------------- 3 files changed, 82 insertions(+), 59 deletions(-) create mode 100644 cpu-exec-common.c diff --git a/Makefile.target b/Makefile.target index 92cff906ad..0d8c504e23 100644 --- a/Makefile.target +++ b/Makefile.target @@ -85,6 +85,7 @@ all: $(PROGS) stap ######################################################### # cpu emulator library obj-y = exec.o translate-all.o cpu-exec.o +obj-y += cpu-exec-common.o obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o obj-$(CONFIG_TCG_INTERPRETER) += tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o diff --git a/cpu-exec-common.c b/cpu-exec-common.c new file mode 100644 index 0000000000..16d305b911 --- /dev/null +++ b/cpu-exec-common.c @@ -0,0 +1,81 @@ +/* + * emulator main execution loop + * + * Copyright (c) 2003-2005 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "config.h" +#include "cpu.h" +#include "sysemu/cpus.h" +#include "exec/memory-internal.h" + +bool exit_request; +CPUState *tcg_current_cpu; + +/* exit the current TB from a signal handler. The host registers are + restored in a state compatible with the CPU emulator + */ +#if defined(CONFIG_SOFTMMU) +void cpu_resume_from_signal(CPUState *cpu, void *puc) +{ + /* XXX: restore cpu registers saved in host registers */ + + cpu->exception_index = -1; + siglongjmp(cpu->jmp_env, 1); +} + +void cpu_reload_memory_map(CPUState *cpu) +{ + AddressSpaceDispatch *d; + + if (qemu_in_vcpu_thread()) { + /* Do not let the guest prolong the critical section as much as it + * as it desires. + * + * Currently, this is prevented by the I/O thread's periodinc kicking + * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread) + * but this will go away once TCG's execution moves out of the global + * mutex. + * + * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which + * only protects cpu->as->dispatch. Since we reload it below, we can + * split the critical section. + */ + rcu_read_unlock(); + rcu_read_lock(); + } + + /* The CPU and TLB are protected by the iothread lock. */ + d = atomic_rcu_read(&cpu->as->dispatch); + cpu->memory_dispatch = d; + tlb_flush(cpu, 1); +} +#endif + +void cpu_loop_exit(CPUState *cpu) +{ + cpu->current_tb = NULL; + siglongjmp(cpu->jmp_env, 1); +} + +void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) +{ + if (pc) { + cpu_restore_state(cpu, pc); + } + cpu->current_tb = NULL; + siglongjmp(cpu->jmp_env, 1); +} diff --git a/cpu-exec.c b/cpu-exec.c index 89455339ea..947e646ae4 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -25,7 +25,6 @@ #include "sysemu/qtest.h" #include "qemu/timer.h" #include "exec/address-spaces.h" -#include "exec/memory-internal.h" #include "qemu/rcu.h" #include "exec/tb-hash.h" @@ -128,61 +127,6 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) } #endif /* CONFIG USER ONLY */ -void cpu_loop_exit(CPUState *cpu) -{ - cpu->current_tb = NULL; - siglongjmp(cpu->jmp_env, 1); -} - -void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) -{ - if (pc) { - cpu_restore_state(cpu, pc); - } - cpu->current_tb = NULL; - siglongjmp(cpu->jmp_env, 1); -} - -/* exit the current TB from a signal handler. The host registers are - restored in a state compatible with the CPU emulator - */ -#if defined(CONFIG_SOFTMMU) -void cpu_resume_from_signal(CPUState *cpu, void *puc) -{ - /* XXX: restore cpu registers saved in host registers */ - - cpu->exception_index = -1; - siglongjmp(cpu->jmp_env, 1); -} - -void cpu_reload_memory_map(CPUState *cpu) -{ - AddressSpaceDispatch *d; - - if (qemu_in_vcpu_thread()) { - /* Do not let the guest prolong the critical section as much as it - * as it desires. - * - * Currently, this is prevented by the I/O thread's periodinc kicking - * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread) - * but this will go away once TCG's execution moves out of the global - * mutex. - * - * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which - * only protects cpu->as->dispatch. Since we reload it below, we can - * split the critical section. - */ - rcu_read_unlock(); - rcu_read_lock(); - } - - /* The CPU and TLB are protected by the iothread lock. */ - d = atomic_rcu_read(&cpu->as->dispatch); - cpu->memory_dispatch = d; - tlb_flush(cpu, 1); -} -#endif - /* Execute a TB, and fix up the CPU state afterwards if necessary */ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) { @@ -385,9 +329,6 @@ static void cpu_handle_debug_exception(CPUState *cpu) /* main execution loop */ -bool exit_request; -CPUState *tcg_current_cpu; - int cpu_exec(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); -- cgit v1.2.3-55-g7522 From 9b68a7754a892d8deb7696cfe609fe2ec3c6034a Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:33 -0700 Subject: translate-all: Move tcg_handle_interrupt() to -common Move this function to common code. It has no arch specific dependencies. Prepares support for multi-arch where the translate-all interface needs to be virtualised. One less thing to virtualise. Reviewed-by: Richard Henderson Signed-off-by: Peter Crosthwaite Message-Id: <44a7c73604ed2552af47ed02b047b6a772b683e0.1441614289.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini --- Makefile.target | 1 + translate-all.c | 30 ------------------------------ translate-common.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 translate-common.c diff --git a/Makefile.target b/Makefile.target index 0d8c504e23..43b3eb1682 100644 --- a/Makefile.target +++ b/Makefile.target @@ -85,6 +85,7 @@ all: $(PROGS) stap ######################################################### # cpu emulator library obj-y = exec.o translate-all.o cpu-exec.o +obj-y += translate-common.o obj-y += cpu-exec-common.o obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o obj-$(CONFIG_TCG_INTERPRETER) += tci.o diff --git a/translate-all.c b/translate-all.c index 0b8b34b884..0140255127 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1491,36 +1491,6 @@ void tb_check_watchpoint(CPUState *cpu) } #ifndef CONFIG_USER_ONLY -/* mask must never be zero, except for A20 change call */ -static void tcg_handle_interrupt(CPUState *cpu, int mask) -{ - int old_mask; - - old_mask = cpu->interrupt_request; - cpu->interrupt_request |= mask; - - /* - * If called from iothread context, wake the target cpu in - * case its halted. - */ - if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(cpu); - return; - } - - if (use_icount) { - cpu->icount_decr.u16.high = 0xffff; - if (!cpu->can_do_io - && (mask & ~old_mask) != 0) { - cpu_abort(cpu, "Raised interrupt while not in I/O function"); - } - } else { - cpu->tcg_exit_req = 1; - } -} - -CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt; - /* in deterministic execution mode, instructions doing device I/Os must be at the end of the TB */ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr) diff --git a/translate-common.c b/translate-common.c new file mode 100644 index 0000000000..681e2bf8d5 --- /dev/null +++ b/translate-common.c @@ -0,0 +1,53 @@ +/* + * Host code generation common components + * + * Copyright (c) 2015 Peter Crosthwaite + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu-common.h" +#include "qom/cpu.h" + +#ifndef CONFIG_USER_ONLY +/* mask must never be zero, except for A20 change call */ +static void tcg_handle_interrupt(CPUState *cpu, int mask) +{ + int old_mask; + + old_mask = cpu->interrupt_request; + cpu->interrupt_request |= mask; + + /* + * If called from iothread context, wake the target cpu in + * case its halted. + */ + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + return; + } + + if (use_icount) { + cpu->icount_decr.u16.high = 0xffff; + if (!cpu->can_do_io + && (mask & ~old_mask) != 0) { + cpu_abort(cpu, "Raised interrupt while not in I/O function"); + } + } else { + cpu->tcg_exit_req = 1; + } +} + +CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt; +#endif -- cgit v1.2.3-55-g7522 From 7d8f787d9d261d6880b69e35ed682241e3f9242f Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:34 -0700 Subject: tcg: split tcg_op_defs to -common tcg_op_defs (and the _max) are both needed by the TCI disassembler. For multi-arch, tcg.c will be multiple-compiled (arch-obj) with its symbols hidden from common code. So split the definition off to new file, tcg-common.c which will remain a regular obj-y for use by both the TCI disas as well as the multiple tcg.c's. Cc: Stefan Weil Signed-off-by: Peter Crosthwaite Message-Id: <4b607425886d85aee65878e4935dfad46b3e6085.1441614289.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini --- Makefile.target | 1 + tcg/tcg-common.c | 33 +++++++++++++++++++++++++++++++++ tcg/tcg.c | 8 +------- tcg/tci/tcg-target.c | 2 +- 4 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 tcg/tcg-common.c diff --git a/Makefile.target b/Makefile.target index 43b3eb1682..04538e49e1 100644 --- a/Makefile.target +++ b/Makefile.target @@ -89,6 +89,7 @@ obj-y += translate-common.o obj-y += cpu-exec-common.o obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o obj-$(CONFIG_TCG_INTERPRETER) += tci.o +obj-y += tcg/tcg-common.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-y += fpu/softfloat.o obj-y += target-$(TARGET_BASE_ARCH)/ diff --git a/tcg/tcg-common.c b/tcg/tcg-common.c new file mode 100644 index 0000000000..6a68c42032 --- /dev/null +++ b/tcg/tcg-common.c @@ -0,0 +1,33 @@ +/* + * Tiny Code Generator for QEMU + * + * Copyright (c) 2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "tcg/tcg.h" + +TCGOpDef tcg_op_defs[] = { +#define DEF(s, oargs, iargs, cargs, flags) \ + { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, +#include "tcg-opc.h" +#undef DEF +}; +const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); diff --git a/tcg/tcg.c b/tcg/tcg.c index f463e44639..a2cb027a14 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -113,12 +113,6 @@ static void tcg_out_tb_init(TCGContext *s); static void tcg_out_tb_finalize(TCGContext *s); -TCGOpDef tcg_op_defs[] = { -#define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, -#include "tcg-opc.h" -#undef DEF -}; -const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); static TCGRegSet tcg_target_available_regs[2]; static TCGRegSet tcg_target_call_clobber_regs; @@ -1240,7 +1234,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) #if defined(CONFIG_DEBUG_TCG) i = 0; - for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) { + for (op = 0; op < tcg_op_defs_max; op++) { const TCGOpDef *def = &tcg_op_defs[op]; if (def->flags & TCG_OPF_NOT_PRESENT) { /* Wrong entry in op definitions? */ diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c index bbb54d4e8c..4afe4d7a8d 100644 --- a/tcg/tci/tcg-target.c +++ b/tcg/tci/tcg-target.c @@ -850,7 +850,7 @@ static void tcg_target_init(TCGContext *s) #endif /* The current code uses uint8_t for tcg operations. */ - assert(ARRAY_SIZE(tcg_op_defs) <= UINT8_MAX); + assert(tcg_op_defs_max <= UINT8_MAX); /* Registers available for 32 bit operations. */ tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, -- cgit v1.2.3-55-g7522 From 162e992270fd3587b21fa77fd4a8ccc879c402c9 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:35 -0700 Subject: tcg: Move tci_tb_ptr to -common This requires global visibility to common code. Move to tcg-common. Cc: Stefan Weil Signed-off-by: Peter Crosthwaite Message-Id: Signed-off-by: Paolo Bonzini --- tcg/tcg-common.c | 4 ++++ tci.c | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tcg/tcg-common.c b/tcg/tcg-common.c index 6a68c42032..8fa4e13305 100644 --- a/tcg/tcg-common.c +++ b/tcg/tcg-common.c @@ -24,6 +24,10 @@ #include "tcg/tcg.h" +#if defined(CONFIG_TCG_INTERPRETER) +uintptr_t tci_tb_ptr; +#endif + TCGOpDef tcg_op_defs[] = { #define DEF(s, oargs, iargs, cargs, flags) \ { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags }, diff --git a/tci.c b/tci.c index 3d6d17783d..70eaab25eb 100644 --- a/tci.c +++ b/tci.c @@ -52,12 +52,6 @@ typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong, tcg_target_ulong); #endif -/* Targets which don't use GETPC also don't need tci_tb_ptr - which makes them a little faster. */ -#if defined(GETPC) -uintptr_t tci_tb_ptr; -#endif - static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS]; static tcg_target_ulong tci_read_reg(TCGReg index) -- cgit v1.2.3-55-g7522 From 5f12a788c04cf36442f3be00ebf6fdc3b8c8c4ba Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:36 -0700 Subject: translate: move real_host_page setting to -common Move the size and mask globals for the "real" host page size to translate-common. This is to allow system-level code to use REAL_HOST_PAGE_ALIGN and friends in builds which hide translate-all behind arch-obj. Cc: dgilbert@redhat.com Signed-off-by: Peter Crosthwaite Message-Id: Signed-off-by: Paolo Bonzini --- translate-all.c | 2 -- translate-common.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/translate-all.c b/translate-all.c index 0140255127..4a9ee33dac 100644 --- a/translate-all.c +++ b/translate-all.c @@ -117,8 +117,6 @@ typedef struct PageDesc { #define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS) -uintptr_t qemu_real_host_page_size; -uintptr_t qemu_real_host_page_mask; uintptr_t qemu_host_page_size; uintptr_t qemu_host_page_mask; diff --git a/translate-common.c b/translate-common.c index 681e2bf8d5..619feb466e 100644 --- a/translate-common.c +++ b/translate-common.c @@ -20,6 +20,9 @@ #include "qemu-common.h" #include "qom/cpu.h" +uintptr_t qemu_real_host_page_size; +uintptr_t qemu_real_host_page_mask; + #ifndef CONFIG_USER_ONLY /* mask must never be zero, except for A20 change call */ static void tcg_handle_interrupt(CPUState *cpu, int mask) -- cgit v1.2.3-55-g7522 From 9a13565d52bfd321934fb44ee004bbaf5f5913a8 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:41 -0700 Subject: cputlb: move CPU_LOOP() for tlb_reset() to exec.c To prepare for multi-arch, cputlb.c should only have awareness of one single architecture. This means it should not have access to the full CPU lists which may be heterogeneous. Instead, push the CPU_LOOP() up to the one and only caller in exec.c. Signed-off-by: Peter Crosthwaite Message-Id: Signed-off-by: Paolo Bonzini --- cputlb.c | 27 ++++++++++++--------------- exec.c | 5 ++++- include/exec/cputlb.h | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cputlb.c b/cputlb.c index fbcebe3cf4..dd149a28bc 100644 --- a/cputlb.c +++ b/cputlb.c @@ -262,27 +262,24 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr) return ram_addr; } -void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length) +void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length) { - CPUState *cpu; CPUArchState *env; - CPU_FOREACH(cpu) { - int mmu_idx; + int mmu_idx; - env = cpu->env_ptr; - for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { - unsigned int i; + env = cpu->env_ptr; + for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { + unsigned int i; - for (i = 0; i < CPU_TLB_SIZE; i++) { - tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i], - start1, length); - } + for (i = 0; i < CPU_TLB_SIZE; i++) { + tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i], + start1, length); + } - for (i = 0; i < CPU_VTLB_SIZE; i++) { - tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i], - start1, length); - } + for (i = 0; i < CPU_VTLB_SIZE; i++) { + tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i], + start1, length); } } } diff --git a/exec.c b/exec.c index 07dfeae4d8..1fa27f5c08 100644 --- a/exec.c +++ b/exec.c @@ -913,6 +913,7 @@ found: static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length) { + CPUState *cpu; ram_addr_t start1; RAMBlock *block; ram_addr_t end; @@ -924,7 +925,9 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length) block = qemu_get_ram_block(start); assert(block == qemu_get_ram_block(end - 1)); start1 = (uintptr_t)ramblock_ptr(block, start - block->offset); - cpu_tlb_reset_dirty_all(start1, length); + CPU_FOREACH(cpu) { + tlb_reset_dirty(cpu, start1, length); + } rcu_read_unlock(); } diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index 360815e1b4..c3aaa30efa 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -25,7 +25,7 @@ void tlb_protect_code(ram_addr_t ram_addr); void tlb_unprotect_code(ram_addr_t ram_addr); void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, uintptr_t length); -void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length); +void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); void tlb_set_dirty(CPUArchState *env, target_ulong vaddr); extern int tlb_flush_count; -- cgit v1.2.3-55-g7522 From bcae01e468d961ad9afaf4148329147e4be209ab Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:42 -0700 Subject: cputlb: Change tlb_set_dirty() arg to cpu Change tlb_set_dirty() to accept a CPU instead of an env pointer. This allows for removal of another CPUArchState usage from prototypes that need to be QOMified. Signed-off-by: Peter Crosthwaite Message-Id: Signed-off-by: Paolo Bonzini --- cputlb.c | 3 ++- exec.c | 3 +-- include/exec/cputlb.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cputlb.c b/cputlb.c index dd149a28bc..bf1d50adde 100644 --- a/cputlb.c +++ b/cputlb.c @@ -293,8 +293,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr) /* update the TLB corresponding to virtual page vaddr so that it is no longer dirty */ -void tlb_set_dirty(CPUArchState *env, target_ulong vaddr) +void tlb_set_dirty(CPUState *cpu, target_ulong vaddr) { + CPUArchState *env = cpu->env_ptr; int i; int mmu_idx; diff --git a/exec.c b/exec.c index 1fa27f5c08..f760f44911 100644 --- a/exec.c +++ b/exec.c @@ -1922,8 +1922,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, /* we remove the notdirty callback only if the code has been flushed */ if (!cpu_physical_memory_is_clean(ram_addr)) { - CPUArchState *env = current_cpu->env_ptr; - tlb_set_dirty(env, current_cpu->mem_io_vaddr); + tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr); } } diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index c3aaa30efa..7ad5c9a467 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -26,7 +26,7 @@ void tlb_unprotect_code(ram_addr_t ram_addr); void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, uintptr_t length); void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); -void tlb_set_dirty(CPUArchState *env, target_ulong vaddr); +void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); extern int tlb_flush_count; /* exec.c */ -- cgit v1.2.3-55-g7522 From dfccc7602374c9fd3b083208b552d62daa244811 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:43 -0700 Subject: include/exec: Move cputlb exec.c defs out Move the architecture agnostic function prototypes for exec.c out of cputlb.h to exec-all.h. This allows hiding of the arch specific cputlb.h from exec.c which should be getting close to having no architecture specifics. Prepares support for multi-arch, which will have a minimal cpu.h that services exec.c but not cputlb.h. Reviewed-by: Richard Henderson Signed-off-by: Peter Crosthwaite Message-Id: Signed-off-by: Paolo Bonzini --- exec.c | 1 - include/exec/cputlb.h | 16 ---------------- include/exec/exec-all.h | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/exec.c b/exec.c index f760f44911..47ada31040 100644 --- a/exec.c +++ b/exec.c @@ -49,7 +49,6 @@ #include "exec/cpu-all.h" #include "qemu/rcu_queue.h" #include "qemu/main-loop.h" -#include "exec/cputlb.h" #include "translate-all.h" #include "exec/memory-internal.h" diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index 7ad5c9a467..d454c005b7 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -25,23 +25,7 @@ void tlb_protect_code(ram_addr_t ram_addr); void tlb_unprotect_code(ram_addr_t ram_addr); void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, uintptr_t length); -void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); -void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); extern int tlb_flush_count; -/* exec.c */ -void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr); - -MemoryRegionSection * -address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, - hwaddr *plen); -hwaddr memory_region_section_get_iotlb(CPUState *cpu, - MemoryRegionSection *section, - target_ulong vaddr, - hwaddr paddr, hwaddr xlat, - int prot, - target_ulong *address); -bool memory_region_is_unassigned(MemoryRegion *mr); - #endif #endif diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 72d4012ed9..a3719b7f0d 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -388,6 +388,24 @@ static inline void mmap_unlock(void) {} /* cputlb.c */ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr); + +void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); +void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); + +/* exec.c */ +void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr); + +MemoryRegionSection * +address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, + hwaddr *plen); +hwaddr memory_region_section_get_iotlb(CPUState *cpu, + MemoryRegionSection *section, + target_ulong vaddr, + hwaddr paddr, hwaddr xlat, + int prot, + target_ulong *address); +bool memory_region_is_unassigned(MemoryRegion *mr); + #endif /* vl.c */ -- cgit v1.2.3-55-g7522 From e6b65fe1c234b5f63af075b9c85691ea744ead34 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:45 -0700 Subject: monitor: uninclude cpu_ldst This header is non-needed anymore and wont work in multi-arch where this service is not provided to core code. Cc: Markus Armbruster Signed-off-by: Peter Crosthwaite Message-Id: <4e96622ab5320603829b6f94b8c4e94d573d34fc.1441614289.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini --- monitor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/monitor.c b/monitor.c index b4578cb8ea..1f432635ad 100644 --- a/monitor.c +++ b/monitor.c @@ -68,7 +68,6 @@ #include "trace/simple.h" #endif #include "exec/memory.h" -#include "exec/cpu_ldst.h" #include "qmp-commands.h" #include "hmp.h" #include "qemu/thread.h" -- cgit v1.2.3-55-g7522 From 04f2562f8ec6af573508880ac607d098a5d3ad7f Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Fri, 11 Sep 2015 19:07:36 +0800 Subject: checkpatch: Escape left braces in regex Latest perl now deprecates "{" literal in regex and print warnings like "unescaped left brace in regex is deprecated". Add escape to keep it happy. Signed-off-by: Fam Zheng Message-Id: <1441969656-2640-1-git-send-email-famz@redhat.com> Signed-off-by: Paolo Bonzini --- scripts/checkpatch.pl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4ac00a9121..574334b985 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -582,7 +582,7 @@ sub statement_block_size { my ($stmt) = @_; $stmt =~ s/(^|\n)./$1/g; - $stmt =~ s/^\s*{//; + $stmt =~ s/^\s*\{//; $stmt =~ s/}\s*$//; $stmt =~ s/^\s*//; $stmt =~ s/\s*$//; @@ -1479,7 +1479,7 @@ sub process { # 79 or 80 characters, it is no longer possible to add a space and an # opening brace there) if ($#ctx == 0 && $ctx !~ /{\s*/ && - defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/ && + defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*\{/ && defined($lines[$ctx_ln - 2]) && length($lines[$ctx_ln - 2]) < 80) { ERROR("that open brace { should be on the previous line\n" . "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); @@ -1519,7 +1519,7 @@ sub process { my $continuation = 0; my $check = 0; $s =~ s/^.*\bdo\b//; - $s =~ s/^\s*{//; + $s =~ s/^\s*\{//; if ($s =~ s/^\s*\\//) { $continuation = 1; } @@ -1618,7 +1618,7 @@ sub process { } # check for initialisation to aggregates open brace on the next line - if ($line =~ /^.\s*{/ && + if ($line =~ /^.\s*\{/ && $prevline =~ /(?:^|[^=])=\s*$/) { ERROR("that open brace { should be on the previous line\n" . $hereprev); } @@ -1693,13 +1693,13 @@ sub process { # function brace can't be on same line, except for #defines of do while, # or if closed on same line - if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and - !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { + if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and + !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } # open braces for enum, union and struct go on the same line. - if ($line =~ /^.\s*{/ && + if ($line =~ /^.\s*\{/ && $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); } @@ -1853,7 +1853,7 @@ sub process { # not required when having a single },{ on one line } elsif ($op eq ',') { if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ && - ($elements[$n] . $elements[$n + 2]) !~ " *}{") { + ($elements[$n] . $elements[$n + 2]) !~ " *}\\{") { ERROR("space required after that '$op' $at\n" . $hereptr); } @@ -1953,8 +1953,8 @@ sub process { } #need space before brace following if, while, etc - if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || - $line =~ /do{/) { + if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || + $line =~ /do\{/) { ERROR("space required before the open brace '{'\n" . $herecurr); } @@ -2268,7 +2268,7 @@ sub process { my $spaced_block = $block; $spaced_block =~ s/\n\+/ /g; - $seen++ if ($spaced_block =~ /^\s*{/); + $seen++ if ($spaced_block =~ /^\s*\{/); print "APW: cond<$cond> block<$block> allowed<$allowed>\n" if $dbg_adv_apw; -- cgit v1.2.3-55-g7522 From d6268348493f32ecc096caa637620757472a1196 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Wed, 16 Sep 2015 16:35:46 +0800 Subject: nbd: release exp->blk after all clients are closed If the socket fd is shutdown, there may be some data which is received before shutdown. We will read the data and do read/write in nbd_trip(). But the exp's blk is NULL, and it will cause qemu crashed. Reported-by: Li Zhijian Signed-off-by: Wen Congyang Message-Id: <55F929E2.1020501@cn.fujitsu.com> Signed-off-by: Paolo Bonzini --- nbd.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/nbd.c b/nbd.c index 06b501ba67..07240bd3e3 100644 --- a/nbd.c +++ b/nbd.c @@ -1131,12 +1131,6 @@ void nbd_export_close(NBDExport *exp) } nbd_export_set_name(exp, NULL); nbd_export_put(exp); - if (exp->blk) { - blk_remove_aio_context_notifier(exp->blk, blk_aio_attached, - blk_aio_detach, exp); - blk_unref(exp->blk); - exp->blk = NULL; - } } void nbd_export_get(NBDExport *exp) @@ -1159,6 +1153,13 @@ void nbd_export_put(NBDExport *exp) exp->close(exp); } + if (exp->blk) { + blk_remove_aio_context_notifier(exp->blk, blk_aio_attached, + blk_aio_detach, exp); + blk_unref(exp->blk); + exp->blk = NULL; + } + g_free(exp); } } @@ -1305,6 +1306,14 @@ static void nbd_trip(void *opaque) goto invalid_request; } + if (client->closing) { + /* + * The client may be closed when we are blocked in + * nbd_co_receive_request() + */ + goto done; + } + switch (command) { case NBD_CMD_READ: TRACE("Request type is READ"); -- cgit v1.2.3-55-g7522