Ejemplo n.º 1
0
void kgdboe_io_cleanup(void)
{
	/*
		We don't check for race conditions between running code by other cores and unloading the module!
		There is always a small chance that unloading this module would cause a kernel panic because
		another core is executing a function hooked by us. As normally you don't need to load/unload this
		module all the time (just execute the 'detach' command in GDB and connect back when ready), we
		don't check for it here.
	*/
	kgdb_unregister_io_module(&kgdboe_io_ops);
	netpoll_wrapper_free(s_pKgdboeNetpoll);
	nethook_cleanup();
	s_pKgdboeNetpoll = NULL;
}
Ejemplo n.º 2
0
int kgdboe_io_init(const char *device_name, int port, const char *local_ip,
		   bool force_single_core)
{
	int err;
	u8 ipaddr[4];

	spin_lock_init(&exception_lock);

	s_pKgdboeNetpoll = netpoll_wrapper_create(device_name, port, local_ip);
	if (!s_pKgdboeNetpoll)
		return -EINVAL;

	if (force_single_core) {
		force_single_cpu_mode();
	} else if (!nethook_initialize(s_pKgdboeNetpoll->pDeviceWithHandler)) {
		printk(KERN_ERR "kgdboe: failed to guarantee cross-CPU network "
				"API synchronization. Aborting. Try enabling "
				"single-CPU mode.\n");
		return -EINVAL;
	}

	err = kgdb_register_io_module(&kgdboe_io_ops);
	if (err != 0) {
		netpoll_wrapper_free(s_pKgdboeNetpoll);
		s_pKgdboeNetpoll = NULL;
		return err;
	}

	netpoll_wrapper_set_callback(s_pKgdboeNetpoll, kgdboe_rx_handler, NULL);

	memcpy(ipaddr, &ip_addr_as_int(s_pKgdboeNetpoll->netpoll_obj.local_ip),
	       4);
	printk(KERN_INFO "kgdboe: Successfully initialized. Use the following "
			 "gdb command to attach:\n");
	printk(KERN_INFO "\ttarget remote udp:%d.%d.%d.%d:%d\n", ipaddr[0],
	       ipaddr[1], ipaddr[2], ipaddr[3],
	       s_pKgdboeNetpoll->netpoll_obj.local_port);

	return 0;
}
Ejemplo n.º 3
0
struct netpoll_wrapper *netpoll_wrapper_create(const char *pDeviceName, int localPort, const char *pOptionalLocalIp)
{
	struct net_device *pDevice;
	struct netpoll_wrapper *pResult;
	int localIp;
	int err;

	if (!pDeviceName || !localPort)
	{
		printk(KERN_ERR "kgdboe: cannot create a netpoll wrapper without a device name\n");
		return NULL;
	}

	pDevice = dev_get_by_name(&init_net, pDeviceName);
	if (!pDevice)
	{
		printk(KERN_ERR "kgdboe: Cannot find network device by name: %s\n", pDeviceName);
		return NULL;
	}


	if (pOptionalLocalIp)
	{
		localIp = in_aton(pOptionalLocalIp);
		if (!localIp)
		{
			printk(KERN_ERR "kgdboe: Invalid local IP: %s\n", pOptionalLocalIp);
			return NULL;
		}
	}
	else
	{
		if (!pDevice->ip_ptr)
		{
			printk(KERN_ERR "kgdboe: %s does not have an in_device associated. Cannot get default IP address.\n", pDeviceName);
			return NULL;
		}
		if (!pDevice->ip_ptr->ifa_list)
		{
			printk(KERN_ERR "kgdboe: %s does not have a in_ifaddr struct associated. Cannot get default IP address.\n", pDeviceName);
			return NULL;
		}

		localIp = pDevice->ip_ptr->ifa_list->ifa_local;
	}

	pResult = (struct netpoll_wrapper *)kmalloc(sizeof(struct netpoll_wrapper), GFP_KERNEL);
	if (!pResult)
	{
		printk(KERN_ERR "kgdboe: cannot allocate memory for netpoll wrapper\n");
		return NULL;
	}

	memset(pResult, 0, sizeof(*pResult));

#ifdef NETPOLL_POLL_DEV_USABLE
	pResult->netpoll_poll_dev = (void(*)(struct net_device *))kallsyms_lookup_name("netpoll_poll_dev");
	if (!pResult->netpoll_poll_dev)
	{
		printk(KERN_ERR "kgdboe: Cannot find netpoll_poll_dev(). Aborting.\n");
		netpoll_wrapper_free(pResult);
		return NULL;
	}
#else
	pResult->zap_completion_queue = (void(*)(void))kallsyms_lookup_name("zap_completion_queue");
	if (!pResult->zap_completion_queue)
	{
		printk(KERN_ERR "kgdboe: Cannot find zap_completion_queue(). Aborting.\n");
		netpoll_wrapper_free(pResult);
		return NULL;
	}
#endif

	rtnl_lock();
	err = netdev_rx_handler_register(pDevice, netpoll_wrapper_rx_handler, pResult);
	rtnl_unlock();
	if (err < 0)
	{
		printk(KERN_ERR "kgdboe: Failed to register rx handler for %s, code %d\n", pDeviceName, err);
		netpoll_wrapper_free(pResult);
		return NULL;
	}

	register_tracepoint_wrapper(netif_receive_skb, hook_receive_skb, pResult);
	pResult->tracepoint_registered = true;

	pResult->pDeviceWithHandler = pDevice;

	strncpy(pResult->netpoll_obj.dev_name, pDeviceName, sizeof(pResult->netpoll_obj.dev_name));
	pResult->netpoll_obj.name = "kgdboe";
	pResult->netpoll_obj.local_port = localPort;
	memset(pResult->netpoll_obj.remote_mac, 0xFF, sizeof(pResult->netpoll_obj.remote_mac));

	err = netpoll_setup(&pResult->netpoll_obj);
	if (err < 0)
	{
		printk(KERN_ERR "kgdboe: Failed to setup netpoll for %s, code %d\n", pDeviceName, err);
		netpoll_wrapper_free(pResult);
		return NULL;
	}

	pResult->netpoll_initialized = true;

	return pResult;
}