Beispiel #1
0
static inline void *coherent_kvaddr(struct page *page, unsigned long base,
				    unsigned long vaddr, unsigned long *paddr)
{
	if (PageHighMem(page) || !DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
		*paddr = page_to_phys(page);
		return (void *)(base + (vaddr & DCACHE_ALIAS_MASK));
	} else {
		*paddr = 0;
		return page_to_virt(page);
	}
}
Beispiel #2
0
static inline void kmap_invalidate_coherent(struct page *page,
					    unsigned long vaddr)
{
	if (!DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) {
		unsigned long kvaddr;

		if (!PageHighMem(page)) {
			kvaddr = (unsigned long)page_to_virt(page);

			__invalidate_dcache_page(kvaddr);
		} else {
			kvaddr = TLBTEMP_BASE_1 +
				(page_to_phys(page) & DCACHE_ALIAS_MASK);

			__invalidate_dcache_page_alias(kvaddr,
						       page_to_phys(page));
		}
	}
}
Beispiel #3
0
int __init mem_module_init(void)
{
	UINT phys, virt;
	printk("-----------------\n");
	printk("PAGE_OFFSET = %x\n", (UINT)PAGE_OFFSET);
	
	printk("This module addr: %x(%u MB)\n", (UINT)&virt, MB(&virt));
	phys = virt_to_phys((void*)&virt);
	printk("phys: %x(%u MB)\n", phys, MB(phys));
	
	
	/*申请的内存位于物理内存映射区域,与真实物理地址只有一个固定偏移*/
	free_pg = (void*)__get_free_page(0);
	virt = (UINT)free_pg;
	printk("->Free page mem: %x(%u MB)\n", virt, MB(virt));
	phys = virt_to_phys(free_pg);
	printk("phys: %x(%u MB)\n", phys, MB(phys));
	
	alloc_pg = alloc_page(GFP_KERNEL);
	virt = page_to_virt(alloc_pg);
	printk("->Alloc page mem: %x(%u MB)\n", virt, MB(virt));
	phys = virt_to_phys(alloc_pg);
	printk("phys: %x(%u MB)\n", phys, MB(phys));

	/*申请的内存位于物理内存映射区域,与真实物理地址只有一个固定偏移*/
	kmallocmem = (void*)kmalloc(100, 0);
	virt = (UINT)kmallocmem;
	printk("->Kmalloc mem: %x(%u MB)\n", virt, MB(virt));
	phys = virt_to_phys(kmallocmem);
	printk("phys: %x(%u MB)\n", phys, MB(phys));

	/*申请的内存位于vmalloc_start~vmalloc_end之间,与物理地址没有简短的转换关系*/
	vmallocmem = (void*)vmalloc(100000);
	virt = (UINT)vmallocmem;
	printk("->Vmalloc mem: %x(%u MB)\n", virt, MB(virt));
	phys = virt_to_phys(vmallocmem);
	printk("phys: %x(%u MB)\n", phys, MB(phys));
	
	printk("-----------------\n");
	return 0;
}
static int
trans_open(struct inode *i, struct file *f)
{
    struct trans_channel *c;
    struct page *p;

    printl("trans_open\n");
    c = kmalloc(sizeof(struct trans_channel), GFP_KERNEL);
    if (!c) return -ENOMEM;
    trans_channel_init(c);

    p = alloc_pages(GFP_KERNEL, TRANS_PAGE_ORDER);
    if (!p) goto free;
    c->mem = page_to_virt(p);
    f->private_data = c;

    return 0;
free:
    kfree(c);
    return -ENOMEM;
}
static void *
xencomm_vaddr(unsigned long paddr, struct page_info *page)
{
    return (void*)((paddr & ~PAGE_MASK) | (unsigned long)page_to_virt(page));
}
static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive,
					       long eq_idx, u64 addr)
{
	struct kvm *kvm = xive->kvm;
	struct kvm_vcpu *vcpu;
	struct kvmppc_xive_vcpu *xc;
	void __user *ubufp = (void __user *) addr;
	u32 server;
	u8 priority;
	struct kvm_ppc_xive_eq kvm_eq;
	int rc;
	__be32 *qaddr = 0;
	struct page *page;
	struct xive_q *q;
	gfn_t gfn;
	unsigned long page_size;

	/*
	 * Demangle priority/server tuple from the EQ identifier
	 */
	priority = (eq_idx & KVM_XIVE_EQ_PRIORITY_MASK) >>
		KVM_XIVE_EQ_PRIORITY_SHIFT;
	server = (eq_idx & KVM_XIVE_EQ_SERVER_MASK) >>
		KVM_XIVE_EQ_SERVER_SHIFT;

	if (copy_from_user(&kvm_eq, ubufp, sizeof(kvm_eq)))
		return -EFAULT;

	vcpu = kvmppc_xive_find_server(kvm, server);
	if (!vcpu) {
		pr_err("Can't find server %d\n", server);
		return -ENOENT;
	}
	xc = vcpu->arch.xive_vcpu;

	if (priority != xive_prio_from_guest(priority)) {
		pr_err("Trying to restore invalid queue %d for VCPU %d\n",
		       priority, server);
		return -EINVAL;
	}
	q = &xc->queues[priority];

	pr_devel("%s VCPU %d priority %d fl:%x shift:%d addr:%llx g:%d idx:%d\n",
		 __func__, server, priority, kvm_eq.flags,
		 kvm_eq.qshift, kvm_eq.qaddr, kvm_eq.qtoggle, kvm_eq.qindex);

	/*
	 * sPAPR specifies a "Unconditional Notify (n) flag" for the
	 * H_INT_SET_QUEUE_CONFIG hcall which forces notification
	 * without using the coalescing mechanisms provided by the
	 * XIVE END ESBs. This is required on KVM as notification
	 * using the END ESBs is not supported.
	 */
	if (kvm_eq.flags != KVM_XIVE_EQ_ALWAYS_NOTIFY) {
		pr_err("invalid flags %d\n", kvm_eq.flags);
		return -EINVAL;
	}

	rc = xive_native_validate_queue_size(kvm_eq.qshift);
	if (rc) {
		pr_err("invalid queue size %d\n", kvm_eq.qshift);
		return rc;
	}

	/* reset queue and disable queueing */
	if (!kvm_eq.qshift) {
		q->guest_qaddr  = 0;
		q->guest_qshift = 0;

		rc = xive_native_configure_queue(xc->vp_id, q, priority,
						 NULL, 0, true);
		if (rc) {
			pr_err("Failed to reset queue %d for VCPU %d: %d\n",
			       priority, xc->server_num, rc);
			return rc;
		}

		if (q->qpage) {
			put_page(virt_to_page(q->qpage));
			q->qpage = NULL;
		}

		return 0;
	}

	if (kvm_eq.qaddr & ((1ull << kvm_eq.qshift) - 1)) {
		pr_err("queue page is not aligned %llx/%llx\n", kvm_eq.qaddr,
		       1ull << kvm_eq.qshift);
		return -EINVAL;
	}

	gfn = gpa_to_gfn(kvm_eq.qaddr);
	page = gfn_to_page(kvm, gfn);
	if (is_error_page(page)) {
		pr_err("Couldn't get queue page %llx!\n", kvm_eq.qaddr);
		return -EINVAL;
	}

	page_size = kvm_host_page_size(kvm, gfn);
	if (1ull << kvm_eq.qshift > page_size) {
		pr_warn("Incompatible host page size %lx!\n", page_size);
		return -EINVAL;
	}

	qaddr = page_to_virt(page) + (kvm_eq.qaddr & ~PAGE_MASK);

	/*
	 * Backup the queue page guest address to the mark EQ page
	 * dirty for migration.
	 */
	q->guest_qaddr  = kvm_eq.qaddr;
	q->guest_qshift = kvm_eq.qshift;

	 /*
	  * Unconditional Notification is forced by default at the
	  * OPAL level because the use of END ESBs is not supported by
	  * Linux.
	  */
	rc = xive_native_configure_queue(xc->vp_id, q, priority,
					 (__be32 *) qaddr, kvm_eq.qshift, true);
	if (rc) {
		pr_err("Failed to configure queue %d for VCPU %d: %d\n",
		       priority, xc->server_num, rc);
		put_page(page);
		return rc;
	}

	/*
	 * Only restore the queue state when needed. When doing the
	 * H_INT_SET_SOURCE_CONFIG hcall, it should not.
	 */
	if (kvm_eq.qtoggle != 1 || kvm_eq.qindex != 0) {
		rc = xive_native_set_queue_state(xc->vp_id, priority,
						 kvm_eq.qtoggle,
						 kvm_eq.qindex);
		if (rc)
			goto error;
	}

	rc = kvmppc_xive_attach_escalation(vcpu, priority,
					   xive->single_escalation);
error:
	if (rc)
		kvmppc_xive_native_cleanup_queue(vcpu, priority);
	return rc;
}
Beispiel #7
0
static void run_tool(uint8_t devices) {
    uint8_t highlighted;

    for (uint8_t i = 0; i < 4; i++) {
        if (ide_device_is_present(i) && ide_device_get_type(i) == 0) {
            highlighted = i;
            break;
        }
    }

    bool selected[4] = {0,0,0,0};
    bool selecting = true;
    uint8_t selectedNum = 0;

    while (selecting) {
        console_clear();
        print_header();

        console_puts("Please select the drives which you would like to erase.\n");

        for (uint8_t i = 0; i < 4; i++) {
            if (ide_device_is_present(i) && ide_device_get_type(i) == 0) {
                uint8_t foreground = 0x7, background = 0x0;
                if (selected[i]) foreground = 0xC;
                if (highlighted == i) {
                    background = 0xF;
                    if (foreground == 0x7) foreground = 0x0;
                }

                console_color((background << 4) + foreground);
                console_putsf("    - ATA Device %u (%s) %7uMB - %s\n", i, ide_device_is_dma_capable(i) ? "DMA" : "PIO", ide_device_get_size(i) / 1024 / 2, ide_device_get_string(i, IDE_STRING_MODEL));
                console_color(0x07);
            }
        }

        for (int i = 0; i < 10 - devices; i++) console_puts("\n");

        console_puts("Use the \"ARROW KEYS\" to highlight a drive.\n");
        console_puts("Press \"SPACE\"  to select/deselect the currently highlighted drive.\n\n");

        console_puts("NOTE: You must select at least one drive to continue.\n\n");

        console_puts("Press \"ENTER\"  to continue.\n");
        console_puts("Press \"ESCAPE\" to go back.");

        switch (get_key()) {
            case '\n':
                if (selectedNum > 0) {
                    selecting = false;
                }
                break;
            case '\1':
                return;
            case '\3':
                do {
                    highlighted--;
                    if (highlighted > 3) highlighted = 3;
                } while (!(ide_device_is_present(highlighted) && ide_device_get_type(highlighted) == 0));
                break;
            case '\5':
                do {
                    highlighted++;
                    if (highlighted == 4) highlighted = 0;
                } while (!(ide_device_is_present(highlighted) && ide_device_get_type(highlighted) == 0));
                break;
            case ' ':
                selected[highlighted] = !selected[highlighted];
                selectedNum += selected[highlighted] ? 1 : -1;
                break;
        }
    }

    console_clear();
    print_header();

    console_puts("Please select the drives which you would like to erase.\n");

    for (uint8_t i = 0; i < 4; i++) {
        if (ide_device_is_present(i) && ide_device_get_type(i) == 0) {
            uint8_t foreground = 0x7, background = 0x0;
            if (selected[i]) foreground = 0xC;

            console_color((background << 4) + foreground);
            console_putsf("    - ATA Device %u (%s) %7uMB - %s\n", i, ide_device_is_dma_capable(i) ? "DMA" : "PIO", ide_device_get_size(i) / 1024 / 2, ide_device_get_string(i, IDE_STRING_MODEL));
            console_color(0x07);
        }
    }

    console_puts("\n\nPlease enter the number of passes to be performed (max 99, 0 to cancel): ");

    uint8_t idx = 0;
    char raw_passes[3];

    char c;
    do {
        c = get_key();

        if (c == '\x7f' && idx > 0) {
            idx--;
            console_cursor(console_row(), console_col() - 1);
            console_puts(" ");
            console_cursor(console_row(), console_col() - 1);
        } else if (c >= '0' && c <= '9' && idx < 2) {
            console_putsf("%c", c);
            raw_passes[idx] = c;
            idx++;
        }
    } while (!(c == '\n' && idx != 0));

    raw_passes[idx] = '\0';
    uint32_t passes = atoi(raw_passes);

    if (passes == 0) return;

    console_puts("\n\nPress \"ENTER\"  to ");
    console_color(0x0C);
    console_puts("WIPE THE ATA DISKS SELECTED ABOVE");
    console_color(0x07);
    console_putsf(" in %u pass", passes);

    if (passes != 1) console_puts("es");

    console_puts(".\nPress \"ESCAPE\" to cancel and go back.\n\n");

    bool wait = true;
    while (wait) {
        switch (get_key()) {
            case '\1':
                return;
                break;
            case '\n':
                wait = false;
        }
    }

    console_clear();

    console_puts("Starting Data Erasure Tool...\n\n");

    uint8_t *space = (uint8_t *) page_to_virt(alloc_page(0));
    for (uint32_t i = 1; i < 64; i++) {
        alloc_page(0);
        console_putsf("Initializing... %3u%%\r", ((i + 1) * 100) / 64);
    }
    console_puts("Initializing... 100%%\n");

    uint8_t bit = 0x00;
    for (uint32_t pass = 0; pass < passes; pass++) {
        console_clear();

        console_puts("Starting Data Erasure Tool...\n\n");

        console_putsf("Initializing... 100%%\n", space);

        console_putsf("\nWriting Pass %02u of %02u...\n", pass + 1, passes);
        for (uint32_t i = 0; i < (64 * 4 * 1024); i++) {
            space[i] = bit;
        }

        int device = 0;
        for (uint32_t i = 0; i < 4; i++) {
            if (selected[i]) {
                device++;
                uint32_t count = 0;
                uint32_t written = 0;
                while(written < ide_device_get_size(i)) {
                    count++;
                    console_putsf("    - Writing to device %u... %3u%%                                             %c\r", device, (written * 100) / ide_device_get_size(i), twirls[(count / 10) % 4]);
                    written += ide_write_sectors_same(i, ide_device_get_size(i) - written, written, space) / 512;
                }
                console_putsf("    - Writing to device %u... 100%%                                              \n", device);
            }
        }

        bit = ~bit;
    }

    console_color(0x0A);
    console_puts("\nOperation completed successfully! ");
    console_color(0x07);
    console_puts("You may now turn the computer off.");

    beep();
    die();
}