From c5f860e1cb5d7f6725cb9e9f366bcb96f40b85bc Mon Sep 17 00:00:00 2001 From: "Zheng, Gen" Date: Mon, 16 Apr 2018 12:07:42 +0800 Subject: [PATCH] MMU: bug fix on operating va <=> pa convertion Before referencing to physical address of devs such as lapic, ioapic, vtd, and uart, switch to virtual address. Use a phisical address of pml4 to write CR3. Signed-off-by: Zheng, Gen --- hypervisor/arch/x86/interrupt.c | 10 +++++----- hypervisor/arch/x86/intr_lapic.c | 2 +- hypervisor/arch/x86/ioapic.c | 28 ++++++++++++++-------------- hypervisor/arch/x86/mmu.c | 10 +++++----- hypervisor/arch/x86/vtd.c | 14 +++++++------- hypervisor/debug/uart16550.c | 6 +++--- hypervisor/include/arch/x86/mmu.h | 4 ++-- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/hypervisor/arch/x86/interrupt.c b/hypervisor/arch/x86/interrupt.c index 0b79cc165..f19db3880 100644 --- a/hypervisor/arch/x86/interrupt.c +++ b/hypervisor/arch/x86/interrupt.c @@ -215,11 +215,11 @@ void dump_lapic(void) { dev_dbg(ACRN_DBG_INTR, "LAPIC: TIME %08x, init=0x%x cur=0x%x ISR=0x%x IRR=0x%x", - mmio_read_long((void*)(0xFEE00000 + LAPIC_LVT_TIMER_REGISTER)), - mmio_read_long((void*)(0xFEE00000 + LAPIC_INITIAL_COUNT_REGISTER)), - mmio_read_long((void*)(0xFEE00000 + LAPIC_CURRENT_COUNT_REGISTER)), - mmio_read_long((void*)(0xFEE00000 + LAPIC_IN_SERVICE_REGISTER_7)), - mmio_read_long((void*)(0xFEE00000 + LAPIC_INT_REQUEST_REGISTER_7))); + mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_LVT_TIMER_REGISTER)), + mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_INITIAL_COUNT_REGISTER)), + mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_CURRENT_COUNT_REGISTER)), + mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_IN_SERVICE_REGISTER_7)), + mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_INT_REQUEST_REGISTER_7))); } int vcpu_inject_extint(struct vcpu *vcpu) diff --git a/hypervisor/arch/x86/intr_lapic.c b/hypervisor/arch/x86/intr_lapic.c index ed0950163..b9f212982 100644 --- a/hypervisor/arch/x86/intr_lapic.c +++ b/hypervisor/arch/x86/intr_lapic.c @@ -204,7 +204,7 @@ static void map_lapic(void) /* At some point we may need to translate this paddr to a vaddr. 1:1 * mapping for now. */ - lapic_info.xapic.vaddr = (void *)lapic_info.xapic.paddr; + lapic_info.xapic.vaddr = HPA2HVA(lapic_info.xapic.paddr); } int early_init_lapic(void) diff --git a/hypervisor/arch/x86/ioapic.c b/hypervisor/arch/x86/ioapic.c index a96b0afba..1baf697bd 100644 --- a/hypervisor/arch/x86/ioapic.c +++ b/hypervisor/arch/x86/ioapic.c @@ -47,7 +47,7 @@ struct ioapic_rte { struct gsi_table { uint8_t ioapic_id; uint8_t pin; - uint64_t addr; + void *addr; }; static struct gsi_table gsi_table[NR_MAX_GSI]; static int nr_gsi; @@ -76,17 +76,17 @@ uint16_t legacy_irq_to_pin[NR_LEGACY_IRQ] = { 15, /* IRQ15*/ }; -static uint64_t map_ioapic( +static void *map_ioapic( uint64_t ioapic_paddr) { /* At some point we may need to translate this paddr to a vaddr. * 1:1 mapping for now. */ - return ioapic_paddr; + return HPA2HVA(ioapic_paddr); } static inline uint32_t -ioapic_read_reg32(const uint64_t ioapic_base, const uint8_t offset) +ioapic_read_reg32(const void *ioapic_base, const uint8_t offset) { uint32_t v; @@ -104,7 +104,7 @@ ioapic_read_reg32(const uint64_t ioapic_base, const uint8_t offset) } static inline void -ioapic_write_reg32(const uint64_t ioapic_base, +ioapic_write_reg32(const void *ioapic_base, const uint8_t offset, const uint32_t value) { spinlock_rflags; @@ -138,7 +138,7 @@ get_ioapic_base(int apic_id) static inline void -ioapic_get_rte_entry(uint64_t ioapic_addr, +ioapic_get_rte_entry(void *ioapic_addr, int pin, struct ioapic_rte *rte) { rte->lo_32 = ioapic_read_reg32(ioapic_addr, pin*2 + 0x10); @@ -146,7 +146,7 @@ ioapic_get_rte_entry(uint64_t ioapic_addr, } static inline void -ioapic_set_rte_entry(uint64_t ioapic_addr, +ioapic_set_rte_entry(void *ioapic_addr, int pin, struct ioapic_rte *rte) { ioapic_write_reg32(ioapic_addr, pin*2 + 0x10, rte->lo_32); @@ -204,7 +204,7 @@ create_rte_for_gsi_irq(int irq, int vr) static void ioapic_set_routing(int gsi, int vr) { - uint64_t addr; + void *addr; struct ioapic_rte rte; addr = gsi_table[gsi].addr; @@ -223,7 +223,7 @@ static void ioapic_set_routing(int gsi, int vr) void ioapic_get_rte(int irq, uint64_t *rte) { - uint64_t addr; + void *addr; struct ioapic_rte _rte; if (!irq_is_gsi(irq)) @@ -238,7 +238,7 @@ void ioapic_get_rte(int irq, uint64_t *rte) void ioapic_set_rte(int irq, uint64_t raw_rte) { - uint64_t addr; + void *addr; struct ioapic_rte rte; if (!irq_is_gsi(irq)) @@ -289,7 +289,7 @@ int pin_to_irq(int pin) void irq_gsi_mask_unmask(int irq, bool mask) { - uint64_t addr = gsi_table[irq].addr; + void *addr = gsi_table[irq].addr; int pin = gsi_table[irq].pin; struct ioapic_rte rte; @@ -318,7 +318,7 @@ void setup_ioapic_irq(void) int pin; int max_pins; int version; - uint64_t addr; + void *addr; addr = map_ioapic(get_ioapic_base(ioapic_id)); version = ioapic_read_reg32(addr, IOAPIC_VER); @@ -372,7 +372,7 @@ void dump_ioapic(void) int irq; for (irq = 0; irq < nr_gsi; irq++) { - uint64_t addr = gsi_table[irq].addr; + void *addr = gsi_table[irq].addr; int pin = gsi_table[irq].pin; struct ioapic_rte rte; @@ -404,7 +404,7 @@ int get_ioapic_info(char *str, int str_max_len) str += len; for (irq = 0; irq < nr_gsi; irq++) { - uint64_t addr = gsi_table[irq].addr; + void *addr = gsi_table[irq].addr; int pin = gsi_table[irq].pin; struct ioapic_rte rte; diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c index 86f598969..f56114651 100644 --- a/hypervisor/arch/x86/mmu.c +++ b/hypervisor/arch/x86/mmu.c @@ -468,15 +468,15 @@ static void *walk_paging_struct(void *addr, void *table_base, return sub_table_addr; } -void *get_paging_pml4(void) +uint64_t get_paging_pml4(void) { /* Return address to caller */ - return mmu_pml4_addr; + return HVA2HPA(mmu_pml4_addr); } -void enable_paging(void *pml4_base_addr) +void enable_paging(uint64_t pml4_base_addr) { - CPU_CR_WRITE(cr3, (unsigned long)pml4_base_addr); + CPU_CR_WRITE(cr3, pml4_base_addr); } void init_paging(void) @@ -527,7 +527,7 @@ void init_paging(void) pr_dbg("Enabling MMU "); /* Enable paging */ - enable_paging(mmu_pml4_addr); + enable_paging(HVA2HPA(mmu_pml4_addr)); } void *alloc_paging_struct(void) diff --git a/hypervisor/arch/x86/vtd.c b/hypervisor/arch/x86/vtd.c index a3d08e58c..c02f9fcba 100644 --- a/hypervisor/arch/x86/vtd.c +++ b/hypervisor/arch/x86/vtd.c @@ -219,17 +219,17 @@ static int register_hrhd_units(void) static uint32_t iommu_read32(struct dmar_drhd_rt *dmar_uint, uint32_t offset) { - return mmio_read_long((void*)(dmar_uint->drhd->reg_base_addr + offset)); + return mmio_read_long(HPA2HVA(dmar_uint->drhd->reg_base_addr + offset)); } static uint64_t iommu_read64(struct dmar_drhd_rt *dmar_uint, uint32_t offset) { uint64_t value; - value = (mmio_read_long((void*)(dmar_uint->drhd->reg_base_addr + offset + 4))); + value = mmio_read_long(HPA2HVA(dmar_uint->drhd->reg_base_addr + offset + 4)); value = value << 32; - value = value | (mmio_read_long((void*)(dmar_uint->drhd->reg_base_addr + - offset))); + value = value | mmio_read_long(HPA2HVA(dmar_uint->drhd->reg_base_addr + + offset)); return value; } @@ -237,7 +237,7 @@ static uint64_t iommu_read64(struct dmar_drhd_rt *dmar_uint, uint32_t offset) static void iommu_write32(struct dmar_drhd_rt *dmar_uint, uint32_t offset, uint32_t value) { - mmio_write_long(value, (void*)(dmar_uint->drhd->reg_base_addr + offset)); + mmio_write_long(value, HPA2HVA(dmar_uint->drhd->reg_base_addr + offset)); } static void iommu_write64(struct dmar_drhd_rt *dmar_uint, uint32_t offset, @@ -246,10 +246,10 @@ static void iommu_write64(struct dmar_drhd_rt *dmar_uint, uint32_t offset, uint32_t temp; temp = value; - mmio_write_long(temp, (void*)(dmar_uint->drhd->reg_base_addr + offset)); + mmio_write_long(temp, HPA2HVA(dmar_uint->drhd->reg_base_addr + offset)); temp = value >> 32; - mmio_write_long(temp, (void*)(dmar_uint->drhd->reg_base_addr + offset + 4)); + mmio_write_long(temp, HPA2HVA(dmar_uint->drhd->reg_base_addr + offset + 4)); } /* flush cache when root table, context table updated */ diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index c7e59ffa2..d238cda11 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -93,7 +93,7 @@ static inline uint32_t uart16550_read_reg(uint64_t base, uint32_t reg_idx) if (serial_port_mapped) { return io_read_byte((uint16_t)base + reg_idx); } else { - return mmio_read_long((void*)((uint32_t*)base + reg_idx)); + return mmio_read_long((void*)((uint32_t*)HPA2HVA(base) + reg_idx)); } } @@ -103,7 +103,7 @@ static inline void uart16550_write_reg(uint64_t base, if (serial_port_mapped) { io_write_byte(val, (uint16_t)base + reg_idx); } else { - mmio_write_long(val, (void*)((uint32_t*)base + reg_idx)); + mmio_write_long(val, (void*)((uint32_t*)HPA2HVA(base) + reg_idx)); } } @@ -339,5 +339,5 @@ void uart16550_set_property(int enabled, int port_mapped, uint64_t base_addr) { uart_enabled = enabled; serial_port_mapped = port_mapped; - Tgt_Uarts[0].base_address = (uint32_t) base_addr; + Tgt_Uarts[0].base_address = base_addr; } diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index ef1b7e318..f84f43696 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -314,10 +314,10 @@ struct mem_io_node { uint64_t range_end; }; -void *get_paging_pml4(void); +uint64_t get_paging_pml4(void); void *alloc_paging_struct(void); void free_paging_struct(void *ptr); -void enable_paging(void *pml4_base_addr); +void enable_paging(uint64_t pml4_base_addr); void init_paging(void); int map_mem(struct map_params *map_params, void *paddr, void *vaddr, uint64_t size, uint32_t flags);