On Thu, 1 Sep 2016 10:10:49 +0200 Laurent Vivier <lviv...@redhat.com> wrote:
> Since kernel v4.0, linux uses H_CHANGE_LOGICAL_LAN_MAC to change lively > the MAC address of an ibmveth interface. > > As QEMU doesn't implement this h_call, we can't change anymore the > MAC address of an spapr-vlan interface. > > Signed-off-by: Laurent Vivier <lviv...@redhat.com> > --- > hw/net/spapr_llan.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c > index b273eda..4bb95a5 100644 > --- a/hw/net/spapr_llan.c > +++ b/hw/net/spapr_llan.c > @@ -106,6 +106,7 @@ typedef struct VIOsPAPRVLANDevice { > VIOsPAPRDevice sdev; > NICConf nicconf; > NICState *nic; > + MACAddr perm_mac; > bool isopen; > hwaddr buf_list; > uint32_t add_buf_ptr, use_buf_ptr, rx_bufs; > @@ -316,6 +317,10 @@ static void spapr_vlan_reset(VIOsPAPRDevice *sdev) > spapr_vlan_reset_rx_pool(dev->rx_pool[i]); > } > } > + > + memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a, > + sizeof(dev->nicconf.macaddr.a)); > + qemu_format_nic_info_str(qemu_get_queue(dev->nic), > dev->nicconf.macaddr.a); > } > > static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp) > @@ -324,6 +329,8 @@ static void spapr_vlan_realize(VIOsPAPRDevice *sdev, > Error **errp) > > qemu_macaddr_default_if_unset(&dev->nicconf.macaddr); > > + memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, > sizeof(dev->perm_mac.a)); > + > dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf, > object_get_typename(OBJECT(sdev)), > sdev->qdev.id, dev); > qemu_format_nic_info_str(qemu_get_queue(dev->nic), > dev->nicconf.macaddr.a); > @@ -756,6 +763,27 @@ static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, > sPAPRMachineState *spapr, > return H_SUCCESS; > } > > +static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu, > + sPAPRMachineState *spapr, > + target_ulong opcode, > + target_ulong *args) > +{ > + target_ulong reg = args[0]; > + target_ulong macaddr = args[1]; > + VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg); > + VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev); > + int i; > + > + for (i = 0; i < ETH_ALEN; i++) { > + dev->nicconf.macaddr.a[ETH_ALEN - i - 1] = macaddr & 0xff; Since ETH_ALEN is a constant, this could have been: + dev->nicconf.macaddr.a[ETH_ALEN - 1 - i] = macaddr & 0xff; and spare 1 instruction (at least with GCC 4.8.3/ppc64le) but we don't care for speed here, so: Reviewed-by: Greg Kurz <gr...@kaod.org> and tested with both LE and BE guests on a LE host, and the permanent address is restored as expected on reset: Tested-by: Greg Kurz <gr...@kaod.org> > + macaddr >>= 8; > + } > + > + qemu_format_nic_info_str(qemu_get_queue(dev->nic), > dev->nicconf.macaddr.a); > + > + return H_SUCCESS; > +} > + > static Property spapr_vlan_properties[] = { > DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev), > DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf), > @@ -854,6 +882,8 @@ static void spapr_vlan_register_types(void) > spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER, > h_add_logical_lan_buffer); > spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl); > + spapr_register_hypercall(H_CHANGE_LOGICAL_LAN_MAC, > + h_change_logical_lan_mac); > type_register_static(&spapr_vlan_info); > } >