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 <gen.zheng@intel.com>
This commit is contained in:
Zheng, Gen 2018-04-16 12:07:42 +08:00 committed by Jack Ren
parent d02f4d4a5f
commit c5f860e1cb
7 changed files with 37 additions and 37 deletions

View File

@ -215,11 +215,11 @@ void dump_lapic(void)
{ {
dev_dbg(ACRN_DBG_INTR, dev_dbg(ACRN_DBG_INTR,
"LAPIC: TIME %08x, init=0x%x cur=0x%x ISR=0x%x IRR=0x%x", "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(HPA2HVA(LAPIC_BASE + LAPIC_LVT_TIMER_REGISTER)),
mmio_read_long((void*)(0xFEE00000 + LAPIC_INITIAL_COUNT_REGISTER)), mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_INITIAL_COUNT_REGISTER)),
mmio_read_long((void*)(0xFEE00000 + LAPIC_CURRENT_COUNT_REGISTER)), mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_CURRENT_COUNT_REGISTER)),
mmio_read_long((void*)(0xFEE00000 + LAPIC_IN_SERVICE_REGISTER_7)), mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_IN_SERVICE_REGISTER_7)),
mmio_read_long((void*)(0xFEE00000 + LAPIC_INT_REQUEST_REGISTER_7))); mmio_read_long(HPA2HVA(LAPIC_BASE + LAPIC_INT_REQUEST_REGISTER_7)));
} }
int vcpu_inject_extint(struct vcpu *vcpu) int vcpu_inject_extint(struct vcpu *vcpu)

View File

@ -204,7 +204,7 @@ static void map_lapic(void)
/* At some point we may need to translate this paddr to a vaddr. 1:1 /* At some point we may need to translate this paddr to a vaddr. 1:1
* mapping for now. * 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) int early_init_lapic(void)

View File

@ -47,7 +47,7 @@ struct ioapic_rte {
struct gsi_table { struct gsi_table {
uint8_t ioapic_id; uint8_t ioapic_id;
uint8_t pin; uint8_t pin;
uint64_t addr; void *addr;
}; };
static struct gsi_table gsi_table[NR_MAX_GSI]; static struct gsi_table gsi_table[NR_MAX_GSI];
static int nr_gsi; static int nr_gsi;
@ -76,17 +76,17 @@ uint16_t legacy_irq_to_pin[NR_LEGACY_IRQ] = {
15, /* IRQ15*/ 15, /* IRQ15*/
}; };
static uint64_t map_ioapic( static void *map_ioapic(
uint64_t ioapic_paddr) uint64_t ioapic_paddr)
{ {
/* At some point we may need to translate this paddr to a vaddr. /* At some point we may need to translate this paddr to a vaddr.
* 1:1 mapping for now. * 1:1 mapping for now.
*/ */
return ioapic_paddr; return HPA2HVA(ioapic_paddr);
} }
static inline uint32_t 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; uint32_t v;
@ -104,7 +104,7 @@ ioapic_read_reg32(const uint64_t ioapic_base, const uint8_t offset)
} }
static inline void 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) const uint8_t offset, const uint32_t value)
{ {
spinlock_rflags; spinlock_rflags;
@ -138,7 +138,7 @@ get_ioapic_base(int apic_id)
static inline void static inline void
ioapic_get_rte_entry(uint64_t ioapic_addr, ioapic_get_rte_entry(void *ioapic_addr,
int pin, struct ioapic_rte *rte) int pin, struct ioapic_rte *rte)
{ {
rte->lo_32 = ioapic_read_reg32(ioapic_addr, pin*2 + 0x10); 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 static inline void
ioapic_set_rte_entry(uint64_t ioapic_addr, ioapic_set_rte_entry(void *ioapic_addr,
int pin, struct ioapic_rte *rte) int pin, struct ioapic_rte *rte)
{ {
ioapic_write_reg32(ioapic_addr, pin*2 + 0x10, rte->lo_32); 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) static void ioapic_set_routing(int gsi, int vr)
{ {
uint64_t addr; void *addr;
struct ioapic_rte rte; struct ioapic_rte rte;
addr = gsi_table[gsi].addr; 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) void ioapic_get_rte(int irq, uint64_t *rte)
{ {
uint64_t addr; void *addr;
struct ioapic_rte _rte; struct ioapic_rte _rte;
if (!irq_is_gsi(irq)) 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) void ioapic_set_rte(int irq, uint64_t raw_rte)
{ {
uint64_t addr; void *addr;
struct ioapic_rte rte; struct ioapic_rte rte;
if (!irq_is_gsi(irq)) if (!irq_is_gsi(irq))
@ -289,7 +289,7 @@ int pin_to_irq(int pin)
void void
irq_gsi_mask_unmask(int irq, bool mask) 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; int pin = gsi_table[irq].pin;
struct ioapic_rte rte; struct ioapic_rte rte;
@ -318,7 +318,7 @@ void setup_ioapic_irq(void)
int pin; int pin;
int max_pins; int max_pins;
int version; int version;
uint64_t addr; void *addr;
addr = map_ioapic(get_ioapic_base(ioapic_id)); addr = map_ioapic(get_ioapic_base(ioapic_id));
version = ioapic_read_reg32(addr, IOAPIC_VER); version = ioapic_read_reg32(addr, IOAPIC_VER);
@ -372,7 +372,7 @@ void dump_ioapic(void)
int irq; int irq;
for (irq = 0; irq < nr_gsi; 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; int pin = gsi_table[irq].pin;
struct ioapic_rte rte; struct ioapic_rte rte;
@ -404,7 +404,7 @@ int get_ioapic_info(char *str, int str_max_len)
str += len; str += len;
for (irq = 0; irq < nr_gsi; 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; int pin = gsi_table[irq].pin;
struct ioapic_rte rte; struct ioapic_rte rte;

View File

@ -468,15 +468,15 @@ static void *walk_paging_struct(void *addr, void *table_base,
return sub_table_addr; return sub_table_addr;
} }
void *get_paging_pml4(void) uint64_t get_paging_pml4(void)
{ {
/* Return address to caller */ /* 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) void init_paging(void)
@ -527,7 +527,7 @@ void init_paging(void)
pr_dbg("Enabling MMU "); pr_dbg("Enabling MMU ");
/* Enable paging */ /* Enable paging */
enable_paging(mmu_pml4_addr); enable_paging(HVA2HPA(mmu_pml4_addr));
} }
void *alloc_paging_struct(void) void *alloc_paging_struct(void)

View File

@ -219,17 +219,17 @@ static int register_hrhd_units(void)
static uint32_t iommu_read32(struct dmar_drhd_rt *dmar_uint, uint32_t offset) 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) static uint64_t iommu_read64(struct dmar_drhd_rt *dmar_uint, uint32_t offset)
{ {
uint64_t value; 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 << 32;
value = value | (mmio_read_long((void*)(dmar_uint->drhd->reg_base_addr + value = value | mmio_read_long(HPA2HVA(dmar_uint->drhd->reg_base_addr +
offset))); offset));
return value; 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, static void iommu_write32(struct dmar_drhd_rt *dmar_uint, uint32_t offset,
uint32_t value) 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, 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; uint32_t temp;
temp = value; 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; 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 */ /* flush cache when root table, context table updated */

View File

@ -93,7 +93,7 @@ static inline uint32_t uart16550_read_reg(uint64_t base, uint32_t reg_idx)
if (serial_port_mapped) { if (serial_port_mapped) {
return io_read_byte((uint16_t)base + reg_idx); return io_read_byte((uint16_t)base + reg_idx);
} else { } 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) { if (serial_port_mapped) {
io_write_byte(val, (uint16_t)base + reg_idx); io_write_byte(val, (uint16_t)base + reg_idx);
} else { } 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; uart_enabled = enabled;
serial_port_mapped = port_mapped; serial_port_mapped = port_mapped;
Tgt_Uarts[0].base_address = (uint32_t) base_addr; Tgt_Uarts[0].base_address = base_addr;
} }

View File

@ -314,10 +314,10 @@ struct mem_io_node {
uint64_t range_end; uint64_t range_end;
}; };
void *get_paging_pml4(void); uint64_t get_paging_pml4(void);
void *alloc_paging_struct(void); void *alloc_paging_struct(void);
void free_paging_struct(void *ptr); 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); void init_paging(void);
int map_mem(struct map_params *map_params, void *paddr, void *vaddr, int map_mem(struct map_params *map_params, void *paddr, void *vaddr,
uint64_t size, uint32_t flags); uint64_t size, uint32_t flags);