From 05620f85e930b0ac3dc22fdf8e4c390fa11afdeb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 16 Sep 2015 14:26:59 +0200 Subject: [PATCH 01/24] 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(); } From 84090bbce91a386ae6e5f61b26f36783196712d2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 10 Sep 2015 11:31:12 +0200 Subject: [PATCH 02/24] pci: remove Link Training error from AER error list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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, From 120758fba4c52d1ccf3a8ae1fe3b7495f2b584d8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 14:50:17 +0200 Subject: [PATCH 03/24] 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 | 379 ++++++++++++++----- 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, 295 insertions(+), 98 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) +#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 entry's format */ +/* 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 From eddb4de3cc1403546b29e260068c4c1397cbd62d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 15:25:52 +0200 Subject: [PATCH 04/24] 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 From 73aa529a48b4ed7fce21fc74e62fb24db526af5f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 9 Sep 2015 15:25:52 +0200 Subject: [PATCH 05/24] 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" From bac05aa9a77af1ca7972c8dc07560f4daa7c2dfc Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Fri, 3 Jul 2015 15:01:44 +0300 Subject: [PATCH 06/24] cpu: Add crash_occurred flag into CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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); } From 7c207b90465bc16a39b9fb8d9194f161059f69bf Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Fri, 3 Jul 2015 15:01:43 +0300 Subject: [PATCH 07/24] kvm: Add kvm system event crash handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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); From f2a53c9e05a24352a0f9740db0539ce5aeed22ca Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 9 Sep 2015 14:41:30 +0200 Subject: [PATCH 08/24] i386/kvm: Hyper-v crash msrs set/get'ers and migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 From da76ee76f78b9705e2a91e3c964aef28fecededb Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:38:58 +0300 Subject: [PATCH 09/24] 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 */ From bf957284006b6325e6ed64fd839c237c15b42029 Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:38:59 +0300 Subject: [PATCH 10/24] 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); +} From 70703344de56c2119fcb7c2e01be3fa02087fb3c Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:39:00 +0300 Subject: [PATCH 11/24] 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 From 2cd8af2d44268ffd4d224d6c297e8c644c01fa8d Mon Sep 17 00:00:00 2001 From: Pavel Butsykin Date: Thu, 10 Sep 2015 18:39:01 +0300 Subject: [PATCH 12/24] 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 From 2d528d45ecf5ee3c1a566a9f3d664464925ef830 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 14 Sep 2015 13:54:03 +0200 Subject: [PATCH 13/24] 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; From 5abf9495ca9ff41160260ac274115825c10545cc Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:31 -0700 Subject: [PATCH 14/24] 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); From 9b68a7754a892d8deb7696cfe609fe2ec3c6034a Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:33 -0700 Subject: [PATCH 15/24] 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 From 7d8f787d9d261d6880b69e35ed682241e3f9242f Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:34 -0700 Subject: [PATCH 16/24] 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, From 162e992270fd3587b21fa77fd4a8ccc879c402c9 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:35 -0700 Subject: [PATCH 17/24] 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) From 5f12a788c04cf36442f3be00ebf6fdc3b8c8c4ba Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:36 -0700 Subject: [PATCH 18/24] 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) From 9a13565d52bfd321934fb44ee004bbaf5f5913a8 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:41 -0700 Subject: [PATCH 19/24] 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; From bcae01e468d961ad9afaf4148329147e4be209ab Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:42 -0700 Subject: [PATCH 20/24] 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 */ From dfccc7602374c9fd3b083208b552d62daa244811 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:43 -0700 Subject: [PATCH 21/24] 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 */ From e6b65fe1c234b5f63af075b9c85691ea744ead34 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 10 Sep 2015 22:39:45 -0700 Subject: [PATCH 22/24] 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" From 04f2562f8ec6af573508880ac607d098a5d3ad7f Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Fri, 11 Sep 2015 19:07:36 +0800 Subject: [PATCH 23/24] 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; From d6268348493f32ecc096caa637620757472a1196 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Wed, 16 Sep 2015 16:35:46 +0800 Subject: [PATCH 24/24] 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");